Ir al contenido
EuroVPSEuroVPS

Seconds_Behind_Master no es una comprobación de salud de la réplica

Por qué el lag de replicación por sí solo puede dar por sana una réplica que no lo está, y cómo comprobar réplicas MySQL y MariaDB por GTID y checksum.

Por EuroVPS Engineering

5 min de lectura
Seconds_Behind_Master is not a replica health check

La réplica desde la que restauraría solo vale algo si está al día, es consistente y está fuera del alcance de un atacante. La mayoría de la monitorización comprueba un número, el lag de replicación, y ese número puede marcar cero en una réplica que dejó de recibir cambios hace una hora. Así se comprueba una réplica de MySQL o MariaDB para que la respuesta signifique algo.

El problema con la cifra del lag

Seconds_Behind_Master (o Seconds_Behind_Source en MySQL más reciente) lo calcula el hilo SQL de la réplica: la diferencia entre la marca de tiempo del evento que está aplicando y la hora actual. No sabe nada de los eventos que no ha recibido.

Así que si el hilo de E/S que trae los cambios del primario está atascado en una conexión TCP medio abierta, el hilo SQL termina todo lo que ya tiene e informa de 0. La réplica parece perfecta. Mientras tanto ha dejado de moverse. La cifra también marca NULL cuando la replicación está detenida, y muchas comprobaciones tratan NULL como «sin lag».

Comprobación uno: los dos hilos, y los campos de error

La primera prueba es aburrida y detecta la mayoría de los problemas:

SHOW SLAVE STATUS\G      -- or SHOW REPLICA STATUS\G

Exija Slave_IO_Running: Yes y Slave_SQL_Running: Yes (los nombres Replica_ en MySQL más reciente), y exija que Last_IO_Error y Last_SQL_Error estén vacíos. Connecting en el hilo de E/S no es «en marcha», es una réplica que no puede alcanzar su origen.

Fije también un slave_net_timeout (o replica_net_timeout) corto junto con MASTER_HEARTBEAT_PERIOD en el canal de replicación. El primario envía entonces heartbeats cuando está ocioso, y una conexión muerta se detecta en segundos en lugar de esperar a que venza el timeout de red por defecto.

Comprobación dos: compare posiciones, no marcas de tiempo

Con replicación GTID, cada transacción confirmada tiene un identificador, y puede comparar directamente dónde está el primario con dónde está la réplica.

En MariaDB:

-- on the primary
SELECT @@gtid_binlog_pos;
-- on the replica
SELECT @@gtid_slave_pos;

En MySQL, compare @@gtid_executed en ambos lados, o pregunte directamente a la réplica si se ha puesto al día con un conjunto:

SELECT WAIT_FOR_EXECUTED_GTID_SET('<primary gtid_executed>', 5);

Cuando la posición del primario sigue avanzando y la de la réplica no, tiene una réplica parada, diga lo que diga la cifra del lag. Esta comparación es también la forma de terminar una resiembra o un cutover: ambos lados deben coincidir en la misma transacción antes de que nadie lo dé por hecho.

Comprobación tres: un heartbeat que escribe usted mismo

La medición de lag más honesta es una fila que el primario actualiza con su propio reloj, leída de vuelta en la réplica. pt-heartbeat, de Percona Toolkit, hace exactamente eso:

# on the primary, as a service
pt-heartbeat --update --database percona --create-table --daemonize
# on the replica, from monitoring
pt-heartbeat --check --database percona --master-server-id <id>

Como la medición viaja a través de la propia replicación, un hilo de E/S roto aparece como un lag que crece sin parar, que es lo que quería ver desde el principio. Una escritura de prueba en el primario seguida de una lectura en la réplica da la misma prueba a mano, y es la comprobación de aceptación más rápida para una réplica nueva.

Comprobación cuatro: ¿son los datos realmente los mismos?

