Creación de un Clúster de MariaDB con Galera en Ubuntu 24.04 Desktop

· 25min · linux

Introducción

La idea de esta entrada es la de la creación de un clúster de MariaDB con Galera en Ubuntu 24.04 Desktop.

Requisitos mínimos

3 máquinas con Ubuntu Server 24.04 nodo1: 192.168.1.81 nodo2: 192.168.1.82 nodo3: 192.168.1.83

Ubuntu 24.04

En los tres nodos deberíamos realizar los siguientes pasos:

Instalación de repositorios automática

curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

otra forma:

wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
chmod +x mariadb_repo_setup
sudo ./mariadb_repo_setup

Instalación de Repositorio APT manual

editar el fichero /etc/apt/sources.list.d/mariadb.list

# MariaDB Server
# To use a different major version of the server, or to pin to a specific minor version, change URI below.
deb [arch=amd64,arm64] https://dlm.mariadb.com/repo/mariadb-server/11.rolling/repo/ubuntu noble main

deb [arch=amd64,arm64] https://dlm.mariadb.com/repo/mariadb-server/11.rolling/repo/ubuntu noble main/debug

# MariaDB MaxScale
# To use the latest stable release of MaxScale, use "latest" as the version
# To use the latest beta (or stable if no current beta) release of MaxScale, use "beta" as the version
deb [arch=amd64,arm64] https://dlm.mariadb.com/repo/maxscale/latest/apt noble main

# MariaDB Tools
deb [arch=amd64] http://downloads.mariadb.com/Tools/ubuntu noble main

Metiendo las claves de los repositorios en su sitio

curl -LsSO https://supplychain.mariadb.com/mariadb-keyring-2019.gpg
sudo mv mariadb-keyring-2019.gpg /etc/apt/trusted.gpg.d/
sudo chmod 644 /etc/apt/trusted.gpg.d/mariadb-keyring-2019.gpg

Instalación de los paquetes vía APT

sudo apt update
sudo apt-get install -y \
mariadb-server galera-4 mariadb-client \
libmariadb3 mariadb-backup mariadb-common

Configuración del nodo principal

Editar el fichero /etc/mysql/mariadb.conf.d/50-server.cnf dentro de la sección [mariadbd] para verificar que guardamos datos en UTF8 4 Bytes

bind-address          = 0.0.0.0
character-set-server  = utf8mb4
collation-server      = utf8mb4_general_ci

Reiniciamos el servidor con

sudo systemctl restart mariadb

Configuramos la seguridad del nodo para Mariadb

sudo mysql_secure_installation

Recuerda reiniciar el servidor

sudo systemctl restart mariadb

Comprobaciones de acceso

sudo mariadb --user=root   --password

Al meter la password deberíamos tener ya acceso a la bbdd

Permitir el acceso desde fuera de Root con una contraseña

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Comprobar acceso externo

sudo mariadb --protocol=TCP  \
--host=192.168.1.81   \
--port=3306   \
--user=root   \
--password

Configuración de Galera

Desde el nodo principal

En el fichero /etc/mysql/mariadb.conf.d/60-galera.cnf

#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mariadb
# and read more at https://mariadb.com/kb/en/galera-cluster/

[galera]
# Mandatory settings
wsrep_on                 = ON
wsrep_provider           = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name       = "MariaDB Galera Cluster"
wsrep_cluster_address    = gcomm://
binlog_format            = row
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2

wsrep_sst_method=rsync
wsrep_slave_threads=2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0

# configuración específica de nodo
wsrep_node_name='nodo1'
wsrep_node_address="192.168.1.81"

# Optional settings
#wsrep_slave_threads = 1
#innodb_flush_log_at_trx_commit = 0

Reiniciamos el servidor

sudo systemctl restart mariadb

Ejecutamos el comando:

sudo galera_new_cluster

Nos Conectamos al servidor nodo1:

sudo mariadb --protocol=TCP  \
--host=192.168.1.81   \
--port=3306   \
--user=root   \
--password

Desde la consola comprobamos que tenemos ya el cluster montado

SHOW GLOBAL VARIABLES LIKE 'wsrep_on';

Debería dar una salida como:

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'wsrep_on';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_on      | ON    |
+---------------+-------+
1 row in set (0,001 sec)

luego debería ejecutar:

SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';

con la siguiente salida:

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 1     |
+--------------------+-------+
1 row in set (0,001 sec)

Para saber el status:

SHOW GLOBAL STATUS LIKE 'wsrep_cluster_status';

Salida para el status

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+
1 row in set (0,001 sec)

