TL;DR — Resumen Rápido

Guia completa de replicacion MySQL master-slave para alta disponibilidad: binary logs, configuracion de slaves, monitoreo de lag, failover y ProxySQL.

La replicacion de MySQL permite que un servidor (el master) transmita cada cambio de datos a uno o mas servidores replica (slaves) en tiempo casi real. El resultado es una arquitectura de alta disponibilidad donde el trafico de lectura se distribuye entre multiples nodos, los respaldos se pueden tomar desde un slave sin afectar al master, y un slave puede promoverse a master en minutos si el servidor primario falla. Esta guia cubre la configuracion completa de replicacion master-slave en MySQL 8.0: desde la configuracion de binary logs y la sincronizacion inicial de datos hasta el monitoreo de lag, la recuperacion de replicacion rota, los procedimientos de failover y la separacion de lectura/escritura con ProxySQL.

Arquitectura de Replicacion

La replicacion de MySQL funciona mediante tres componentes que trabajan en conjunto:

  • Binary log (binlog) — el master registra cada transaccion confirmada en un archivo de log secuencial. Existen tres formatos: STATEMENT (registra el texto SQL), ROW (registra los valores antes/despues de las filas modificadas) y MIXED (usa STATEMENT por defecto y cambia a ROW para funciones no deterministas). Usa siempre ROW en produccion.
  • IO thread — un hilo en el slave se conecta al master, lee los nuevos eventos del binary log y los escribe en el relay log local.
  • SQL thread — un segundo hilo en el slave lee el relay log y reproduce los eventos contra la base de datos local, manteniendo los datos sincronizados.

Modos de Replicacion

ModoComo FuncionaCuando Usarlo
Asincrono (defecto)El master no espera ACK del slaveHA general, escalado de lecturas
Semi-sincronoEl master espera que al menos un slave escriba el relay logDatos financieros, menor riesgo de perdida
Group ReplicationMulti-master con protocolo de consenso (Paxos)Activo-activo, failover automatico

Prerrequisitos

  • Dos servidores Linux con MySQL 8.0 o 8.4 (Ubuntu 22.04+ o RHEL 9+)
  • Acceso root o sudo en ambos servidores
  • Conectividad de red entre master y slave (puerto 3306 abierto)
  • server-id del master y del slave deben ser enteros unicos en toda la topologia

Paso 1: Configurar el Servidor Master

Edita la configuracion de MySQL en el master:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Agrega o modifica estas opciones en la seccion [mysqld]:

[mysqld]
# ID unico para este servidor — debe ser diferente en cada nodo
server-id = 1

# Habilita el binary log — obligatorio para replicacion
log-bin = /var/log/mysql/mysql-bin
binlog-format = ROW

# Conserva 7 dias de binary logs
expire_logs_days = 7

# Sincroniza el binlog a disco en cada commit — evita perdida de datos
sync_binlog = 1

# Replicacion basada en GTID (recomendada para MySQL 8.0+)
gtid_mode = ON
enforce_gtid_consistency = ON

Aplica la configuracion:

sudo systemctl restart mysql

Verifica que el binary log este activo:

SHOW VARIABLES LIKE 'log_bin';
-- log_bin | ON

SHOW MASTER STATUS\G
-- File: mysql-bin.000003
-- Position: 1573

Paso 2: Crear el Usuario de Replicacion

En el master, crea un usuario dedicado con solo los permisos necesarios para replicacion:

CREATE USER 'repl'@'192.168.1.102' IDENTIFIED BY 'ReplStr0ng!Pass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.102';
FLUSH PRIVILEGES;

Reemplaza 192.168.1.102 con la IP real del slave. Nunca uses % (cualquier host) para usuarios de replicacion — restringe por IP por seguridad.

Paso 3: Tomar un Snapshot Consistente

Necesitas un snapshot consistente en un punto del tiempo del master para inicializar el slave. El flag --master-data registra automaticamente la posicion del binary log dentro del archivo de volcado.

# Opcion A: mysqldump (adecuado para bases de datos menores a ~50 GB)
mysqldump -u root -p \
  --all-databases \
  --master-data=2 \
  --single-transaction \
  --flush-logs \
  --routines \
  --triggers \
  > /tmp/master_dump.sql

