- Introducción a la Replicación Paralela
La replicación paralela es una técnica fundamental para reducir la latencia de replicación entre servidores MySQL master y slave. El objetivo principal es minimizar el tiempo que tardan las transacciones en reflejarse desde el servidor principal hacia los servidores secundarios.
El funcionamiento de la replicación paralela se basa en:
- Configurar group commits en el servidor master
- Activar múltiples hilos SQL en el slave para reproducir transacciones de forma concurrente
El proceso funciona de la siguiente manera: el hilo IO transfiere las operaciones que pueden ejecutarse en paralelo hacia los hilos worker. Desde MySQL 5.5 hasta 5.7, la granularidad de paralelización ha evolucionado significativamente, pasando desde replication a nivel de base de datos, luego a tabla, y finalmente a nivel de fila. Fue en MySQL 5.7 donde esta característica alcanzó su máximo desarrollo.
Causas de延迟en la Replicación Master-Slave:
- La escritura del binlog en el master y la lectura por parte del dump_thread son operaciones secuenciales (solo en MySQL 5.7+ estas operaciones son paralelas mediante group commit)
- El hilo SQL de reproducción tiene un único hilo (problema resuelto con replicación paralela)
- Existen diferencias de rendimiento de hardware entre los servidores master y slave
- El master puede tener transacciones grandes que requieren tiempo de procesamiento
- Configuración de la Replicación Paralela
2.1 Configuración con GTID
Configuración en el servidor Master:
binlog_group_commit_sync_delay=100
binlog_group_commit_sync_no_delay_count=10
Configuración en el servidor Slave:
# Configuración de hilos Multi-thread
slave_parallel_type=LOGICAL_CLOCK
slave_parallel_workers=8
slave_preserve_commit_order=1
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
log_slave_updates=1
2.2 Verificación del Funcionamiento
Después de reiniciar los servicios, es fundamental verificar que el estado de replicación sea correcto, confirmando que ambos hilos (SQL e IO) estén en estado "Yes". Si hay errores de configuración, la replicación no iniciaría correctamente.
Para visualizar el estado de los workers de replicación, ejecutar:
SELECT * FROM performance_schema.replication_applier_status_by_worker\G
El resultado debería mostrar una fila por cada worker configurado, donde el campo SERVICE_STATE debe mostrar "ON" para todos los hilos activos. Por ejemplo, si se configuraron 8 workers, aparecerán 8 registros diferentes con sus respectivos THREAD_ID.
También se puede monitorear mediante:
SHOW PROCESSLIST;
En un ambiente correctamente configurado, se observarán múltiples entradas con el usuario "system user" esperando eventos del Coordinador, indicando que los workers están activos y listos para procesar transacciones.
2.3 Monitoreo de la Replicación
Una vez habilitada la replicación paralela, se puede evaluar el rendimiento comparando los valores de Read_Master_Log_Pos y Exec_Master_Log_Pos en la salida de SHOW SLAVE STATUS. La diferencia entre estos valores indica la cantidad de datos pendientes de aplicar.
También es posible utilizar GTID para realizar comparaciones precisas entre el estado del master y el slave.
- Descripción de Parámetros
binlog_group_commit_sync_delay
Parámetro global y dinámico, medido en microsegundos. Valor predeterminado: 0, rango válido: 0 a 1,000,000 (1 segundo).
Este parámetro controla el tiempo de espera después de un commit antes de sincronizar el binlog al disco. Cuando el valor es 0, no hay retraso. Cuando se establece un valor mayor a 0, se permite que múltiples transacciones sean escritas conjuntamente en una sola operación de disco, conocido como group commmit. Esta funcionalidad es la base de la replicación paralela.
binlog_group_commit_sync_no_delay_count
Parámetro global y dinámico,medido en cantidad de transacciones. Valor predeterminado: 0, rango válido: 0 a 1,000,000.
Define el número máximo de transacciones que pueden acumularse para un commit grupal. Si el número de transacciones alcanza este límite antes de que expire el tiempo definido en binlog_group_commit_sync_delay, se procede a escribir inmediatamente en el disco. Si el parámetro binlog_group_commit_sync_delay está deshabilitado (valor 0), este parámetro tampoco tendrá efecto.
Ejemplo práctico:
binlog_group_commit_sync_delay=100
binlog_group_commit_sync_no_delay_count=10
Con esta configuración, el sistema consolida y escribe en disco cada 100 microsegundos, o cuando se acumulan 10 transacciones pendientes,lo que ocurra primero. Ambos parámetros trabajan conjuntamente para optimizar el rendimiento del master. Es importante destacar que estos ajustes mejoran la eficiencia del master pero no afectan directamente la replicación paralela en el slave.
slave_parallel_type
MySQL 5.7 introdujo esta variable con dos posibles valores:
- DATABASE: Utiliza replicación paralela basada en bases de datos (valor predeterminado)
- LOGICAL_CLOCK: Utiliza replicación paralela basada en grupo de commits, correspondiendo directamente con los group commits del master
slave_parallel_workers
Define la cantidad de hilos worker que se utilizarán para la replicación paralela. Se recomienda establecer un valor mayor a 1 para beneficiarse de la paralelización. Si el valor es 1, el rendimiento puede ser inferior debido a la sobrecarga del coordinados, siendo preferible desactivar esta característica.
slave_preserve_commit_order
Este parámetro asegura que, en un entorno de replicación paralela, las transacciones en el slave se ejecuten en el mismo orden en que fueron registradas en el relay log, manteniendo así la misma secuencia de commits del master.
Ejemplo de comportamiento:
Supongamos que el relay log contiene tres transacciones A, B y C en ese orden, y las tres tienen el mismo last_committed. Aunque estas transacciones pueden ejecutarse en paralelo,la tienda de commits en el slave podría no seguir el orden A -> B -> C. Configurando slave_preserve_commit_order=ON se garantiza que el orden de ejecución sea exactamente el mismo que en el relay log y, por consecuencia, el mismo del master.
Características del parámetro:
- Ámbito: Global
- Modificable dinámicamente: Sí, pero requiere detener el hilo SQL
- Valor predeterminado: OFF
Este parámetro requiere que la replicación paralela esté ACTIVADA con slave_parallel_type=LOGICAL_CLOCK y slave_parallel_workers mayor a 0.
En versiones anteriores a MySQL 8.0.19, era obligatorio tener habilitadas ambos binlogs (log_bin y log_slave_updates) para utilizar esta opción. Desde MySQL 8.0.19, esta restricción fue eliminada.
Cuando un hilo está esperando que otras transacciones culminen, se puede observar el estado "Waiting for preceding transaction to commit" al ejecutar SHOW PROCESSLIST en el slave.
Nota importante:
ERROR 3031 (HY000): slave_preserve_commit_order is not supported
unless both log_bin and log_slave_updates are enabled.
Para utilizar esta funcionalidad debe asegurarse de tener habilitado log_bin y log_slave_updates=1.
master_info_repository y relay_log_info_repository
El parámetro master_info_repository determina si el estado del slave respecto al master se almacena en el archivo master.info o en la tabla slave_master_info.
Este parámetro acepta dos valores: "file" o "table". Si se utiliza "file", se creará un archivo master.info en el sistema de archivos. Si se selecciona "table", se creará una tabla llamada slave_master_info en la base de datos mysql.
Al habilitar la funcionalidad MTS (Multi-Threaded Slave), es altamente recomendable establecer master_info_repository=TABLE, lo cual puede generar mejoras de rendimiento entre 50% y 80%. Esto se debe a que la replicación paralela genera un volumen significativamente mayor de actualizaciones al archivo master.info, aumentando la competencia por recursos del sistema de archivos.
En versiones anteriores de MySQL (como InnoSQL), existía parámetros para controlar la frecuencia de actualización del archivo master.info, e incluso era posible deshabilitar completamente estas actualizaciones, ya que depender de este archivo para recover no era seguro.
Recomendación para MySQL 5.7 y posteriores:
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
relay_log_recovery
Este parámetro viene habilitado por defecto. Cuando la base de datos inicia, inmediatamente se ejecuta la recuperación automática del relay log. Durante este proceso, se crea un nuevo archivo de relay log, se inicializa la posición del hilo SQL al inicio del nuevo relay log, y el hilo IO se posiciona donde estaba el hilo SQL.
Durante la operación normal de MySQL, el slave puede experimentar caídas inesperadas. Al reiniciar, debe ser capaz de restaurar el estado exacto que tenía antes de la interrupción: el hilo IO debe continuar desde la posición donde recibió la última transacción, y el hilo SQL debe reanudar desde la transacción que estaba procesando.
Históricamente, esta información se almacenaba en archivos del sistema, lo cual podía generar inconsistencias. Desde MySQL 5.7, es posible almacenar esta metadata en tablas InnoDB, aprovechando las propiedades transaccionales del motor de almacenamiento para garantizar la integridad de la información de recuperación.
La configuración recomendada es establecer master_info_repository=table y relay_log_info_repository=table.
Comportamiento según el modo de replicación:
Modo de replicación de hilo único (MySQL 5.7):
- Para replicación basada en GTID con master_auto_position y relay_log_recovery=0, la configuración se maneja automáticamente
- Para replicación tradicional, configurar relay_log_recovery=1 y relay_log_info_repository=table
Modo de replicación multihilo (MySQL 5.7):
- Para replicación basada en GTID con master_auto_position y relay_log_recovery=0, la configuración es automática
- Para replicación tradicional, configurar relay_log_recovery=1, sync_relay_log=1 y relay_log_info_repository=table