Ir al contenido
EuroVPSEuroVPS

Cómo leer la salud de un clúster Galera en cinco variables de estado

Las variables de estado wsrep que le dicen si un clúster Percona XtraDB o MariaDB Galera está sano, lento, o a un paso de perder el quórum.

Por EuroVPS Engineering

6 min de lectura
Cómo leer la salud de un clúster Galera en cinco variables de estado

Un clúster Galera (Percona XtraDB Cluster o MariaDB Galera) puede parecer perfectamente sano desde la aplicación mientras, en silencio, funciona con dos patas, se frena a sí mismo o retiene un nodo que necesitará una copia completa para reincorporarse. Cada uno de esos estados es visible en un puñado de variables de estado. Así las leemos nosotros, y esto es lo que cada una le está diciendo.

El problema: «responde consultas» no es una comprobación de salud

La mayor parte de la monitorización de una base de datos en clúster comprueba lo mismo que comprobaba en un servidor único: si el puerto 3306 está abierto, si SELECT 1 devuelve algo. Un nodo Galera que ha salido del componente primario sigue aceptando conexiones. Un nodo que está sincronizado pero aplica las escrituras demasiado despacio sigue respondiendo lecturas. Un clúster de tres que se ha convertido en silencio en un clúster de dos sigue sirviendo el sitio, justo hasta el momento en que se va el siguiente nodo y el quórum desaparece.

El clúster sabe todo esto de sí mismo. Solo tiene que preguntárselo.

La única consulta que ejecutar en cada nodo

SHOW GLOBAL STATUS WHERE Variable_name IN (
  'wsrep_cluster_status',
  'wsrep_cluster_size',
  'wsrep_local_state_comment',
  'wsrep_ready',
  'wsrep_cluster_state_uuid',
  'wsrep_flow_control_paused',
  'wsrep_local_recv_queue_avg',
  'wsrep_local_send_queue_avg',
  'wsrep_local_cert_failures',
  'wsrep_local_bf_aborts'
);

Ejecútela en cada miembro, no solo en el que su balanceador alcanza por casualidad. Varios de estos valores son locales al nodo, y los fallos interesantes son aquellos en los que los nodos no están de acuerdo.

Pertenencia: ¿forma este nodo realmente parte del clúster?

wsrep_cluster_status debe ser Primary. Cualquier otra cosa (Non-Primary, Disconnected) significa que este nodo ha perdido el contacto con la mayoría y se negará a servir datos consistentes. Si su comprobación de salud no mira este valor, un nodo particionado puede seguir recibiendo tráfico.

wsrep_cluster_size debe ser igual al número de nodos que construyó. Esta es la variable que detecta el «funcionar con dos patas». Un clúster de tres nodos que informa de dos sigue sirviendo, sigue en quórum, y no le queda tolerancia alguna. Alerte sobre ella como aviso en el momento en que baje del tamaño de diseño, no cuando llegue a uno.

wsrep_local_state_comment debería decir Synced. Donor/Desynced significa que el nodo está alimentando a un nodo que se incorpora y puede estar ralentizado; Joining y Joined significan que todavía se está poniendo al día. Un nodo en cualquier estado distinto de Synced debería salir del pool de lectura de su proxy hasta que vuelva.

wsrep_cluster_state_uuid debe ser idéntico en todos los nodos. Dos valores distintos significan que tiene dos clústeres que creen, cada uno, ser el clúster. Eso solo ocurre después de que alguien haga bootstrap del nodo equivocado, así que merece la pena comprobarlo tras cualquier recuperación manual.

wsrep_ready simplemente confirma que el nodo aceptará consultas; si dice OFF, los demás valores le dirán por qué.

Rendimiento: ¿se está frenando el clúster a sí mismo?

La replicación de Galera se basa en certificación: cada nodo tiene que estar de acuerdo en que un write set no entra en conflicto antes de que se confirme. Eso hace que el clúster sea tan rápido como su aplicador más lento, y Galera lo impone con flow control.

wsrep_flow_control_paused es la fracción de tiempo, desde el último FLUSH STATUS, en que la replicación estuvo en pausa porque algún nodo no podía seguir el ritmo. Léalo como un porcentaje. Cerca de cero es sano. Cualquier valor persistente por encima de un pequeño porcentaje significa que las escrituras esperan a un nodo lento, y la latencia de escritura de su aplicación lo está pagando. Haga flush, espere un intervalo conocido, lea de nuevo, para que el número describa el presente y no el mes pasado.

wsrep_local_recv_queue_avg le dice qué nodo es el lento. Un nodo cuya media de cola de recepción se mantiene claramente por encima de cero es el que dispara el flow control. Normalmente la causa es local: storage más lento, un vecino ruidoso, un informe de larga duración, o demasiado pocos hilos aplicadores (wsrep_applier_threads, o wsrep_slave_threads en versiones anteriores).

