sql >> Base de Datos >  >> RDS >> Mysql

Principales errores a evitar en la replicación de MySQL

Configurar la replicación en MySQL es fácil, pero administrarla en producción nunca ha sido una tarea fácil. Incluso con el nuevo posicionamiento automático de GTID, aún puede salir mal si no sabe lo que está haciendo. Después de configurar la replicación, todo tipo de cosas pueden salir mal. Los errores se pueden cometer fácilmente y pueden tener un final desastroso para sus datos.

Esta publicación destacará algunos de los errores más comunes que se cometen con la replicación de MySQL y cómo puede prevenirlos.

Configuración de la replicación

Al configurar la replicación de MySQL, debe preparar los nodos esclavos con el conjunto de datos del maestro. Con soluciones como el clúster de Galera, esto se maneja automáticamente con el método que elija. Para la replicación de MySQL, debe hacerlo usted mismo, por lo que, naturalmente, debe usar su herramienta de copia de seguridad estándar.

Para MySQL hay una gran variedad de herramientas de copia de seguridad disponibles, pero la más utilizada es mysqldump. Mysqldump genera una copia de seguridad lógica del conjunto de datos de su maestro. Esto significa que la copia de los datos no será una copia binaria, sino un archivo grande que contiene consultas para recrear su conjunto de datos. En la mayoría de los casos, esto debería proporcionarle una copia (casi) idéntica de sus datos, pero hay casos en los que no lo hará, debido a que el volcado se realiza por objeto. Esto significa que incluso antes de comenzar a replicar datos, su conjunto de datos no es el mismo que el del maestro.

Hay un par de ajustes que puede hacer para que mysqldump sea más confiable, como volcar como una sola transacción, y tampoco olvide incluir rutinas y disparadores:

mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql

Una buena práctica es verificar si su nodo esclavo es 100% igual, usando pt-table-checksum después de configurar la replicación:

pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass

Esta herramienta calculará una suma de verificación para cada tabla en el maestro, replicará el comando en el esclavo y luego el nodo esclavo realizará la misma operación de suma de verificación. Si alguna de las tablas no es la misma, esto debería verse claramente en la tabla de suma de comprobación.

Uso del método de replicación incorrecto

El método de replicación predeterminado de MySQL fue la llamada replicación basada en declaraciones. Este método es exactamente lo que es:un flujo de replicación de cada instrucción ejecutada en el maestro que se reproducirá en el nodo esclavo. Dado que MySQL en sí mismo es de subprocesos múltiples pero su replicación (tradicional) no lo es, el orden de las declaraciones en el flujo de replicación puede no ser 100% igual. Además, reproducir una declaración puede dar resultados diferentes cuando no se ejecuta exactamente al mismo tiempo.

Esto puede resultar en conjuntos de datos diferentes entre el maestro y el esclavo, debido a la deriva de datos. Esto no fue un problema durante muchos años, ya que no muchos ejecutaron MySQL con muchos subprocesos simultáneos, pero con las arquitecturas modernas de múltiples CPU, esto se ha vuelto muy probable en una carga de trabajo normal del día a día.

La respuesta de MySQL fue la llamada replicación basada en filas. La replicación basada en filas replicará los datos siempre que sea posible, pero en algunos casos excepcionales seguirá usando declaraciones. Un buen ejemplo sería el cambio de DLL de una tabla, donde la replicación tendría que copiar cada fila de la tabla a través de la replicación. Dado que esto es ineficiente, dicha declaración se replicará de la manera tradicional. Cuando la replicación basada en filas detecta la deriva de datos, detendrá el subproceso esclavo para evitar que empeore las cosas.

Entonces hay un método entre estos dos:replicación en modo mixto. Este tipo de replicación siempre replicará declaraciones, excepto cuando la consulta contenga la función UUID(), activadores, procedimientos almacenados, UDF y algunas otras excepciones. El modo mixto no resolverá el problema de la deriva de datos y, junto con la replicación basada en declaraciones, debe evitarse.

Replicación circular

A menudo, es necesario ejecutar la replicación de MySQL con varios maestros si tiene un entorno de varios centros de datos. Dado que la aplicación no puede esperar a que el maestro en el otro centro de datos reconozca su escritura, se prefiere un maestro local. Normalmente, el desplazamiento de incremento automático se utiliza para evitar conflictos de datos entre los maestros. Hacer que dos maestros se escriban entre sí de esta manera es una solución ampliamente aceptada.

Replicación maestro-maestro MySQL

Sin embargo, si necesita escribir en varios centros de datos en la misma base de datos, terminará con varios maestros que necesitan escribir sus datos entre sí. Antes de MySQL 5.7.6 no había ningún método para realizar una replicación de tipo malla, por lo que la alternativa sería utilizar una replicación de anillo circular en su lugar.

Topología de replicación en anillo MySQL