# Opcion B: Percona XtraBackup (recomendado para bases grandes, sin bloqueo de tablas)
xtrabackup --backup --user=root --password=mipass \
  --target-dir=/tmp/xtrabackup/
xtrabackup --prepare --target-dir=/tmp/xtrabackup/

Transfiere el volcado al slave:

scp /tmp/master_dump.sql usuario@192.168.1.102:/tmp/

Paso 4: Configurar el Servidor Slave

En el slave, edita mysqld.cnf:

[mysqld]
# Debe ser diferente al master y a todos los demas slaves
server-id = 2

# Ubicacion del relay log
relay-log = /var/log/mysql/mysql-relay-bin

# Evita escrituras accidentales en el slave
read_only = 1
super_read_only = 1

# Necesario si este slave sera a su vez un master (replicacion en cadena)
log_slave_updates = 1

# Coincide con la configuracion GTID del master
gtid_mode = ON
enforce_gtid_consistency = ON
sudo systemctl restart mysql

Paso 5: Importar el Snapshot e Iniciar la Replicacion

Restaura el volcado del master en el slave:

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

Configura el slave para conectarse al master. Con modo GTID (recomendado):

CHANGE MASTER TO
  MASTER_HOST          = '192.168.1.101',
  MASTER_USER          = 'repl',
  MASTER_PASSWORD      = 'ReplStr0ng!Pass',
  MASTER_AUTO_POSITION = 1;

Sin GTID (basado en posicion tradicional), busca la posicion en el comentario del volcado:

grep "MASTER_LOG_FILE\|MASTER_LOG_POS" /tmp/master_dump.sql | head -5
# -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=1573;
CHANGE MASTER TO
  MASTER_HOST     = '192.168.1.101',
  MASTER_USER     = 'repl',
  MASTER_PASSWORD = 'ReplStr0ng!Pass',
  MASTER_LOG_FILE = 'mysql-bin.000003',
  MASTER_LOG_POS  = 1573;

Inicia la replicacion:

START SLAVE;

Paso 6: Monitorear la Salud de la Replicacion

SHOW SLAVE STATUS\G

Campos clave a verificar:

Slave_IO_Running: Yes          -- hilo IO conectado y funcionando
Slave_SQL_Running: Yes         -- hilo SQL reproduciendo eventos
Seconds_Behind_Master: 0       -- slave completamente al dia
Last_IO_Error: (vacio)         -- sin errores de conexion
Last_SQL_Error: (vacio)        -- sin errores de reproduccion

Para monitoreo continuo mediante performance_schema (MySQL 8.0+):

SELECT
  CHANNEL_NAME,
  SERVICE_STATE,
  LAST_ERROR_MESSAGE,
  LAST_HEARTBEAT_TIMESTAMP
FROM performance_schema.replication_connection_status;

Manejo del Lag de Replicacion

El lag de replicacion (Seconds_Behind_Master creciendo) es comun bajo cargas de escritura intensas:

CausaSolucion
Hilo SQL de un solo subprocesoHabilita workers de replicacion paralela
Consultas lentas en el slaveIdentifica con SHOW PROCESSLIST; optimiza
Cuello de botella de I/O en el slaveMueve los relay logs a almacenamiento mas rapido
Transacciones masivasDivide en lotes mas pequenos en el master
Latencia de redColoca master y slaves en el mismo datacenter

Habilitar replicacion paralela (MySQL 8.0):

STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_workers = 4;
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
START SLAVE SQL_THREAD;

Reparar la Replicacion Rota

Cuando Slave_SQL_Running: No aparece en SHOW SLAVE STATUS:

Saltar una Sola Transaccion con Error

STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
SHOW SLAVE STATUS\G

Saltar por GTID (Mas Seguro con Modo GTID)

STOP SLAVE;
-- Reemplaza con el GTID del mensaje Last_SQL_Error
SET GTID_NEXT = 'a1b2c3d4-1111-2222-3333-444444444444:1234';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START SLAVE;

Resincronizacion Completa desde el Master

