MariaDB Galera Cluster en Instancias Virtuales

Introducción

Un Cluster de Galera para MariaDB es una solución mutinodo activo-activo que permite la lectura y escritura en todos los nodos del cluster. De acuerdo a la documentación:

El Cluster de Galera es un cluster multi-master virtualmente síncrono para MariaDB.

… el Servidor replica cada transacción al momento del commit transmitiendo el conjunto de escritura asociado a la transacción hacia todos los nodos del cluster.

Vamos a construir un Cluster de Galera de tres nodos usando Virtual Machine Instances en la Google Cloud Platform.

Crear las Instancias de Cluster de Galera

Usando nuestras Imagen y Plantilla para Instancia de MariaDB personalizadas, crear tres instancias.

Crear la instancia Primaria patomariagm desde la Cloud Console:
En Google Cloud Platform - Compute Engine - VM Instances - Create Instance - New VM Instance from template

  • Select template: patomariadb-template
  • Name: patomariagm
  • Networking
    • Hostname: patomariagm.databases

y para probar la opción de comando, crear las otras instancias patomariag1 and patomariag2 usando el Cloud Shell:

$ gcloud compute instances create patomariag1 --hostname patomariag1.databases --source-instance-template patomariadb-template
Created [https://www.googleapis.com/compute/v1/projects/databases-20202/zones/us-central1-f/instances/patomariag1].

$ gcloud compute instances create patomariag2 --hostname patomariag2.databases --source-instance-template patomariadb-template
Created [https://www.googleapis.com/compute/v1/projects/databases-20202/zones/us-central1-f/instances/patomariag2].

Validar que ambas instancias están arriba y corriendo.

$ gcloud compute instances list
NAME          ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
patomariag1   us-central1-f  f1-micro                   10.128.0.48  35.223.249.103  RUNNING
patomariag2   us-central1-f  f1-micro                   10.128.0.49  34.66.218.222   RUNNING
patomariagm   us-central1-f  f1-micro                   10.128.0.47  35.226.17.216   RUNNING

Crear Objetos y Datos

Se espera que el nodo Primario sea el origen de los datos que queremos replicar en el cluster así que creemos algunos objetos y datos para nuestra prueba.

Accede via ssh a tu nodo Primario patomariagm y conéctate a MariaDB para crear una base de datos, una tabla e insertar un registro con la identificación del hostname y la hora:

pato@patomariagm:~$ mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 10.3.22-MariaDB-0ubuntu0.19.10.1 Ubuntu 19.10

MariaDB [(none)]> create database taller;
Query OK, 1 row affected (0.040 sec)

MariaDB [(none)]> use taller
Database changed
MariaDB [taller]> create table tg1 (i1 int auto_increment primary key, c2 varchar(20), d3 datetime) ;
Query OK, 0 rows affected (0.018 sec)

MariaDB [taller]> insert into tg1 (c2,d3) values (@@hostname,now());
Query OK, 1 row affected (0.004 sec)

MariaDB [taller]> commit ;
Query OK, 0 rows affected (0.000 sec)

Configuración del Cluster de Galera

Una vez que tengamos nuestras 3 instancias necesitamos configurarlas para la replicación de Galera.

Contéctate a tu servidor Primario patomariagm, detén los servicios de MariaDB y crea un nuevo archivo de configración para Galera.

pato@patomariagm:~$ sudo systemctl stop mariadb
pato@patomariagm:~$ sudo nano /etc/mysql/conf.d/galera.cnf

y agrega las siguiente opciones:

  • Activar la replicación y definir la librería
[mariadb]
# Galera Replication Configuration
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
  • Definir el nombre del Cluster y listar las direcciones de los miembros
# Galera Cluster Name and Members
wsrep_cluster_name="patocluster"
wsrep_cluster_address="gcomm://patomariagm,patomariag1,patomariag2"
  • Identificar a este miembro del Cluster
# Galera Cluster Member
wsrep_node_name="patomain"
wsrep_node_address="patomariagm"
  • Definir al nodo primario como el origen de la copia inicial de datos
# Galera State Snapshot Transfer Full Data Copy
wsrep_sst_method=rsync
wsrep_sst_donor="patomain"
  • Habilitar el Identificador Global de Transacciones
# Galera GTID Configuration
wsrep_gtid_mode=ON
wsrep_gtid_domain_id=1
  • Agregar la configuración para el Binary log y el Motor de Almacenamiento
# MariaDB Configuration
binlog_format=ROW
default-storage-engine=InnoDB
innodb_autoinc_lock_mode=2
log_slave_updates=ON
log_bin=galera-bin

Conéctate a los otros dos nodos, detén los servicios de MariaDB y crea el mismo archivo de configuración pero cambiando los parámetros de identificación de este miembro:

pato@patomariag1:~$ sudo systemctl stop mariadb
pato@patomariag1:~$ sudo nano /etc/mysql/conf.d/galera.cnf
# Galera Cluster Member
wsrep_node_name="patonode1"
wsrep_node_address="patomariag1"
pato@patomariag2:~$ sudo systemctl stop mariadb
pato@patomariag2:~$ sudo nano /etc/mysql/conf.d/galera.cnf
# Galera Cluster Member
wsrep_node_name="patonode2"
wsrep_node_address="patomariag2"

Levantar los Nodos del Cluster de Galera

En un Cluster de Galera el nodo Primario debe ser el primero en arrancar con el fin de inicializar el cluster, como se describe en la Documentación de Cluster de Galera

… se necesita iniciar el daemon mysqld en un nodo, usando la opción –wsrep-new-cluster. Esto inicializa el nuevo Componente Primario para el cluster. Cada nodo que se levante después se conectará al componenete e iniciará la replicación.

A partir de la versión 10.4 de MariaDB, la cual incluye la versión 4 de Galera, puedes mejor usar el siguiente comando para inciar MariaDB, Galera, y para establecer el Componente Primario:
galera_new_cluster

Entonces vamos a levantar cada nodo en orden y validaremos cuántos miembros están registrados en el cluster.

pato@patomariagm:~$ sudo galera_new_cluster

pato@patomariagm:~$ mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 1     |
+--------------------+-------+
pato@patomariag1:~$ sudo systemctl start mariadb
pato@patomariag1:~$ mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 2     |
+--------------------+-------+
pato@patomariag2:~$ sudo systemctl start mariadb
pato@patomariag2:~$ mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+

¡Perfecto, nuestro cluster de Galera está configurado y en ejecución y todos los miembros se han unido!

Probar la Replicación en el Cluster de Galera

Ahora vamos a validar que la replicación esté funcionando.

Validar la Replicación Inicial

Primero queremos validar que los objetos y datos creados antes de la configuración del cluster se hayan replicado a los nuevos nodos:

pato@patomariag1:~$ mysql

MariaDB [(none)]> use taller
Database changed
MariaDB [taller]> select * from tg1;
+----+-------------+---------------------+
| i1 | c2          | d3                  |
+----+-------------+---------------------+
|  1 | patomariagm | 2020-05-11 17:55:19 |
+----+-------------+---------------------+
1 row in set (0.001 sec)
pato@patomariag2:/var/log/mysql$ mysql

MariaDB [(none)]> use taller
Database changed
MariaDB [taller]> select * from tg1;
+----+-------------+---------------------+
| i1 | c2          | d3                  |
+----+-------------+---------------------+
|  1 | patomariagm | 2020-05-11 17:55:19 |
+----+-------------+---------------------+
1 row in set (0.000 sec)

Nuestros datos originales fueron replicados en cada nodo, entonces validemos la replicación futura de datos.

Validar la Replication Nodo a Nodo

Como un Cluster de Galera te permite actualizar desde todos los nodos, vamos a insertar un registro en cada nodo identificando la instancia que hace la inserción con @@hostname y el momento de la operación con now():

pato@patomariagm:~$ mysql

MariaDB [taller]> insert into tg1 (c2,d3) values (@@hostname,now());
Query OK, 1 row affected (0.120 sec)

MariaDB [taller]> commit;
Query OK, 0 rows affected (0.000 sec)
pato@patomariag1:~$ mysql

MariaDB [taller]> insert into tg1 (c2,d3) values (@@hostname,now());
Query OK, 1 row affected (0.005 sec)

MariaDB [taller]> commit;
Query OK, 0 rows affected (0.000 sec)
pato@patomariag2:~$ mysql

MariaDB [taller]> insert into tg1 (c2,d3) values (@@hostname,now());
Query OK, 1 row affected (0.004 sec)

MariaDB [taller]> commit;
Query OK, 0 rows affected (0.000 sec)

y revisemos el resultado también en cada nodo:

pato@patomariagm:~$ mysql -e "select * from taller.tg1"
+----+-------------+---------------------+
| i1 | c2          | d3                  |
+----+-------------+---------------------+
|  1 | patomariagm | 2020-05-11 17:55:19 |
|  4 | patomariagm | 2020-05-11 18:35:42 |
|  5 | patomariag1 | 2020-05-11 18:36:03 |
|  6 | patomariag2 | 2020-05-11 18:37:01 |
+----+-------------+---------------------+
pato@patomariag1:~$ mysql -e "select * from taller.tg1"
+----+-------------+---------------------+
| i1 | c2          | d3                  |
+----+-------------+---------------------+
|  1 | patomariagm | 2020-05-11 17:55:19 |
|  4 | patomariagm | 2020-05-11 18:35:42 |
|  5 | patomariag1 | 2020-05-11 18:36:03 |
|  6 | patomariag2 | 2020-05-11 18:37:01 |
+----+-------------+---------------------+
pato@patomariag2:~$ mysql -e "select * from taller.tg1"
+----+-------------+---------------------+
| i1 | c2          | d3                  |
+----+-------------+---------------------+
|  1 | patomariagm | 2020-05-11 17:55:19 |
|  4 | patomariagm | 2020-05-11 18:35:42 |
|  5 | patomariag1 | 2020-05-11 18:36:03 |
|  6 | patomariag2 | 2020-05-11 18:37:01 |
+----+-------------+---------------------+

¡Como podemos ver se insertó un registro en cada nodo y los datos fueron replicados en los demás!

Conclusión

Fuimos capaces de configurar un Cluster de Galera para MariaDB de tres nodos usando Virtual Machine Instances en la Google Cloud Platform y validamos que podemos actualizar cualquier tabla en cualquier nodo y esos cambios serán replicados a todos los nodos.