ALTER TABLE en una tabla grande puede bloquear todas las transacciones nuevas durante minutos u horas. Cuando una sentencia DDL bloqueante mantiene abierta la cola de solicitudes del bloqueo MDL-X, cada transacción que accede a esa tabla se acumula detrás de ella. Si la cola crece demasiado, el agotamiento de conexiones puede dejar inoperativa toda la aplicación. Las sentencias DDL no bloqueantes eliminan este riesgo: reintentan obtener el bloqueo en intervalos cortos y liberan su posición en la cola entre intentos para que las transacciones nuevas sigan ejecutándose.
Cómo funciona
El sistema de bloqueo de metadatos (MDL) de MySQL protege las tablas durante los cambios de esquema. Una sentencia DDL bloqueante solicita un bloqueo exclusivo MDL-X y mantiene bloqueada la cola de solicitudes hasta que lo obtiene. Como MDL-X tiene la prioridad más alta, cada transacción nueva que accede a la tabla se acumula detrás de la sentencia DDL, incluso si esta aún espera que termine una transacción anterior.
Las sentencias DDL no bloqueantes cambian este comportamiento:
La sentencia DDL intenta obtener el bloqueo MDL-X dentro de un tiempo de espera corto (
loose_polar_nonblock_ddl_lock_wait_timeout, valor predeterminado: 1 segundo).Si el bloqueo no está disponible, la sentencia DDL libera por completo su posición en la cola. Al desbloquearse la cola, las transacciones pendientes y entrantes pueden obtener sus propios bloqueos y continuar con normalidad.
Después de un intervalo configurable (
loose_polar_nonblock_ddl_retry_interval, valor predeterminado: 6 segundos), la sentencia DDL reintenta la operación.Los pasos 2 y 3 se repiten hasta
loose_polar_nonblock_ddl_retry_timesintentos.
Durante los intervalos de reintento, la tabla permanece totalmente accesible. Las transacciones por segundo (TPS) pueden disminuir brevemente cuando la sentencia DDL obtiene el bloqueo, pero nunca llegan a cero.
Las sentencias DDL no bloqueantes tienen menor prioridad que las bloqueantes y una mayor probabilidad de no obtener el bloqueo MDL-X. Utilícelas cuando la continuidad del negocio sea más importante que la velocidad del cambio de esquema.
Versiones compatibles
Las sentencias DDL no bloqueantes requieren una de a continuación versiones:
PolarDB for MySQL 8.0.1 en la versión de revisión 8.0.1.1.29 o posterior
PolarDB for MySQL 8.0.2 en la versión de revisión 8.0.2.2.12 o posterior
Para comprobar la versión de revisión de su clúster, consulte Engine versions 5.6, 5.7, and 8.0.
Sentencias DDL compatibles
Las sentencias que admiten sentencias DDL no bloqueantes dependen de su versión de revisión.
|
Versión de revisión |
Sentencias compatibles |
Notas |
|
8.0.1.1.29 o posterior, o 8.0.2.2.12 |
Solo |
Para desfragmentar una tabla InnoDB, utilice |
|
8.0.2.2.13 o posterior |
|
— |
Habilitar las sentencias DDL no bloqueantes
Los cuatro parámetros son de nivel de sesión. Establézcalos en la misma sesión antes de ejecutar la sentencia DDL.
Paso 1: Habilite el modo DDL no bloqueante
SET SESSION loose_polar_nonblock_ddl_mode = ON;
El valor predeterminado de loose_polar_nonblock_ddl_mode es OFF.
Paso 2: Configure el comportamiento de reintento
SET SESSION loose_polar_nonblock_ddl_retry_times = 4194304;
SET SESSION loose_polar_nonblock_ddl_retry_interval = 6;
SET SESSION loose_polar_nonblock_ddl_lock_wait_timeout = 1;
|
Parámetro |
Valor predeterminado |
Valores válidos |
Unidad |
Cuándo modificarlo |
|
|
0 (derivado de |
0–31536000 |
— |
Establezca |
|
|
6 |
1–31536000 |
Segundos |
Auméntelo para reducir la contención de bloqueos; redúzcalo para terminar la sentencia DDL más rápido |
|
|
1 |
1–31536000 |
Segundos |
Auméntelo si el bloqueo no se obtiene con suficiente frecuencia bajo una carga de escritura intensa |
Para obtener más información sobre cómo aplicar estos parámetros, consulte Configure cluster and node parameters.
Paso 3: Ejecute la sentencia DDL
ALTER TABLE table_name ADD INDEX index_name (column1, column2, column3);
La sentencia se ejecuta con comportamiento no bloqueante en la sesión actual. Las demás sesiones no se ven afectadas.
Prueba de rendimiento
A continuación se comparan las sentencias DDL bloqueantes, las no bloqueantes y la herramienta de cambio de esquema en línea gh-ost mediante SysBench. Para obtener más información sobre SysBench, consulte OLTP performance test.
Test environment: PolarDB for MySQL 8.0, Cluster Edition, 8 núcleos de CPU, 64 GB de memoria.
Configuración
-
Cree una tabla con 1 millón de filas:
./oltp_read_write.lua --mysql-host="Cluster endpoint" --mysql-port="Port number" \ --mysql-user="Username" --mysql-password="Password" \ --mysql-db="sbtest" --tables=1 --table-size=1000000 \ --report-interval=1 --percentile=99 --threads=8 --time=6000 prepare -
Simule una carga de trabajo de lectura y escritura:
./oltp_read_write.lua --mysql-host="Cluster endpoint" --mysql-port="Port number" \ --mysql-user="Username" --mysql-password="Password" \ --mysql-db="sbtest" --tables=1 --table-size=1000000 \ --report-interval=1 --percentile=99 --threads=8 --time=6000 run -
Mantenga un bloqueo MDL al iniciar una transacción y dejarla abierta:
/* Session 1 */ BEGIN; SELECT * FROM sbtest1; -
En una segunda sesión, agregue una columna a la tabla:
/* Session 2 */ ALTER TABLE sbtest1 ADD COLUMN d INT; -
Repita el cambio de esquema con gh-ost (requiere registro binario; consulte Enable binary logging):
./gh-ost --assume-rbr --user="Username" --password="Password" \ --host="Cluster endpoint" --port="Port number" \ --database="sbtest" --table="sbtest1" --alter="ADD COLUMN d INT" \ --allow-on-master --aliyun-rds \ --initially-drop-old-table --initially-drop-ghost-table --execute
Impacto en las TPS
DDL bloqueante (sentencias DDL no bloqueantes deshabilitadas): las TPS caen a cero y permanecen así hasta que termina la sentencia DDL.

DDL no bloqueante: las TPS disminuyen periódicamente mientras la sentencia DDL reintenta obtener el bloqueo, pero nunca llegan a cero. El impacto en el negocio es mínimo.

gh-ost: las TPS caen a cero en picos periódicos. Esta herramienta crea una tabla fantasma, le aplica los cambios y luego renombra atómicamente dicha tabla para reemplazar a la original (el paso de corte). Este proceso requiere un breve bloqueo de tabla, lo que provoca las caídas periódicas de TPS.

Comparación de velocidad con 100 millones de filas
Se agregaron columnas a una tabla de 100 millones de filas mediante sentencias DDL no bloqueantes (algoritmos INSTANT, INPLACE y COPY) y gh-ost.
Sin carga de trabajo: las sentencias DDL no bloqueantes terminan más rápido que gh-ost.

Carga de trabajo de lectura y escritura: las sentencias DDL no bloqueantes siguen terminando más rápido que gh-ost.

Las sentencias DDL no bloqueantes mantienen las TPS por encima de cero durante todo el cambio de esquema. Además, terminan más rápido que gh-ost tanto sin carga como con cargas similares a las de producción.
Temas relacionados
Si tiene preguntas sobre las operaciones DDL, contáctenos.