La replicación de anillo en MySQL es problemática por las siguientes razones:latencia, alta disponibilidad y deriva de datos. Al escribir algunos datos en el servidor A, se necesitarían tres saltos para terminar en el servidor D (a través del servidor B y C). Dado que la replicación de MySQL (tradicional) es de un solo subproceso, cualquier consulta de ejecución prolongada en la replicación puede detener todo el anillo. Además, si alguno de los servidores dejara de funcionar, el anillo se rompería y actualmente no existe ningún software de conmutación por error que pueda reparar las estructuras del anillo. Entonces, la deriva de datos puede ocurrir cuando los datos se escriben en el servidor A y se modifican al mismo tiempo en el servidor C o D.

Replicación de anillo roto

En general, la replicación circular no encaja bien con MySQL y debe evitarse a toda costa. Galera sería una buena alternativa para las escrituras de varios centros de datos, ya que se diseñó teniendo eso en cuenta.

Detener su replicación con actualizaciones grandes

A menudo, varios trabajos por lotes de limpieza realizarán varias tareas, que van desde la limpieza de datos antiguos hasta el cálculo de promedios de "me gusta" obtenidos de otra fuente. Esto significa que, a intervalos establecidos, un trabajo creará mucha actividad en la base de datos y, muy probablemente, escribirá una gran cantidad de datos en la base de datos. Naturalmente, esto significa que la actividad dentro del flujo de replicación aumentará por igual.

La replicación basada en declaraciones replicará las consultas exactas utilizadas en los trabajos por lotes, por lo que si la consulta tardó media hora en procesarse en el maestro, el subproceso esclavo se detendrá durante al menos la misma cantidad de tiempo. Esto significa que no se pueden replicar otros datos y los nodos esclavos comenzarán a retrasarse respecto del maestro. Si esto supera el umbral de su herramienta de conmutación por error o proxy, puede eliminar estos nodos esclavos de los nodos disponibles en el clúster. Si está utilizando la replicación basada en declaraciones, puede evitar esto procesando los datos para su trabajo en lotes más pequeños.

Ahora puede pensar que la replicación basada en filas no se ve afectada por esto, ya que replicará la información de la fila en lugar de la consulta. Esto es parcialmente cierto, ya que para los cambios de DDL, la replicación vuelve al formato basado en declaraciones. Además, una gran cantidad de operaciones CRUD afectarán el flujo de replicación:en la mayoría de los casos, esta sigue siendo una operación de un solo subproceso y, por lo tanto, cada transacción esperará a que la anterior se reproduzca a través de la replicación. Esto significa que si tiene una alta concurrencia en el maestro, el esclavo puede detenerse debido a la sobrecarga de transacciones durante la replicación.

Para evitar esto, tanto MariaDB como MySQL ofrecen replicación paralela. La implementación puede diferir según el proveedor y la versión. MySQL 5.6 ofrece replicación paralela siempre que las consultas estén separadas por un esquema. Tanto MariaDB 10.0 como MySQL 5.7 pueden manejar la replicación paralela entre esquemas, pero tienen otros límites. La ejecución de consultas a través de subprocesos esclavos paralelos puede acelerar su flujo de replicación si escribe mucho. Sin embargo, si no es así, lo mejor sería ceñirse a la replicación tradicional de un solo subproceso.

Cambios de esquema

Realizar cambios de esquema en una configuración de producción en ejecución siempre es una molestia. Esto tiene que ver con el hecho de que un cambio de DDL bloqueará una tabla la mayor parte del tiempo y solo liberará este bloqueo una vez que se haya aplicado el cambio de DDL. Incluso empeora una vez que comienza a replicar estos cambios DDL a través de la replicación de MySQL, donde además detendrá el flujo de replicación.

Una solución alternativa que se usa con frecuencia es aplicar primero el cambio de esquema a los nodos esclavos. Para la replicación basada en declaraciones, esto funciona bien, pero para la replicación basada en filas, esto puede funcionar hasta cierto punto. La replicación basada en filas permite que existan columnas adicionales al final de la tabla, por lo que siempre que pueda escribir las primeras columnas, estará bien. Primero aplique el cambio a todos los esclavos, luego realice la conmutación por error a uno de los esclavos y luego aplique el cambio al maestro y conéctelo como esclavo. Si su cambio implica la inserción de una columna en el medio o la eliminación de una columna, esto funcionará con la replicación basada en filas.

Existen herramientas que pueden realizar cambios de esquema en línea de manera más confiable. El cambio de esquema en línea de Percona (conocido como pt-osc) creará una tabla oculta con la nueva estructura de tabla, insertará nuevos datos a través de activadores y rellenará los datos en segundo plano. Una vez que haya terminado de crear la nueva tabla, simplemente cambiará la tabla anterior por la nueva dentro de una transacción. Esto no funciona en todos los casos, especialmente si su tabla existente ya tiene disparadores.

