MariaDB Galera Cluster es una solución de replicación síncrona multimaestro: todos los nodos aceptan escrituras y cada transacción se certifica en el grupo antes de confirmarse, de modo que ningún nodo se queda atrás ni pierde datos confirmados si otro cae. A diferencia de la replicación clásica primario/réplica, no hay que promocionar nada cuando falla un nodo; basta con que las aplicaciones se conecten a otro.
En este tutorial montarás un clúster de tres nodos con MariaDB 10.11 y Galera 4 desde los repositorios de Ubuntu 24.04, con transferencia de estado (SST) mediante mariabackup. Comprobarás la replicación, aprenderás a hacer mantenimiento nodo a nodo y a recuperar el clúster tras una caída completa.
Requisitos previos
- Tres servidores con Ubuntu 24.04 LTS, por ejemplo VPS de CubePath, con al menos 2 GB de RAM cada uno y un usuario no root con
sudo. - Conectividad por red privada entre los tres, con baja latencia. Galera confirma cada transacción en todos los nodos, así que la latencia entre ellos se suma a cada escritura.
- Número impar de nodos (tres como mínimo) para que el clúster mantenga quórum cuando uno cae.
En los ejemplos se usan estos nodos. Sustituye nombres e IP por los tuyos:
| Nodo | IP privada |
|---|---|
db1 | 10.0.0.11 |
db2 | 10.0.0.12 |
db3 | 10.0.0.13 |
Galera usa estos puertos entre nodos:
| Puerto | Uso |
|---|---|
| 3306/tcp | Clientes MariaDB |
| 4567/tcp y udp | Comunicación del grupo Galera |
| 4568/tcp | Transferencia incremental (IST) |
| 4444/tcp | Transferencia completa (SST) |
Paso 1: Instalar MariaDB y Galera en los tres nodos
Ejecuta en cada nodo:
sudo apt update
sudo apt install mariadb-server mariadb-backup galera-4 socat
mariadb-backup y socat son necesarios para el método de SST que usarás; galera-4 aporta la librería de replicación.
Comprueba la versión y que existe la librería de Galera:
mariadb --version
ls /usr/lib/galera/libgalera_smm.so
mariadb Ver 15.1 Distrib 10.11.13-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
/usr/lib/galera/libgalera_smm.so
El paquete arranca MariaDB como servidor independiente. Detén el servicio en los tres nodos antes de configurar el clúster:
sudo systemctl stop mariadb
Paso 2: Abrir los puertos entre nodos
Permite el tráfico de Galera y MariaDB solo desde la red privada del clúster. Ejecuta en cada nodo, ajustando la subred:
sudo ufw allow from 10.0.0.0/24 to any port 3306,4444,4567,4568 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4567 proto udp
Si tus aplicaciones se conectan desde otra red, añade también una regla para el puerto 3306 desde esa red. Comprueba las reglas con sudo ufw status.
Paso 3: Configurar Galera
La configuración de Galera va en un fichero dentro de /etc/mysql/mariadb.conf.d/. Se carga después de 50-server.cnf, así que sus valores prevalecen (incluido bind-address, que por defecto limita MariaDB a 127.0.0.1).
En db1, crea el fichero (si ya existe, sustituye su contenido):
sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
[galera]
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "galera_cluster"
wsrep_cluster_address = "gcomm://10.0.0.11,10.0.0.12,10.0.0.13"
# Identidad de este nodo
wsrep_node_name = "db1"
wsrep_node_address = "10.0.0.11"
# Transferencia de estado completa con mariabackup
wsrep_sst_method = mariabackup
wsrep_sst_auth = "mariabackup:your_strong_password"
# Requisitos de Galera
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
# Escuchar en la red para clientes y otros nodos
bind-address = 0.0.0.0
Qué significa cada bloque:
wsrep_cluster_addresslista todos los miembros. Un nodo que arranca intenta unirse a cualquiera de ellos.wsrep_node_nameywsrep_node_addressson los únicos valores que cambian entre nodos.wsrep_sst_method = mariabackuphace que un nodo nuevo reciba una copia completa sin bloquear las escrituras en el donante.wsrep_sst_authson las credenciales del usuario que crearás en el paso 5; sustituyeyour_strong_passwordpor una contraseña segura.binlog_format = roweinnodb_autoinc_lock_mode = 2son obligatorios en Galera. Solo se replican tablas InnoDB.
Copia el mismo fichero en db2 y db3, cambiando solo estas dos líneas:
# En db2
wsrep_node_name = "db2"
wsrep_node_address = "10.0.0.12"
# En db3
wsrep_node_name = "db3"
wsrep_node_address = "10.0.0.13"
Protege el fichero, ya que contiene una contraseña. En cada nodo:
sudo chmod 640 /etc/mysql/mariadb.conf.d/60-galera.cnf
sudo chown root:mysql /etc/mysql/mariadb.conf.d/60-galera.cnf
Paso 4: Arrancar el clúster en el primer nodo
El primer nodo no tiene a quién unirse, así que hay que arrancarlo en modo bootstrap, que crea un clúster nuevo. En db1:
sudo galera_new_cluster
galera_new_cluster arranca el servicio de MariaDB con --wsrep-new-cluster solo esta vez. Comprueba el estado:
sudo mariadb -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_size','wsrep_cluster_status','wsrep_local_state_comment','wsrep_ready');"
+---------------------------+---------+
| Variable_name | Value |
+---------------------------+---------+
| wsrep_cluster_size | 1 |
| wsrep_cluster_status | Primary |
| wsrep_local_state_comment | Synced |
| wsrep_ready | ON |
+---------------------------+---------+
Advertenciausa
galera_new_clustersolo para arrancar un clúster que está completamente parado. Si lo ejecutas en un nodo mientras el clúster sigue funcionando en otros, crearás un segundo clúster independiente y los datos divergirán.
Paso 5: Crear el usuario de SST
El usuario de mariabackup debe existir antes de que se unan los demás nodos, porque db1 lo usará como donante para copiarles los datos. En db1:
sudo mariadb
CREATE USER 'mariabackup'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR ON *.* TO 'mariabackup'@'localhost';
EXIT;
La contraseña debe coincidir con la de wsrep_sst_auth. Galera replica las sentencias CREATE USER y GRANT, así que el usuario existirá en todos los nodos.
Paso 6: Unir el segundo y el tercer nodo
En db2 arranca MariaDB de forma normal. Al no ser bootstrap, buscará el clúster en wsrep_cluster_address y pedirá un SST:
sudo systemctl start mariadb
La primera vez puede tardar según el volumen de datos. Sigue el proceso en el log:
sudo journalctl -u mariadb -f
Cuando veas una línea con Synced, pulsa Ctrl+C y repite en db3:
sudo systemctl start mariadb
Desde cualquier nodo, el tamaño del clúster debe ser ahora 3:
sudo mariadb -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';"
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
Habilita el servicio en los tres nodos para que arranque con el sistema y se una al clúster solo:
sudo systemctl enable mariadb
Paso 7: Probar la replicación
Crea una base de datos y una tabla en db2:
sudo mariadb -e "CREATE DATABASE galera_test; CREATE TABLE galera_test.t (id INT AUTO_INCREMENT PRIMARY KEY, nodo VARCHAR(10)); INSERT INTO galera_test.t (nodo) VALUES ('db2');"
Escribe también en db3:
sudo mariadb -e "INSERT INTO galera_test.t (nodo) VALUES ('db3');"
Lee desde db1:
sudo mariadb -e "SELECT * FROM galera_test.t;"
+----+------+
| id | nodo |
+----+------+
| 2 | db2 |
| 3 | db3 |
+----+------+
Las dos filas están en db1 aunque se escribieron en nodos distintos. Los saltos en id son normales: Galera ajusta auto_increment_increment y auto_increment_offset en cada nodo para que dos nodos nunca generen el mismo valor.
Borra la base de prueba:
sudo mariadb -e "DROP DATABASE galera_test;"
Paso 8: Monitorizar la salud del clúster
Estas variables de estado resumen la salud de cada nodo:
| Variable | Valor sano | Qué indica |
|---|---|---|
wsrep_cluster_size | Número de nodos | Cuántos miembros ve este nodo |
wsrep_cluster_status | Primary | non-Primary significa que el nodo ha perdido el quórum y rechaza consultas |
wsrep_local_state_comment | Synced | Joining, Donor/Desynced o Joined durante transferencias |
wsrep_ready | ON | Si el nodo acepta consultas |
wsrep_flow_control_paused | Cercano a 0 | Fracción de tiempo con la replicación pausada porque un nodo va lento |
Consulta las de control de flujo, que avisan de un nodo que frena a los demás:
sudo mariadb -e "SHOW GLOBAL STATUS LIKE 'wsrep_flow_control%';"
Un wsrep_flow_control_paused alto de forma sostenida indica que algún nodo tiene menos recursos (CPU o disco) que el resto o que la red entre nodos es lenta.
Paso 9: Mantenimiento nodo a nodo
Para actualizar paquetes o cambiar la configuración sin parar el servicio, trabaja con un nodo cada vez:
sudo systemctl stop mariadb
sudo apt update && sudo apt upgrade
sudo systemctl start mariadb
Antes de pasar al siguiente nodo, espera a que este vuelva a estar sincronizado:
sudo mariadb -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_local_state_comment','wsrep_cluster_size');"
Continúa solo cuando veas Synced y el tamaño completo. Si paras dos nodos de tres a la vez, el que queda pierde el quórum.
Paso 10: Recuperar el clúster tras una caída total
Si los tres nodos se paran (un corte eléctrico, por ejemplo), ninguno puede unirse a los otros y hay que volver a arrancar con bootstrap, pero desde el nodo con los datos más recientes.
Mira el fichero de estado de Galera en cada nodo:
sudo cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 9acf4d34-acdb-11ef-8b4a-6e2a7d1f3a10
seqno: 1523
safe_to_bootstrap: 1
- Si los nodos se pararon de forma ordenada, el último en pararse tiene
safe_to_bootstrap: 1. Arranca ese consudo galera_new_clustery después los demás consudo systemctl start mariadb. - Si hubo una caída abrupta, todos tendrán
seqno: -1ysafe_to_bootstrap: 0. Recupera la posición real en cada nodo:
sudo galera_recovery
--wsrep_start_position=9acf4d34-acdb-11ef-8b4a-6e2a7d1f3a10:1523
El número tras los dos puntos es la última transacción aplicada. Elige el nodo con el valor más alto, marca que es seguro arrancar desde él:
sudo sed -i 's/^safe_to_bootstrap: 0/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat
Y arranca el clúster desde ese nodo, y luego los demás:
sudo galera_new_cluster
Solución de problemas
Un nodo no se une y el log muestra errores de SST: revisa que el usuario mariabackup existe en el donante y que su contraseña coincide con wsrep_sst_auth, que socat y mariadb-backup están instalados en ambos nodos y que el puerto 4444 está abierto. El log del donante (journalctl -u mariadb) suele dar el motivo exacto.
WSREP: failed to open gcomm backend connection: el nodo no llega a ningún miembro de wsrep_cluster_address. Comprueba los puertos 4567 tcp/udp y que al menos otro nodo esté funcionando. Si es el primer arranque del clúster, faltó usar galera_new_cluster.
ERROR 1047 (08S01): WSREP has not yet prepared node for application use: el nodo está en non-Primary (sin quórum) o todavía sincronizando. Comprueba wsrep_cluster_status y la conectividad con el resto.
Deadlocks al escribir la misma fila desde varios nodos: es el comportamiento esperado de la certificación optimista de Galera; una de las transacciones se aborta. Reintenta la transacción en la aplicación o envía las escrituras a un único nodo.
Conclusión
Tienes un clúster MariaDB Galera de tres nodos en Ubuntu 24.04 con replicación síncrona multimaestro, SST por mariabackup, monitorización básica y un procedimiento para mantenimiento y recuperación. Como siguientes pasos puedes:
- Poner un balanceador delante (HAProxy o MaxScale) para que las aplicaciones usen una única dirección y los nodos caídos salgan del grupo automáticamente.
- Cifrar el tráfico entre nodos con TLS, sobre todo si no usan una red privada.
- Programar copias de seguridad con
mariadb-backupdesde uno de los nodos y probar su restauración periódicamente.