wsrep_local_send_queue_avg subiendo apunta en la otra dirección: este nodo tiene dificultades para enviar sus propios write sets, lo que normalmente significa latencia o pérdidas de red entre los miembros. Es la razón por la que los miembros de un clúster deben estar en el mismo fabric de baja latencia, con las copias en otra sede gestionadas por réplicas asíncronas.

Conflictos: ¿está escribiendo en más de un nodo?

wsrep_local_cert_failures y wsrep_local_bf_aborts cuentan las transacciones revertidas porque otro nodo confirmó primero un cambio en conflicto. La aplicación los ve como errores de deadlock. Un goteo constante en un clúster donde todos los nodos aceptan escrituras es la firma de la contención multi-writer, y los plugins de WordPress y de comercio electrónico que actualizan las mismas filas de opciones o contadores en cada petición lo producen en volumen.

La solución es arquitectónica, no un parámetro que ajustar: envíe todas las escrituras a un nodo y reparta las lecturas. Con ProxySQL es una sola fila:

INSERT INTO mysql_galera_hostgroups
  (writer_hostgroup, backup_writer_hostgroup, reader_hostgroup,
   offline_hostgroup, active, max_writers, writer_is_also_reader,
   max_transactions_behind)
VALUES (10, 20, 30, 40, 1, 1, 1, 100);
LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;

max_writers = 1 elige un writer, los demás pasan a ser readers y writers de respaldo, y max_transactions_behind permite a ProxySQL sacar automáticamente del pool de lectura a un nodo rezagado. Una vez que las escrituras van a un nodo, estos dos contadores deberían quedarse casi quietos.

Si después los editores se quejan de que un guardado «desapareció» al recargar, la lectura fue a un nodo que aún no había aplicado la escritura. Configurar wsrep_sync_wait para esas sesiones hace que la lectura espere a que el nodo se ponga al día, a cambio de un pequeño coste de latencia.

Reincorporación: ¿volverá un nodo deprisa o despacio?

Un nodo que sale y vuelve recibe o bien los write sets que le faltan desde la caché de un donante (IST, incremental y rápido) o bien una copia completa del conjunto de datos (SST, lento y pesado para el donante). Cuál de los dos recibe depende de si la caché de write sets del donante, gcache.size en wsrep_provider_options, conserva todavía todo lo que el nodo se perdió.

Puede dimensionarla a partir de los propios contadores del clúster. Lea wsrep_replicated_bytes y wsrep_received_bytes con una hora de diferencia; la suma de las diferencias es, aproximadamente, el volumen de write sets por hora. Multiplíquelo por la ventana de mantenimiento más larga que espere, añada un margen, y ese es el gcache que necesita. Un nodo puede entonces parchearse, reiniciarse o quedar parado durante horas de trabajo de hardware y aun así reincorporarse de forma incremental.

Quórum: la aritmética detrás del «tres»

El quórum es una mayoría estricta. Tres miembros toleran la pérdida de uno. Cuatro miembros también toleran solo uno, porque dos de cuatro no es mayoría, así que el cuarto nodo compra capacidad pero no resiliencia. Dos miembros no toleran nada: si se pierden de vista, ambos se detienen. Si de verdad tiene solo dos nodos de datos, añada el árbitro de Galera (garbd) en un tercer host independiente para que siga existiendo una mayoría.

La misma aritmética se aplica a dónde viven los miembros. Tres nodos en un host, o tres nodos cuyos datos están en una sola cabina de storage, son un único dominio de fallo con tres nombres. En Kubernetes, combine una anti-afinidad de pods estricta con un PodDisruptionBudget de minAvailable: 2, para que una actualización progresiva de nodos nunca pueda llevarse dos miembros a la vez.

Qué comprobar en su propio clúster esta semana

  • Cada nodo informa Primary, Synced, el mismo UUID de estado y el tamaño de clúster que diseñó.
  • Su comprobación de salud y su proxy usan esos valores, no solo una conexión TCP.
  • wsrep_flow_control_paused, medido sobre un intervalo fresco, está cerca de cero.
  • Los fallos de certificación no suben; si lo hacen, las escrituras están llegando a más de un nodo.
  • Su gcache cubre su ventana de mantenimiento planificada más larga.
  • No hay dos miembros que compartan un host, una cabina o (en Kubernetes) una interrupción sin presupuesto.

Un clúster Galera que se lee así rara vez sorprende a nadie. Si el suyo lo hace, con gusto le echamos un vistazo.

cta: Hable con un ingeniero

Related

  • /what-we-do/data-web/clustered-databases/
  • /what-we-do/data-web/database-replication/
  • /what-we-do/data-web/high-availability-platforms/

Publicado el 26 de agosto de 2026.

Todas las notas de campo