Una alternativa es la nueva herramienta Gh-ost de Github. Esta herramienta de cambio de esquema en línea primero hará una copia de su diseño de tabla existente, modificará la tabla al nuevo diseño y luego conectará el proceso como una réplica de MySQL. Hará uso de la secuencia de replicación para encontrar nuevas filas que se hayan insertado en la tabla original y, al mismo tiempo, rellenará la tabla. Una vez que se haya completado el relleno, las tablas originales y nuevas se intercambiarán. Naturalmente, todas las operaciones en la nueva tabla también terminarán en el flujo de replicación, por lo que en cada réplica la migración ocurre al mismo tiempo.

Tablas de memoria y replicación

Ya que estamos en el tema de los DDL, un problema común es la creación de tablas de memoria. Las tablas de memoria son tablas no persistentes, su estructura de tabla permanece pero pierden sus datos después de reiniciar MySQL. Al crear una nueva tabla de memoria tanto en un maestro como en un esclavo, ambos tendrán una tabla vacía y funcionará perfectamente bien. Una vez que se reinicia cualquiera de los dos, la tabla se vaciará y se producirán errores de replicación.

La replicación basada en filas se interrumpirá una vez que los datos en el nodo esclavo devuelvan resultados diferentes, y la replicación basada en declaraciones se interrumpirá una vez que intente insertar datos que ya existen. Para las tablas de memoria, este es un factor frecuente de interrupción de la replicación. La solución es fácil:simplemente haga una copia nueva de los datos, cambie el motor a InnoDB y ahora debería ser seguro para la replicación.

Establecer la variable de solo lectura en Verdadero

Como describimos anteriormente, no tener los mismos datos en los nodos esclavos puede interrumpir la replicación. A menudo, esto ha sido causado por algo (o alguien) que altera los datos en el nodo esclavo, pero no en el nodo maestro. Una vez que se modifican los datos del nodo maestro, se replicarán en el esclavo donde no puede aplicar el cambio y esto hace que la replicación se interrumpa.

Hay una prevención fácil para esto:establecer la variable read_only en verdadero. Esto no permitirá que nadie realice cambios en los datos, excepto los usuarios raíz y de replicación. La mayoría de los administradores de conmutación por error configuran este indicador automáticamente para evitar que los usuarios escriban en el maestro usado durante la conmutación por error. Algunos de ellos incluso conservan esto después de la conmutación por error.

Esto todavía deja al usuario root para ejecutar una consulta CRUD errante en el nodo esclavo. Para evitar que esto suceda, existe una variable super_read_only desde MySQL 5.7.8 que incluso impide que el usuario raíz actualice los datos.

Habilitación de GTID

En la replicación de MySQL, es esencial iniciar el esclavo desde la posición correcta en los registros binarios. La obtención de esta posición se puede hacer al hacer una copia de seguridad (xtrabackup y mysqldump lo admiten) o cuando ha dejado de trabajar como esclavo en un nodo del que está haciendo una copia. Comenzar la replicación con el comando CHANGE MASTER TO se vería así:

mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS=  04;

Comenzar la replicación en el lugar equivocado puede tener consecuencias desastrosas:los datos pueden escribirse dos veces o no actualizarse. Esto provoca la deriva de datos entre el nodo maestro y el esclavo.

Además, cuando la conmutación por error de un maestro a un esclavo implica encontrar la posición correcta y cambiar el maestro al host apropiado. MySQL no conserva los registros y posiciones binarios de su maestro, sino que crea sus propios registros y posiciones binarios. Para volver a alinear un nodo esclavo con el nuevo maestro, esto podría convertirse en un problema grave:la posición exacta del maestro en la conmutación por error se debe encontrar en el nuevo maestro, y luego todos los esclavos se pueden volver a alinear.

Para resolver este problema, tanto Oracle como MariaDB han implementado el Identificador de transacción global (GTID). Los GTID permiten la alineación automática de los esclavos, y tanto en MySQL como en MariaDB, el servidor determina por sí mismo cuál es la posición correcta. Sin embargo, ambos han implementado el GTID de manera diferente y, por lo tanto, son incompatibles. Si necesita configurar la replicación de uno a otro, la replicación debe configurarse con el posicionamiento de registro binario tradicional. Además, su software de conmutación por error debe tener en cuenta que no utilice GTID.

Conclusión

Esperamos haberte dado suficientes consejos para no meterte en problemas. Todas estas son prácticas comunes de los expertos en MySQL. Tuvieron que aprenderlo por las malas y con estos consejos nos aseguramos de que tú no tengas que hacerlo.

Tenemos algunos documentos técnicos adicionales que pueden ser útiles si desea obtener más información sobre la replicación de MySQL.

Documentos técnicos relacionados Proyecto de replicación de MySQLEl documento técnico de Proyecto de replicación de MySQL incluye todos los aspectos de una topología de replicación con los pormenores de la implementación, la configuración de la replicación, la supervisión, las actualizaciones, la realización de copias de seguridad y la gestión de la alta disponibilidad mediante proxies.Descargar Replicación de MySQL para alta disponibilidadEste tutorial incluye información sobre MySQL Replication, con información sobre las últimas características introducidas en 5.6 y 5.7. También hay una sección más práctica sobre cómo implementar y administrar rápidamente una configuración de replicación mediante ClusterControl.Download