Para añadir un nuevo nodo

Desde el nodo secundario Primero paramos el servicio

sudo systemctl stop mariadb

Luego debemos modificar el fichero 60-galera.cnf para modificarlo y meter en el parámetro wsrep_cluster_address las IP de los servidores del cluster

#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mariadb
# and read more at https://mariadb.com/kb/en/galera-cluster/

[galera]
# Mandatory settings
wsrep_on                 = ON
wsrep_provider           = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name       = "MariaDB Galera Cluster"
wsrep_cluster_address    = gcomm://192.168.1.81,192.168.1.82
binlog_format            = row
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2

wsrep_sst_method=rsync
wsrep_slave_threads=2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0

# configuración específica de nodo
wsrep_node_name='nodo2'
wsrep_node_address="192.168.1.2"

# Optional settings
#wsrep_slave_threads = 1
#innodb_flush_log_at_trx_commit = 0

Con los cambios hechos en el fichero ahora ya podremos arrancar el servidor para que se enganche al clúster

sudo systemctl start mariadb

Si todo va bien deberíamos ver desde el nodo 1 que se ha metido el nuevo nodo al cluster

journalctl -xeu mariadb.service

Deberíamos ver algo similar a esto:

may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Provider resumed.
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: SST sent: ff4cc52d-2918-11f0-b834-f759c1a1f4e5:5
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Server status change donor -> joined
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: 0.0 (nodo1): State transfer to 1.0 (nodo2) complete.
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Shifting DONOR/DESYNCED -> JOINED (TO: 5)
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Processing event queue:... -nan% (0/0 events) complete.
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Member 0.0 (nodo1) synced with group.
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Processing event queue:... 100.0% (1/1 events) complete.
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 0 [Note] WSREP: Shifting JOINED -> SYNCED (TO: 5)
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 7 [Note] WSREP: Server nodo1 synced with group
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 7 [Note] WSREP: Server status change joined -> synced
may 04 18:56:18 nodo1 mariadbd[8165]: 2025-05-04 18:56:18 7 [Note] WSREP: Synchronized with group, ready for connection

Ahora podremos comprobar que tenemos dos nodos en el cluster

SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';

con la siguiente salida:

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 2     |
+--------------------+-------+
1 row in set (0,001 sec)

Dentro del nodo principal deberíamos poder cambiar la dirección wsrep_cluster_address para meter las direcciones de los dos nodos del cluster

wsrep_cluster_address    = gcomm://192.168.1.81,192.168.1.82

Y probamos a reiniciar el nodo principal

sudo sudo systemctl restart mariadb

Y debería arrancar sin problema Para comprobar por ejemplo el estado del un nodo, por ejemplo el nodo 2, ejecutaremos desde consola

SHOW STATUS LIKE 'wsrep_local_state_comment';

Y debería de dar la salida

+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+
1 row in set (0,002 sec)

Para meter el tercer nodo haremos lo mismo

Desde el nodo 3 meteremos el fichero de configuración 60-galera.cnf

#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mariadb
# and read more at https://mariadb.com/kb/en/galera-cluster/

[galera]
# Mandatory settings
wsrep_on                 = ON
wsrep_provider           = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name       = "MariaDB Galera Cluster"
wsrep_cluster_address    = gcomm://192.168.1.81,192.168.1.82,192.168.1.83
binlog_format            = row
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2
wsrep_sst_method=rsync
wsrep_slave_threads=2

# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0

# configuración específica de nodo
wsrep_node_name='nodo3'
wsrep_node_address="192.168.1.83"

# Optional settings
#wsrep_slave_threads = 1
#innodb_flush_log_at_trx_commit = 0

Reiniciamos el nodo 3

sudo sudo systemctl restart mariadb

Si todo va bien deberíamos ver desde el nodo principal que se ha metido el nuevo nodo al cluster

journalctl -xeu mariadb.service

Veamos un ejemplo del log

may 04 19:02:14 nodo1 mariadbd[8754]: WSREP_SST: [INFO] rsync SST completed on donor (20250504 19:02:14.878)
may 04 19:02:14 nodo1 mariadbd[8508]: 2025-05-04 19:02:14 0 [Note] WSREP: Cleaning up SST user.
may 04 19:02:14 nodo1 mariadbd[8508]: 2025-05-04 19:02:14 0 [Note] WSREP: Donor monitor thread ended with total time 1 sec
may 04 19:02:17 nodo1 mariadbd[8508]: 2025-05-04 19:02:17 0 [Note] WSREP: async IST sender served
may 04 19:02:17 nodo1 mariadbd[8508]: 2025-05-04 19:02:17 0 [Note] WSREP: 1.0 (nodo3): State transfer from 0.0 (nodo1) complete.
may 04 19:02:17 nodo1 mariadbd[8508]: 2025-05-04 19:02:17 0 [Note] WSREP: Member 1.0 (nodo3) synced with group.

