Galera en route

Soumis par jpp le jeu 03/11/2022 - 22:23

Pour Galera le fichier de paramétrage est /etc/mysql/mariadb.conf.d/60-galera.cnf, voir ci-dessous mon paramétrage :

#
# * Galera-related settings
#
[galera]
# Mandatory settings
wsrep_on                 = ON
wsrep_provider           = "/usr/lib/libgalera_smm.so"
wsrep_cluster_name       = "clustertest"
#
wsrep_node_name          = gale-2
wsrep-node-address	 = 192.168.2.153
#
wsrep_cluster_address    = "gcomm://192.168.2.153,192.168.2.154,192.168.2.155"
binlog_format            = row
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 1
innodb_flush_log_at_trx_commit = 0
# pour restart si cluster planté
wsrep_provider_options="gcache.recover=yes"

Pour le premier lancement il faut impérativement utiliser la commande suivante :
mysqld --wsrep-new-cluster
sur chacun des trois membres du cluster. 
Malheureusement cette commande ne "rends pas la main" j'ai donc du passer par la suite de commandes suivantes :
mysqladmin shutdown
systemctl start mariadb
pour "rendre la main" et démarrer normalement, j'ai fait cela sur chacun des nœuds en laissant un petit temps intermédiaire pour laisser les machines se re-synchroniser.

Pour contrôle je crée une base :
CREATE DATABASE montest;
Et je vérifie qu'elle est bien créée sur les trois nœuds, youpi cette base existe bien partout ... c'est le pied.
De même la création d'une table de test est parfaitement répliquée sur les trois nœuds :
Create Table: CREATE TABLE `TT` (
 `ID` bigint(20) NOT NULL AUTO_INCREMENT,
 `ZONE` varchar(32) DEFAULT NULL,
 PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

Vérifions maintenant l'insertion :
Sur le nœud gale-2 (nœud 1) :
insert into TT (ZONE) values ('UN');
Sur les deux autres nœuds :

select * from TT;
+----+------+
| ID | ZONE |
+----+------+
|  3 | UN   |
+----+------+

Tiens, l'autoincrement débute à 3 ?
Voyons voir un insert sur le nœud gale-3 (nœud 2) :
insert into TT (ZONE) values ('DEUX');
L'ID généré est égal à 5.
Un insert sur le nœud gale-4 (nœud 3) :
insert into TT (ZONE) values ('TROIS');
L'ID généré est égal à 7;
Retour sur le nœud 1 qui génère un ID à 9;
En bref cela à l'air de bien fonctionner ...
On essaye un arrêt de toutes les machines machines, puis on les redémarre, et ... c'est la catastrophe, rien ne redémarre.
Il faut chercher quel était le nœud "maître" en examinant les fichiers "grastate.dat" (dans /var/lib/mysql) et chercher celui qui possède la ligne "safe_to_bootstrap: 1".
Ici c'est le nœud "gale-4" qui a été stoppé en dernier ... donc il doit pouvoir repartir car il est réputé le plus à jour. Si aucun fichier ne comporte cette mention (cas de crash simultané) il faudra en éditer un "à la main" et mettre la valeur à 1;

Utilisation du paramètre "wsrep_provider_options="gcache.recover=yes" ne change rien ... par contre en utilisant la commande "galera_new_cluster" sur le nœud 4 celui-ci démarre normalement et le démarrage des deux autres est alors possible ... Ouf! Le cluster se comporte ensuite normalement.

Le redémarrage d'un seul des membres de notre cluster se passe fort bien et chacun des autres nœuds note que ce membre a disparu :
2022-11-01 18:01:03 0 [Note] WSREP:  cleaning up e713c304-9429 (tcp://192.168.2.155:4567)
192.168.2.155 est l'adresse du membre qui s'est absenté, lorsqu'il redémarre il se signale et les deux autres membres constatent ce fait avec un message :
2022-11-01 18:03:24 0 [Note] WSREP: Member 0.0 (gale-4) synced with group.
Une fonction qui peut être utile pour signaler ce type d'événement est disponible dans le paramétrage de Galera :

wsrep_notify_cmd = 'une commande shell'
Cette commande permet de signaler les événements importants.
J'en ai installé une très simple sur le nœud GALE_2 :
#!/bin/bash
FLOG=/var/tmp/MSG.LOG
DTT=$(date +%Y/%m/%d_%H:%M:%S)
echo ${DTT}' | '$* >>${FLOG}
Lors du démarrage des machines (dans l'ordre inverse de celui dans lequel elles ont été stoppées, (le dernier membre actif doit redémarrer le premier) on obtient l'affichage suivant :

23:52:04 | --status connected
23:52:04 | --status joiner
23:52:04 | --status initializing
23:52:05 | --status initialized
23:52:05 | --status joined
23:52:05 | --status joined --uuid 28736ddb-59f8-11ed-abde-fe2234c75fO
23:52:05 | --status synced
23:53:15 | --status synced --uuid 28736ddb-59f8-11ed-abde-fe2234c75fO
23:53:15 | --status donor
23:53:15 | --status joined
23:53:15 | --status synced
23:54:42 | --status synced --uuid 28736ddb-59f8-11ed-abde-fe2234c75fO
23:54:42 | --status donor
23:54:42 | --status joined
23:54:42 | --status synced

C'est très anormal que toutes les machines soient stoppées, mais cela peut arriver, tant qu'il reste une machine en fonction les autres peuvent venir s'abonner au cluster et tout se passe bien.

Le seul problème est que lors de la "panne" d'une machine son adresse IP ne réponds plus et les clients n'ont plus accès aux données et établir un système de haute disponibilité entre trois machines n'est pas une sinécure.
C'est là l'avantage d'utiliser Maxscale qui va, entre autres choses gérer l'accès à notre cluster. Maxscale permet de gérer des clusters disposant de plus de 3 nœuds, nous verrons cela dans un prochain chapitre ... à suivre