STOP SLAVE;
RESET SLAVE ALL;
-- Toma el snapshot nuevamente desde el Paso 3 y reconfigura

Failover: Promover un Slave a Master

Cuando el master falla y necesitas promover un slave:

-- En el slave a promover:
SHOW SLAVE STATUS\G
-- Seconds_Behind_Master: 0

STOP SLAVE;
RESET SLAVE ALL;

-- Deshabilita modo de solo lectura — este servidor es ahora el master
SET GLOBAL read_only = 0;
SET GLOBAL super_read_only = 0;

Actualiza las cadenas de conexion de la aplicacion a la nueva IP del master y reconfigura los slaves restantes:

-- En los slaves restantes:
STOP SLAVE;
CHANGE MASTER TO
  MASTER_HOST          = '192.168.1.102',
  MASTER_AUTO_POSITION = 1;
START SLAVE;

Paso 7: ProxySQL para Separacion Lectura/Escritura

ProxySQL se situa entre la aplicacion y MySQL, enrutando escrituras al master y lecturas a los slaves de forma transparente.

# Instalar ProxySQL (Ubuntu)
wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | sudo apt-key add -
echo "deb https://repo.proxysql.com/ProxySQL/proxysql-2.x/$(lsb_release -sc)/ ./" \
  | sudo tee /etc/apt/sources.list.d/proxysql.list
sudo apt update && sudo apt install proxysql
sudo systemctl enable --now proxysql

Configura mediante la interfaz admin de ProxySQL (puerto 6032):

-- Agregar servidores: hostgroup 0 = escritura (master), hostgroup 1 = lectura (slave)
INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES
  (0, '192.168.1.101', 3306),
  (1, '192.168.1.102', 3306);

-- Agregar usuario de la aplicacion
INSERT INTO mysql_users (username, password, default_hostgroup) VALUES
  ('appuser', 'AppPass123!', 0);

-- Enrutar consultas SELECT al hostgroup de lectura
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES
  (1, 1, '^SELECT.*', 1, 1);

-- Aplicar y persistir cambios
LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL USERS TO RUNTIME;   SAVE MYSQL USERS TO DISK;
LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;

La aplicacion se conecta a ProxySQL en el puerto 6033 y todo el enrutamiento se gestiona de forma transparente.

Comparacion: Replicacion MySQL vs Alternativas

SolucionArquitecturaFailoverEscalado de EscriturasComplejidad
Replicacion MySQLMaster + slavesManual o MHANo (master unico)Baja
MySQL Group ReplicationMulti-master PaxosAutomaticoLimitadoMedia
Galera Cluster (MariaDB)Multi-master sincronoAutomaticoSiMedia
VitessMySQL con shardingAutomaticoSi (sharding)Alta
PlanetScaleVitess administradoAdministradoSiBaja (administrado)
PostgreSQL StreamingPrimario + standbysPatroni/manualNoBaja-Media

La replicacion asincrona de MySQL es el punto de partida de menor complejidad. Migra a Group Replication o Galera cuando necesites failover automatico.

Casos Especiales y Advertencias

  • server-id debe ser globalmente unico en todos los nodos — dos nodos con el mismo ID corrompen silenciosamente la replicacion
  • read_only=1 no bloquea a usuarios SUPER — usa super_read_only=1 para bloquear completamente el slave
  • Las transacciones grandes bloquean el hilo IO — usa pt-online-schema-change para operaciones DDL grandes
  • Diferencias de zona horaria causan errores de replicacion — establece default-time-zone='+00:00' en todos los nodos

Resumen

  • La replicacion MySQL usa binary logs, hilos IO y hilos SQL para mantener los slaves sincronizados
  • Usa binlog-format=ROW, sync_binlog=1 y modo GTID (gtid_mode=ON) en produccion
  • Monitorea Slave_IO_Running, Slave_SQL_Running y Seconds_Behind_Master continuamente
  • Habilita workers de replicacion paralela para reducir el lag bajo cargas de escritura intensas
  • Usa RESET SLAVE ALL para una reconfiguracion limpia en lugar de intentar parchear un estado roto
  • ProxySQL enruta transparentemente las lecturas a los slaves y las escrituras al master

Articulos Relacionados