Configuración de Replicación Asíncrona de MySQL: Una Guía Paso a Paso

Domina la configuración de replicación asíncrona de MySQL con esta guía definitiva paso a paso. Aprende a configurar correctamente los servidores Maestro y Esclavo ajustando la configuración de `my.cnf`, estableciendo cuentas de usuario de replicación seguras y realizando instantáneas de datos iniciales críticas usando `mysqldump`. Este artículo proporciona comandos prácticos y consejos esenciales para solucionar problemas, garantizando una sincronización de datos eficiente y minimizando la latencia de replicación para una arquitectura de base de datos escalable.

Configuración de Replicación Asíncrona de MySQL: Una Guía Paso a Paso

La replicación asíncrona de MySQL sigue siendo uno de los componentes más útiles en una configuración de base de datos. Puedes usarla para réplicas de lectura, copias de seguridad más seguras, copias para informes, preparación de migraciones y recuperación ante desastres. La palabra clave es "asíncrona": la fuente confirma una transacción sin esperar a que la réplica la aplique. Esto evita que la fuente se bloquee en cada escritura de la réplica, pero también significa que la réplica puede retrasarse.

La terminología antigua en muchos comandos de MySQL dice "master" y "slave". Las versiones más nuevas de MySQL usan "source" y "replica" en comandos como SHOW REPLICA STATUS y CHANGE REPLICATION SOURCE TO. Es posible que aún veas los comandos antiguos en sistemas, ejemplos y scripts antiguos. Esta guía usa fuente y réplica en la explicación, y muestra primero la forma más nueva del comando con notas sobre dónde difiere la sintaxis anterior.

El ejemplo utiliza dos servidores:

  • Fuente: 192.168.1.100
  • Réplica: 192.168.1.101
  • Usuario de replicación: repl_user
  • Alcance: todas las bases de datos, a menos que filtres intencionalmente

Haz esto primero en un entorno de prueba si no has realizado el procedimiento antes. La configuración de replicación es simple cuando todo está limpio. Se vuelve estresante cuando la fuente está ocupada, el volcado es inconsistente o la réplica ya contiene datos antiguos.

Antes de Tocar la Configuración

Confirma lo básico:

  • Ambos servidores ejecutan versiones compatibles de MySQL.
  • La réplica puede alcanzar la fuente en el puerto de MySQL, generalmente 3306.
  • Tienes acceso administrativo a ambas instancias de MySQL.
  • Puedes editar el archivo de configuración de MySQL y reiniciar MySQL si es necesario.
  • La réplica está vacía o sabes exactamente qué datos existentes deben ser reemplazados.
  • La fuente tiene suficiente espacio en disco para los registros binarios.

En el host de la réplica, prueba el acceso básico a la red:

nc -vz 192.168.1.100 3306

Si nc no está disponible, usa telnet o las herramientas de conectividad de tu proveedor de nube. Arregla firewalls, grupos de seguridad, direcciones de enlace y enrutamiento antes de configurar la replicación. Un usuario de replicación no ayudará si la ruta TCP está bloqueada.

Configurar el Servidor Fuente

La fuente debe escribir los cambios en los registros binarios. La réplica lee esos eventos y los almacena en registros de retransmisión antes de aplicarlos.

Edita el archivo de configuración de MySQL en la fuente. Las ubicaciones comunes son /etc/mysql/mysql.conf.d/mysqld.cnf, /etc/my.cnf o un archivo incluido desde esas rutas. Agrega o verifica estas configuraciones bajo [mysqld]:

[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW

server-id debe ser único en todos los servidores en la topología de replicación. log-bin habilita el registro binario. binlog_format=ROW es un valor predeterminado práctico para la mayoría de las configuraciones de replicación modernas porque registra cambios de fila en lugar de depender del comportamiento de re-ejecución de declaraciones.

Ten cuidado con binlog-do-db y binlog-ignore-db. Filtrar suena conveniente, pero puede sorprenderte porque el comportamiento basado en declaraciones depende de la base de datos predeterminada seleccionada por la sesión. Si necesitas replicación filtrada, diseñala y pruébala deliberadamente. Para una primera configuración confiable, replica todo.

Reinicia MySQL en la fuente:

sudo systemctl restart mysql
# o, en algunos sistemas
sudo systemctl restart mysqld

Verifica la configuración:

SHOW VARIABLES LIKE 'server_id';
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';

log_bin debe ser ON. El server_id debe ser distinto de cero y único.

Crear un Usuario de Replicación

Crea una cuenta dedicada en la fuente que la réplica usará. Limita el host a la dirección de la réplica si tu diseño de red lo permite:

CREATE USER 'repl_user'@'192.168.1.101' IDENTIFIED BY 'use_a_real_secret_here';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.1.101';

El nombre del privilegio sigue siendo REPLICATION SLAVE en las concesiones de MySQL, aunque la documentación más nueva a menudo dice "replica" en otros lugares.

Prueba el inicio de sesión desde el host de la réplica:

mysql -h 192.168.1.100 -u repl_user -p

Si esto falla, arregla la autenticación y la red ahora. Las causas comunes son bind-address en la fuente, reglas de firewall, discrepancia de host de usuario, resolución de DNS a una dirección diferente e incompatibilidad del complemento de autenticación con un cliente antiguo.

Configurar el Servidor Réplica

En la réplica, configura un server-id diferente. Los registros de retransmisión generalmente se habilitan automáticamente para la replicación, pero nombrarlos explícitamente puede hacer que las operaciones sean más claras:

[mysqld]
server-id=2
relay_log=mysql-relay-bin
read_only=ON

Para una protección más fuerte, considera super_read_only=ON después de la configuración. read_only no evita que todas las cuentas privilegiadas escriban. super_read_only es más seguro para réplicas que nunca deben aceptar escrituras de aplicaciones, pero es posible que debas desactivarlo temporalmente para ciertas tareas administrativas.

Reinicia MySQL en la réplica y verifica:

sudo systemctl restart mysql
SHOW VARIABLES LIKE 'server_id';
SHOW VARIABLES LIKE 'read_only';

Tomar una Instantánea Inicial Consistente

La réplica debe comenzar desde una copia de datos que coincida con una posición específica del registro binario. Si la instantánea y la posición no coinciden, la replicación puede iniciarse y aún así ser incorrecta.

Para bases de datos con mucho InnoDB, mysqldump --single-transaction suele ser el método consistente más simple. Evita un bloqueo de lectura global prolongado para tablas transaccionales. Incluye --source-data=2 en versiones más nuevas de MySQL para que el volcado registre el archivo de registro binario de la fuente y la posición como una línea comentada. Las versiones anteriores usan --master-data=2.

Ejecuta esto en un host confiable que pueda conectarse a la fuente:

mysqldump -h 192.168.1.100 -u root -p \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --source-data=2 \
  > source_dump.sql

Si tu versión de MySQL no soporta --source-data, usa:

mysqldump -h 192.168.1.100 -u root -p \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --master-data=2 \
  > source_dump.sql

--single-transaction es seguro para la consistencia de InnoDB, pero no hace que las tablas MyISAM no transaccionales sean consistentes de la misma manera. Si todavía tienes tablas MyISAM, planifica una ventana de mantenimiento o usa otro método de copia de seguridad que te proporcione una instantánea consistente.

Verifica el volcado en busca de las coordenadas de replicación registradas:

grep -m 1 -E "CHANGE (MASTER|REPLICATION SOURCE)" source_dump.sql

Deberías ver una línea comentada que contiene un archivo de registro binario y una posición. Guárdala. La usarás al apuntar la réplica a la fuente, a menos que elijas replicación basada en GTID.

Importar la Instantánea en la Réplica

Transfiere el volcado a la réplica usando tu método seguro normal:

scp source_dump.sql db-replica:/tmp/source_dump.sql

En la réplica, asegúrate de no estar escribiendo accidentalmente en un conjunto de datos existente similar al de producción. Si esta réplica debe ser una copia limpia, elimina y recrea solo lo que tu plan de migración dice que debe ser reemplazado. Luego importa:

mysql -u root -p < /tmp/source_dump.sql

Para volcados grandes, ejecuta la importación en screen o tmux, y vigila el espacio en disco. Una importación fallida porque /var/lib/mysql o /tmp se llenaron pierde tiempo y puede dejarte con una réplica medio cargada.

Apuntar la Réplica a la Fuente

En MySQL 8.0.23 y versiones posteriores, usa CHANGE REPLICATION SOURCE TO:

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.1.100',
  SOURCE_USER='repl_user',
  SOURCE_PASSWORD='use_a_real_secret_here',
  SOURCE_LOG_FILE='mysql-bin.000001',
  SOURCE_LOG_POS=1234;

Reemplaza el archivo y la posición con los valores del volcado. Si estás usando sintaxis anterior, el equivalente es:

CHANGE MASTER TO
  MASTER_HOST='192.168.1.100',
  MASTER_USER='repl_user',
  MASTER_PASSWORD='use_a_real_secret_here',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=1234;

Si tu entorno usa GTID, la configuración es diferente. Normalmente configuras el modo GTID en ambos servidores, restauras un volcado que conserva el estado GTID y usas SOURCE_AUTO_POSITION=1 en lugar de un archivo y una posición. No mezcles instrucciones de GTID y archivo-posición casualmente; elige un enfoque y pruébalo.

Una Breve Nota sobre la Replicación GTID

La replicación GTID a menudo es más fácil de operar una vez configurada porque MySQL rastrea las transacciones mediante identificadores de transacción globales en lugar de hacer que administres un archivo de registro binario y una posición manualmente. Es especialmente útil durante la conmutación por error, cambios de fuente y reconstrucciones de réplicas.

Eso no significa que debas activarlo casualmente en medio de una migración. Ambos servidores necesitan configuraciones GTID compatibles, y tu proceso de copia de seguridad o volcado debe conservar el estado GTID correcto. Un patrón común es configurar:

[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON

Luego, después de restaurar un volcado compatible con GTID, configura la réplica con:

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.1.100',
  SOURCE_USER='repl_user',
  SOURCE_PASSWORD='use_a_real_secret_here',
  SOURCE_AUTO_POSITION=1;

Usa esto solo si el historial GTID de la fuente y la réplica es limpio y se comprende. Si no estás seguro, la replicación de archivo y posición es más fácil de razonar para una primera configuración. La peor opción es mezclar ejemplos de ambos enfoques hasta que la replicación comience, pero el historial de transacciones no es lo que crees que es.

Inicia la replicación:

START REPLICA;

Sintaxis anterior:

START SLAVE;

Verifica el estado:

SHOW REPLICA STATUS\G

Sintaxis anterior:

SHOW SLAVE STATUS\G

Los campos clave son:

Campo Valor saludable Qué te dice
Replica_IO_Running Yes La réplica puede conectarse y obtener eventos de registro binario.
Replica_SQL_Running Yes La réplica puede aplicar eventos de registro de retransmisión.
Last_IO_Error vacío Los problemas de red, credenciales o registro de fuente se muestran aquí.
Last_SQL_Error vacío Los conflictos de datos y errores de aplicación se muestran aquí.
Seconds_Behind_Source bajo o decreciente Un indicador aproximado de retraso.

La salida anterior usa Slave_IO_Running, Slave_SQL_Running y Seconds_Behind_Master.

Probar con una Pequeña Escritura

No declares victoria después de que los hilos digan Yes. Crea una pequeña tabla de prueba o inserta una fila inofensiva en un esquema de prueba existente en la fuente, luego verifica que aparezca en la réplica.

Ejemplo en la fuente:

CREATE DATABASE IF NOT EXISTS repl_check;
CREATE TABLE IF NOT EXISTS repl_check.heartbeat (
  id INT PRIMARY KEY,
  checked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
REPLACE INTO repl_check.heartbeat (id) VALUES (1);

En la réplica:

SELECT * FROM repl_check.heartbeat;

Esto detecta errores simples como apuntar a la fuente incorrecta, filtrar la base de datos o usar coordenadas obsoletas.

Asegurar el Canal de Replicación

Si el tráfico de replicación cruza una red no confiable, requiere TLS. Incluso dentro de una red privada, muchos equipos ahora prefieren el tráfico de base de datos cifrado porque los límites de la red cambian con el tiempo.

Como mínimo, crea el usuario y el canal de replicación para que las credenciales no se compartan con las cuentas de la aplicación. Para canales basados en TLS, configura los certificados según tu versión de MySQL y luego incluye opciones SSL en la configuración de la fuente de replicación. Las opciones exactas varían según la versión y la política de certificados, pero la intención es la misma: la réplica debe verificar que se está conectando a la fuente esperada y proteger las credenciales y los cambios de fila en tránsito.

También mantén el privilegio del usuario de replicación estrecho. No necesita acceso amplio de DDL o DML. Si alguien obtiene esa contraseña, el radio de explosión debe limitarse a leer registros de replicación, no a escribir datos de la aplicación.

Problemas Comunes de Configuración

Si Replica_IO_Running es No, la réplica no puede obtener eventos. Verifica:

  • SOURCE_HOST es correcto.
  • La fuente está escuchando en la dirección y puerto esperados.
  • Los firewalls y grupos de seguridad permiten el tráfico.
  • El host del usuario de replicación coincide con la IP de origen de la réplica.
  • La contraseña y el complemento de autenticación funcionan con la versión del cliente/servidor de la réplica.
  • El archivo de registro binario solicitado aún existe en la fuente.

Si Replica_SQL_Running es No, la réplica obtuvo eventos pero no pudo aplicarlos. Verifica Last_SQL_Error. Las claves duplicadas a menudo significan que la réplica no se inicializó desde la instantánea coincidente exacta o alguien escribió directamente en la réplica. Las filas faltantes a menudo significan desviación de datos. Omitir una transacción con SQL_SLAVE_SKIP_COUNTER puede hacer que el hilo se mueva, pero también puede hacer que la réplica sea incorrecta. Úsalo solo cuando entiendas la transacción fallida y aceptes el riesgo de divergencia.

Si el retraso es alto justo después de la configuración, deja que la réplica se ponga al día y observa si Seconds_Behind_Source disminuye. Una importación de volcado grande seguida del inicio de la replicación puede dejar un trabajo atrasado. Si el retraso crece en lugar de reducirse, inspecciona la E/S del disco en la réplica y el volumen de escritura en la fuente.

Mantener la Réplica Saludable Después de la Configuración

Configura la retención de registros binarios en la fuente para que las réplicas puedan sobrevivir al mantenimiento y las interrupciones. MySQL moderno usa binlog_expire_logs_seconds:

[mysqld]
binlog_expire_logs_seconds=604800

Ese ejemplo mantiene los registros durante aproximadamente 7 días. Elige un valor basado en tus necesidades de recuperación y capacidad de disco. Los sistemas más antiguos pueden usar expire_logs_days.

Monitorea el estado y el retraso de la replicación. Como mínimo, alerta cuando cualquiera de los hilos de replicación se detenga, cuando el retraso exceda tu tolerancia y cuando el uso del disco de la fuente crezca porque los registros binarios no se purgan. Para comprobaciones de consistencia de datos, muchos equipos usan herramientas de Percona Toolkit como pt-table-checksum y pt-table-sync, pero pruébalas cuidadosamente antes de ejecutarlas en datos de tamaño de producción.

Finalmente, mantén el tráfico de la aplicación alejado de la réplica hasta que estés seguro de que es de solo lectura, está actualizada y monitoreada. Una réplica que acepta escrituras accidentales es peor que ninguna réplica, porque el daño puede permanecer oculto hasta la conmutación por error o la recuperación.

La replicación asíncrona funciona bien cuando la instantánea inicial, las coordenadas del registro binario, los privilegios y el monitoreo están alineados. La mayoría de las configuraciones fallidas provienen de que uno de esos se asume en lugar de verificarse.