Ahora podremos comprobar que tenemos tres nodos en el cluster

SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';

con la siguiente salida:

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+
1 row in set (0,001 sec)

Para comprobar por ejemplo el estado del nodo3, ejecutaremos desde consola

SHOW STATUS LIKE 'wsrep_local_state_comment';

Y debería de dar la salida

+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+
1 row in set (0,002 sec)

Dentro del nodo principal deberíamos poder cambiar la dirección wsrep_cluster_address para meter las direcciones de los dos nodos del cluster

wsrep_cluster_address    = gcomm://192.168.1.81,192.168.1.82,192.168.1.83

Y probamos a reiniciar el nodo principal

sudo sudo systemctl restart mariadb

Dentro del nodo secundario deberíamos poder cambiar la dirección wsrep_cluster_address para meter las direcciones de los dos nodos del cluster

wsrep_cluster_address    = gcomm://192.168.1.81,192.168.1.82,192.168.1.83

Y probamos a reiniciar el nodo secundario

sudo sudo systemctl restart mariadb

Pruebas a realizar

Ahora lo suyo sería probar si somos capaces de manejar los datos para modificar la base de datos dese cualquier nodo y verificar que se replican los datos en todos los nodos a la vez Empezamos creando una bbdd desde el nodo1

create database test;

Comprueba que desde el resto de nodos tienes acceso a esa bbdd Crea una tabla en la BBDD desde el nodo 2

-- 0. usa la bbd test
use test;
-- 1. Definición de la tabla “clientes”
CREATE TABLE clientes (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE,
  telefono VARCHAR(20),
  fecha_registro DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Comprueba que desde el resto de nodos tienes acceso a esa tabla en la bbdd

use test;
select * from clientes;

Mete una serie de datos en la tabla desde el nodo 3

-- 0. usa la bbd test
use test;
-- 2. Inserción de datos de ejemplo
INSERT INTO clientes (nombre, email, telefono) VALUES
  ('María López',  'maria.lopez@dominio.com', '600123456'),
  ('Juan Pérez',   'juan.perez@dominio.com',  '600654321'),
  ('Laura García', 'laura.garcia@dominio.com', NULL);

Comprueba que desde el resto de nodos tienes acceso a esa tabla en la bbdd con datos

use test;
select * from clientes;

Prueba de fallo en un nodo y recuperación posterior

Para el nodo 3

sudo systemctl stop mariadb

Por ejemplo desde el nodo 2 deberíamos ver que sólo tenemos 2 nodos activos

MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 2     |
+--------------------+-------+
1 row in set (0,001 sec)

Ahora vamos a intentar modificar los datos de la base de datos mientras que el nodo 3 está caido Por ejemplo desde el nodo 2 ejecutaremos

use test;
-- Inserción de tres registros adicionales en la tabla “clientes”
INSERT INTO clientes (nombre, email, telefono) VALUES
  ('Carlos Ruiz',   'carlos.ruiz@dominio.com',   '600111222'),
  ('Ana Martínez',  'ana.martinez@dominio.com',  '600333444'),
  ('Pedro Sánchez', 'pedro.sanchez@dominio.com', NULL);

Ahora desde el nodo 3 lo arrancaremos de nuevo

sudo systemctl start mariadb

Entraremos por consola al nodo 3 para ejecutar

SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';

Veremos si están los tres nodos activos

MariaDB [test]> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+
1 row in set (0,002 sec)

Para comprobar por ejemplo el estado del nodo3, ejecutaremos desde consola

SHOW STATUS LIKE 'wsrep_local_state_comment';

Y debería de dar la salida

+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+
1 row in set (0,002 sec)

Comprueba que desde el nodo3 tienes acceso a esa tabla en la bbdd con todos datos

use test;
select * from clientes;

Reseteo del servidor

sudo systemctl stop mariadb
sudo rm -rf /var/lib/mysql/*
sudo mariadb-install-db --user=mysql --group=mysql

Referencias

https://www.server-world.info/en/note?os=Ubuntu_24.04&p=mariadb&f=1#google_vignette https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/#installing-mariadb-galera-cluster-with-apt-get https://www.server-world.info/en/note?os=Ubuntu_24.04&p=mariadb&f=5