
En esta publicación de blog, discutiremos pt-online-schema-change y cómo usarlo correctamente.
¿Siempre usas pt-osc?
La alteración de tablas grandes aún puede ser una tarea de DBA problemática, incluso ahora que han mejorado DDL en línea funcionalidad en MySQL 5.6 y 5.7. Algunos tipos de ALTER siempre están fuera de línea o, a veces, son demasiado costosos para ejecutarlos en un maestro de producción ocupado.
Entonces, en algunos casos, es posible que desee aplicar uno
ALTERAR primero en los esclavos, sacando el tráfico de la piscina uno por uno y llevándolo de vuelta después del
ALTERAR se hace. Finalmente, podemos promover uno de los esclavos ya modificados para que sea un nuevo maestro, por lo que el tiempo de inactividad/mantenimiento se minimiza en gran medida. El maestro anterior se puede cambiar más tarde, sin afectar la producción. Por supuesto, este método funciona mejor cuando el cambio de esquema es compatible con versiones anteriores.
Hasta aquí todo bien, pero hay otro problema. Digamos que la mesa es enorme, y
ALTERAR toma mucho tiempo en el esclavo. Cuando se trata de un tipo de bloque ALTER DML (quizás cuando se utiliza MySQL 5.5.x o anterior, etc.), habrá un largo retraso del esclavo (si la tabla está escrita por el subproceso SQL de replicación al mismo tiempo, por ejemplo) . Entonces, ¿qué hacemos para acelerar el proceso y evitar el retraso del esclavo alterado? Una tentación que podría tentarlo es ¿por qué no usar pt-online-schema-change en el esclavo, que puede hacer ALTER sin bloqueo?
Vamos a ver cómo funciona. Necesito reconstruir una tabla esclava grande con MySQL versión 5.6.16 («alteración nula» fue hecho en línea desde 5.6.17) para recuperar espacio en disco después de eliminar algunas filas.
Este ejemplo muestra el proceso (db1 es el maestro, db2 es el esclavo):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 |
[root@db2 ~]# pt-online-schema-change –execute –alter «motor = innodb» D = db1, t = sbtest1 No esclavos encontrar. Para ver –recursión–método Si anfitrión db2 posee esclavos. No verificar esclavo retraso por qué No esclavos Ellos eran encontrar y –verificado–esclavo–retraso era No especificado. Operación, prueba, esperar: análisis_tabla, 10, 1 copiar_filas, 10, 0.25 crear_triggers, 10, 1 drop_triggers, 10, 1 intercambiar_tablas, 10, 1 actualizar_claves_extranjeras, 10, 1 Alterar `db1`.`sbtest1`... Crear nuevo mesa... Creado nuevo mesa db1._sbtest1_nuevo OK. Alterar nuevo mesa... Alterar `db1`.`_sbtest1_nuevo` OK. 2016–05–16T10:50:50 Crear disparadores... 2016–05–16T10:50:50 Creado disparadores OK. 2016–05–16T10:50:50 Dupdo Buscando 591840 póngase en fila... Dupdo `db1`.`sbtest1`: 51% 00:28 descansar (...) |
La herramienta siempre se trabaja durante la operación, y la mesa recibe algunos escritos sobre el maestro:
db1 {raíz} (db1)> actualizar db1.sbtest1 establecer k = k + 2 donde id<100; Query OK, 99 rows affected (0.06 sec) Rows matched: 99 Changed: 99 Warnings: 0 db1 {root} (db1) > actualizar db1.sbtest1 establecer k = k + 2 donde id <100; Consulta OK, 99 fila cortada (0.05 seg) Fila acordada: 99 Cambiada: 99 Advertencias: 0
db1 {raíz} (db1) > actualizar db1.sbtest1 colocar k=k+2 donde identificación<100; Pregunta está bien, 99 póngase en fila afectado (0.06 segundo) Righe corresponsal: 99 Cambio: 99 Advertencias: 0 db1 {raíz} (db1) > actualizar db1.sbtest1 colocar k=k+2 donde identificación<100; Pregunta está bien, 99 póngase en fila afectado (0.05 segundo) Righe corresponsal: 99 Cambio: 99 Advertencias: 0 |
que se aplican en el esclavo de inmediato, ya que la tabla permite escribir todo el tiempo.
(…) Copiar `db1`.`sbtest1`: 97% 00:01 restantes 2016-05-16T10: 51: 53 Copiar archivo OK. 2016-05-16T10:51:53 Analizando la nueva tabla… 2016-05-16T10:51:53 Intercambiando tablas… 2016-05-16T10:51:53 Intercambiando tablas originales y nuevas OK. 2016-05-16T10: 51: 53 Caída de tabla antigua… 2016-05-16T10: 51: 53 Caída de tabla antigua `db1`.`_sbtest1_old` OK. 2016-05-16T10: 51: 53 Eliminando activadores… 2016-05-16T10: 51: 53 Activadores eliminados OK. Modificado con éxito `db1`.`sbtest1`.
(...) Dupdo `db1`.`sbtest1`: 97% 00:01 descansar 2016–05–16T10:51:53 copiado póngase en fila OK. 2016–05–16T10:51:53 Análisis nuevo mesa... 2016–05–16T10:51:53 Intercambio mesas... 2016–05–16T10:51:53 intercambiado original y nuevo mesas OK. 2016–05–16T10:51:53 Goteante viejo mesa... 2016–05–16T10:51:53 Abandonado viejo mesa `db1`.`_sbtest1_old` OK. 2016–05–16T10:51:53 Goteante disparadores... 2016–05–16T10:51:53 Abandonado disparadores OK. Éxito alterado `db1`.`sbtest1`. |
¡Hecho! No hay retraso esclavo, y la mesa se reconstruye. Mamá. . . solo asegúrese de que los datos sean consistentes entre maestro y esclavo (puede usar pt-table-checksum):
db1 {root} (db1)> seleccione max (k) de db1.sbtest1 donde id<100; +--------+ | max(k) | +--------+ | 392590 | +--------+ 1 row in set (0.00 sec) db2 {root} (test) > seleccione max (k) de db1.sbtest1 donde id <100; + -------- + | máx (k) | + -------- + | 392586 | + -------- + 1 fila en conjunto (0.00 seg)
db1 {raíz} (db1) > Seleccione máximo(k) sí db1.sbtest1 donde identificación<100; + ——– + | máximo(k) | + ——– + | 392590 | + ——– + 1 póngase en fila en colocar (0.00 segundo) db2 {raíz} (prueba) > Seleccione máximo(k) sí db1.sbtest1 donde identificación<100; + ——– + | máximo(k) | + ——– + | 392586 | + ——– + 1 póngase en fila en colocar (0.00 segundo) |
¡No, no es! Al esclavo claramente le faltan las actualizaciones que ocurrieron durante una carrera pt-osc. ¿Por qué?
La explicación es sencilla. tu
punto–en línea–esquema–cambio se basa en disparadores. Los activadores se utilizan para asegurarse de que las entradas posteriores a la tabla original también se llenen con la copia temporal de la tabla, porque las dos tablas son coherentes cuando se produce el cambio de la tabla final al final del proceso. Entonces, ¿cuál es el problema aquí? Es el formato de registro binario: en Replicación basada en ROW, los disparadores no se activan en el esclavo! Y mi profesor trabaja en modo FILA:
db1 {raíz} (db1)> mostrar variables como ‘binlog_format’; + ————— + ——- + | nombre_variable | valor | + ————— + ——- + | binlog_format | FILA | + ————— + ——- + 1 fila en conjunto (0.01 seg)
db1 {raíz} (db1) > espectáculos Variables así como también ‘formato_binlog’; + ————— + ——- + | Nombre de la variable | Valor | + ————— + ——- + | binlog_formato | PÓNGASE EN FILA | + ————— + ——- + 1 póngase en fila en colocar (0.01 segundo) |
Entonces, si lo usé
punto–en línea–esquema–cambio en el maestro, el problema de la inconsistencia de datos no ocurre. ¡Pero usarlo en el esclavo solo es peligroso!
Conclusiones
Cada vez que lo usas
punto–en línea–esquema–cambio, asegúrese de que no se está ejecutando en una instancia esclava. Entonces, escalé este informe de error: https://bugs.launchpad.net/percona-toolkit/+bug/1221372. Incluso en algunos casos, usando una normal
ALTERAR funcionará bastante bien. Como en mi ejemplo, para reconstruir la tabla por separado en cada esclavo en modo sin bloqueo, solo necesitaría actualizar a la última versión 5.6.
Por cierto, si se pregunta acerca de la replicación de Galera (usada en Percona XtraDB Cluster, etc.) ya que también usa un formato basado en ROW, eso no es un problema. Los disparadores de pt-osc se crean en todos los nodos gracias a la naturaleza de replicación síncrona de escribir en todas partes. No importa qué nodo haya iniciado
punto–en línea–esquema–cambio y en qué otros nodos escriben sus aplicaciones al mismo tiempo. ¡Sin esclavos, no hay problema! ⁇