La replicación puede correr tan contenta sobre datos que se han desviado, tras una sentencia que se comporta distinto en cada lado, una escritura hecha en la réplica por error o un tipo de tabla que no replica de forma segura. pt-table-checksum ejecuta checksums por fragmentos en el primario y deja que la replicación los lleve a la réplica, después informa de las tablas que difieren:

pt-table-checksum --replicate=percona.checksums --no-check-binlog-format h=<primary>

Ejecútelo con una programación que se ajuste a su volumen de escrituras, fuera de las horas punta. Ponga read_only = ON en cada réplica (y super_read_only = ON en MySQL) para que nada, incluida la herramienta de un administrador, pueda escribir en ella por accidente.

Comprobación cinco: en qué dirección va la conexión

Esta no trata del lag en absoluto. Una réplica es su copia de recuperación, así que debería ser el lado que inicia el contacto. La réplica abre la conexión de replicación hacia el primario; el primario no debería tener ningún camino de red hacia la réplica.

Pruébelo en lugar de suponerlo. Desde el primario:

nc -vz -w 3 <replica-address> 3306

Eso debería agotar el tiempo de espera. Si conecta, un atacante que controle su servidor de producción también puede alcanzar la copia desde la que planea recuperarse. Nosotros imponemos la dirección en los appliances de firewall, no en los hosts, y lo demostramos en cada construcción.

Alerte sobre el estado, no sobre cada muestra

Reúna todo lo anterior en un único estado por réplica: OK, LAGGING (por encima de un umbral acordado) o BROKEN (un hilo caído, un error registrado o la posición GTID congelada mientras el primario avanza). Después alerte solo cuando el estado cambie, incluido el cambio de vuelta a OK.

state=$(replica_state)          # your check, returns OK, LAGGING or BROKEN
last=$(cat /var/lib/replcheck/state 2>/dev/null)
if [ "$state" != "$last" ]; then
  notify "replica: $last -> $state"
  echo "$state" > /var/lib/replcheck/state
fi

Ejecútelo cada pocos minutos desde un timer. Los ingenieros reciben un mensaje cuando algo cambia y otro cuando se recupera, no un torrente que aprenden a ignorar. El riesgo real con las réplicas no es el lag; es una réplica que se detuvo hace semanas sin que nadie se diera cuenta.

Resembrar sin adivinar

Cuando una réplica sí necesita reconstruirse, GTID elimina la búsqueda de coordenadas del binary log. Un volcado lógico consistente con la posición incrustada, o un backup físico con Mariabackup o Percona XtraBackup, le da la transacción exacta desde la que empezar. En MariaDB el lado de la réplica se reduce a:

SET GLOBAL gtid_slave_pos = '<position from the dump or backup>';
CHANGE MASTER TO MASTER_HOST='<primary>', MASTER_USER='repl',
  MASTER_PASSWORD='<secret>', MASTER_USE_GTID=slave_pos;
START SLAVE;

Después vuelva a ejecutar las comprobaciones uno a tres y no dé el visto bueno hasta que ambos lados informen del mismo GTID tras una escritura de prueba.

Su lista de comprobación

  • Los dos hilos de replicación en marcha, campos de error vacíos, un periodo de heartbeat fijado en el canal.
  • Posiciones GTID del primario y la réplica comparadas, no solo la cifra del lag.
  • Una fila de heartbeat o una escritura de prueba que demuestre que los cambios llegan de verdad.
  • Checksums programados, y read_only en cada réplica.
  • El primario no puede abrir una conexión hacia la réplica, demostrado desde el primario.
  • Alertas sobre cambios de estado, para que una réplica parada sea un mensaje en minutos, no un descubrimiento el día en que la necesite.

Si quiere un segundo par de ojos sobre sus réplicas, ese es el tipo de trabajo que nos gusta.

Hable con un ingeniero

Related (rows[1])

Relacionado: Replicación de bases de datos y réplicas en otra sede · Bases de datos en clúster con Percona XtraDB Cluster · Migraciones de datacenter gestionadas, ensayadas

Publicado el 8 de octubre de 2026.

Todas las notas de campo