LINUX:MariaDB/Galera - Solution d'automatisation de démarrage
→ retour au menu de Galera - Cluster de MariaDB
But
Pour contourner cette limitation d'automatisation de démarrage du cluster Galera, j'ai créé deux services Systemd, pour MariaDB et pour Garb. Au lieu d'utiliser Systemd, on peut utiliser le système de Cron.
MariaDB
Le programme est écrit en scripts "bash" et LUA. Il sera actif sur toutes les machines du cluster MariaDB: "sv1.home.dom", "sv2.home.dom", "sv3.home.dom" et "sv4.home.dom".
Principe
Le script passe par une série de vérifications pour aboutir, si c'est nécessaire, au lancement du service MariaDB.
- La procédure commence par vérifier si le service MariaDB est déjà lancé. Si c'est le cas, la situation est opérationnelle.
- Dans le cas contraire, on recherche sur parmi les autres machines du cluster MariaDB grâce à une procédure écrite en LUA, s'il y en a une où MariaDB s'exécute. Si c'est le cas, on lance le service MariaDB.
- Sinon on vérifie que le fichier d'état de Galera possède un "bootstrap" actif, si c'est le cas, on lance le service MariaDB en initialisant Galera.
- Si ce n'est pas le cas, on récupère grâce à Rsyncd, les états de Galera sur toutes les machines du cluster MariaDB car c'est sur celle qui a le n° de séquence le plus haut qui lancera le service MariaDB en initialisant Galera après activation du "bootstrap". Pour effectuer cette étape, il faut que toutes les machines du cluster MariaDB soient démarrées et accessibles. Si elles ne sont pas toutes actives, on attend.
- Dans le cas où la situation est dégradée: le n° de séquence est "-1", il faudra intervenir manuellement pour déterminer la machine où le service MariaDB avec initialisation de Galera sera lancé.
Cette procédure tourne à intervalle régulier sur toutes les machines du cluster MariaDB.
Rsyncd
Une des étapes consiste à récupérer le fichier d'état de Galera sur toutes les machines du cluster MariaDB. Nous utilisons le service Rsyncd. Ce service sera configuré et activé sur toutes ces machines.
Installation
Le logiciel "rsync" est normalement installé d'office. Il nous faut installer la partie service:
dnf install rsync-daemon dnf install rsync
Fichier de configuration
Le fichier de configuration se nomme "/etc/rsyncd.conf". Voici son contenu pour notre utilisation:
# global max connections = 8 # limiter à IPV4 address=0.0.0.0 uid = root gid = root use chroot = true log file = /var/log/rsyncd.log lock file = /run/rsyncd.lock pid file = /run/rsyncd.pid # partage [db] path = /produc/mysql comment = Espace de la DB hosts allow = 192.168.1.71 192.168.1.72 192.168.1.73 192.168.1.74 read only = true write only = false list = true
On donne accès en lecture seule au répertoire contenant la base de données de MariaDB.
Configurer le mur de feu ou FireWall
Si vous activez le Firewall, ce qui est recommandé, il faut y ajouter la règle suivante:
-A INPUT -p tcp -m tcp --sport 873 -m iprange --src-range 192.168.1.71-192.168.1.74 -m conntrack --ctstate NEW -j ACCEPT -A OUTPUT -p tcp -m tcp --dport 873 -m iprange --dst-range 192.168.1.71-192.168.1.74 -j ACCEPT
Activer et lancer le service
Le service à lancer est "rsyncd.service". La première commande active le service pour qu'à chaque démarrage du serveur, le service se lance. La seconde lance directement le service.
systemctl enable rsyncd.service systemctl start rsyncd.service
Localisation des scripts
Comme précédemment, nous avions placé la base de données dans le répertoire "/produc/mysql". Et nous plaçons les scripts dans le répertoire "/manager/galera".
Fichier "hosts.txt"
Nous créons pour commencer le fichier "/manager/galera/hosts.txt". Il contiendra les noms des machines du cluster MariaDB.
sv1.home.dom sv2.home.dom sv3.home.dom sv4.home.dom
Installation de LUA
Une partie de la procédure est écrite dans le langage de script LUA. Il faut l'installer:
dnf install lua dnf install lua-socket
Script LUA
Ce script sert à rechercher les machines du cluster où le service MariaDB s'exécute en essayant de se connecter à son port TCP 3306.
Voici le script. Son contenu est similaire à celui présenté dans l'article sur le Détail sur le script de configuration LUA. Nous avons nommé ce script "/manager/galera/mariadb.lua":
#!/bin/lua socketbase = require("socket") sockettcp = socketbase.tcp() sockettcp:settimeout(1) port = 3306 nomfichierhost="./hosts.txt" fichierhost=io.open(nomfichierhost,"r") machines = {} i=0 for ligne in fichierhost:lines() do i=i+1 machines[i] = ligne end fichierhost:close() nomfichier="./mariadb.txt" fichier=io.open(nomfichier,"w") machinelocal = socketbase.dns.gethostname() for _, machine in ipairs( machines ) do if not (machine == machinelocal) then local SocketMariadb, errMariadb = sockettcp:connect(machine, port) if SocketMariadb then fichier:write("OK "..machine.."\n") sockettcp:close() end end end fichier:close()
On y remarque le chargement du fichier "hosts.txt". Ce script sera appelé par le script écrit en "bash".
Script Bash
Voici le script principal écrit en langage Bash. Nous avons nommé ce script "/manager/galera/checkdb.bat":
#!/bin/bash # définition du chemin éventuel CHEMIN="/manager/galera" cd $CHEMIN CHEMIN=`pwd` CHEMINDB=`/usr/bin/grep datadir /etc/my.cnf.d/mariadb-server.cnf | /usr/bin/grep -v "#" | /usr/bin/awk -F "=" '{printf("%s",$2)}' ` # bouclage infini !!!! for (( ; ; )) do DT=`/usr/bin/date` PS=`/usr/bin/ps ax | /usr/bin/grep mariadb | /usr/bin/grep -v grep` HOST=`/usr/bin/hostname` if [ "$PS" == "" ] then /usr/bin/lua mariadb.lua TAILLE=`/usr/bin/wc -c mariadb.txt | /usr/bin/awk '{printf("%s",$1)}' ` if [ "$TAILLE" != "0" ] then /usr/bin/echo "$DT - Lancement de Mariadb" >> mariadb.log /usr/bin/echo "$DT - Lancement de Mariadb" /usr/bin/systemctl start mariadb.service else LIGNE2=`/usr/bin/grep safe_to_bootstrap $CHEMINDB/grastate.dat | /usr/bin/awk '{printf("%s",$2)}' ` if [ "$LIGNE2" == "1" ] then /usr/bin/echo "$DT - Lancement de Galera" >> mariadb.log /usr/bin/echo "$DT - Lancement de Galera" /usr/bin/galera_new_cluster else NOMAX="-1" BSMAX="-1" MACHINE="" LISTES=`/usr/bin/cat hosts.txt` for LISTE in $LISTES do /usr/bin/echo "-" > $LISTE.etat /usr/bin/rsync $LISTE::db/grastate.dat $LISTE.etat 2> /dev/null NO=`/usr/bin/grep seqno $LISTE.etat | /usr/bin/awk '{printf("%s",$2)}' ` BS=`/usr/bin/grep safe_to_bootstrap $LISTE.etat | /usr/bin/awk '{printf("%s",$2)}' ` if [ "$NO" == "" ] then NO="100000000" fi if [ "$BS" == "1" ] then BSMAX=$BS fi if [ $NOMAX -lt $NO ] then NOMAX=$NO MACHINE=$LISTE fi done if [ "$BSMAX" == "1" ] then /usr/bin/echo "$DT - Attente de lancement de Galera" >> mariadb.log /usr/bin/echo "$DT - Attente de lancement de Galera" else if [ "$NOMAX" == "100000000" ] then /usr/bin/echo "$DT - Une machine n'est pas accessible" >> mariadb.log /usr/bin/echo "$DT - Une machine n'est pas accessible" else if [ $MACHINE == $HOST ] then /usr/bin/sed -i 's/safe_to_bootstrap: 0/safe_to_bootstrap: 1/g' $CHEMINDB/grastate.dat /usr/bin/echo "$DT - Lancement de Galera" >> mariadb.log /usr/bin/echo "$DT - Lancement de Galera" /usr/bin/galera_new_cluster else /usr/bin/echo "$DT - Attente de démarrage distant de Galera" >> mariadb.log /usr/bin/echo "$DT - Attente de démarrage distant de Galera" fi fi fi fi fi fi # pause de 20 secondes avant le passage suivant sleep 20 done
On y voit l'utilisation du fichier "hosts.txt" et celle des services Rsyncd. Le fichier journal "mariadb.log" affiche l'état de la procédure.
Dans ce script, on remarque deux lignes en vert. On y définit l'endroit où se trouve les fichiers utiles au script. Ces lignes sont utiles si ce script est éxécuté via le Cron. Par contre, dans le cas des services, il sera précisé dans sa définition. Elles sont à adapter selon vos désirs.
De même les lignes en rouge permettent l'exécution en boucle infinie.
Ces deux types de blocs seront activés ou non selon les divers cas présentés ci-dessous.
Il faut faire attention au chemin (variable "CHEMINDB") où se trouve la base de données MariaDB; nous le cherchons dans la configuration du serveur Mariadb. Dans notre cas, elle se trouve dans le répertoire "/produc/mysql".
Utilisation du Cron
Une première utilisation de se script peut être faire via le Cron.
Il faut utiliser dans ce cas la version du script Bash dont les lignes en rouge sont éliminées et les lignes en vert sont maintenues.
On ajoute alors dans le fichier "/etc/crontab" la ligne suivante:
# Check de Galera */10 * * * * root /manager/galera/checkdb.bat > /manager/galera/db.log
Il va s'exécuter toutes les dix minutes.
Services n°1 avec target Timer
Les procédures ci-dessus seront lancées à intervalles réguliers par Systemd.
Il faut utiliser dans ce cas la version du script Bash dont les lignes en rouge et celles en vert sont éliminées.
En premier, on crée le service "checkdb.service" dans le répertoire de Systemd "/etc/systemd/system" dont voici le contenu:
[Unit] Description=Check MariaDB avec Galera After=network.target rsyncd.service Wants=rsyncd.service [Service] Type=simple WorkingDirectory=/manager/galera ExecStart=/manager/galera/checkdb.bat [Install] WantedBy=multi-user.target
Adaptez le répertoire où se trouve les procédures selon votre situation.
Comme cette procédure s'exécute et s'arrête rapidement, il faut la relancer à intervalle régulier. On crée un autre service de type "Timer".
On nomme ce fichier sur la même base "checkdb.timer" dans le même répertoire de Systemd "/etc/systemd/system" dont voici le contenu:
[Unit] Description=Timer for the checkdb service [Timer] OnBootSec=3min OnUnitActiveSec=10min [Install] WantedBy=timers.target
Le service ne s'activera que 3 minutes après le démarrage de la machine et s'exécutera toutes les 10 minutes. Ces temps sont indicatifs.
Comme le paramétrage de Systemd a été modifié, il faut le recharger:
systemctl daemon-reload
On active et lance le service:
systemctl enable checkdb.timer systemctl start checkdb.timer
Service n°2 à traitement périodique
Une troisième utilisation va utiliser toutes les possibilités du script. La partie en rouge du script reste mais la partie en vert est éliminée car la variable CHEMIN est définie implicitement par l'option "WorkingDirectory".
Voici le contenu de ce service que l'on nommera "checkgalera.service" et qu'on place dans le répertoire "/etc/systemd/system":
[Unit] Description=Check Mariadb avec Galera After=network.target rsyncd.service Wants=rsyncd.service [Service] Type=simple WorkingDirectory=/manager/galera ExecStart=/manager/galera/checkdb.bat ExecStopPost=systemctl stop mariadb.service [Install] WantedBy=multi-user.target
Il boucle sur lui-même à interval de 20 secondes comme défini dans le script Bash. Dans le script Bash, les commandes "echo", notées en rouge, se retrouvent dans l'affichage du statut du service:
systemctl status checkgalera.service
On l'active et on le lance:
systemctl enable checkgalera.service systemctl start checkgalera.service
Dès que ce service est arrêté:
systemctl stop checkgalera.service
Le service "mariadb.service" est également arrêté.
Garb
Il reste à régler le cas du service Garb qui tourne sur la machine "sv0.home.dom". Le programme est écrit en scripts "bash" et LUA.
Principe
La seule contrainte est que ce service doive démarrer après qu'au moins une instance de MariaDB s'exécute sur une des machines du cluster si ce n'est pas le cas, il ne doit pas s'exécuter. Il va donc repérer s'il y a au moins une machine du cluster où s'exécute le service MariaDB grâce au scrip LUA "mariadb.lua".
Localisation des scripts
Comme précédemment, nous avions placé la base de données dans le répertoire "/produc/mysql". Et nous plaçons les scripts dans le répertoire "/produc/mysql.bat".
Fichier "hosts.txt"
Nous utiliserons le même fichier comme décrit ci-dessus.
Script LUA
Nous utiliserons également le même script LUA "mariadb.lua" que ci-dessus. Ce logiciel nécessite les mêmes paquets que ci-dessus.
Script Bash
Voici le script principal écrit en langage Bash. Nous avons nommé ce script "/produc/mysql.bat/checkgarb.bat":
#!/bin/bash # définition du chemin éventuel CHEMIN="/manager/galera" cd $CHEMIN CHEMIN=`pwd` # bouclage infini !!!! for (( ; ; )) do DT=`/usr/bin/date` PS=`/usr/bin/ps ax | /usr/bin/grep garbd | /usr/bin/grep -v grep` /usr/bin/lua mariadb.lua TAILLE=`/usr/bin/wc -c mariadb.txt | /usr/bin/awk '{printf("%s",$1)}' ` if [ "$PS" != "" ] then if [ "$TAILLE" == "0" ] then /usr/bin/echo "$DT - Arret de Garbd" >> garb.log /usr/bin/echo "$DT - Arret de Garbd" /usr/bin/systemctl stop garbd.service fi else if [ "$TAILLE" != "0" ] then /usr/bin/echo "$DT - Lancement de Garbd" >> garb.log /usr/bin/echo "$DT - Lancement de Garbd" /usr/bin/systemctl start garbd.service fi fi # pause de 20 secondes avant le passage suivant sleep 20 done
Le fichier journal "garb.log" affiche l'état de la procédure.
Dans ce script, on remarque deux lignes en vert. On y définit l'endroit où se trouve les fichiers utiles au script. Ces lignes sont utiles si ce script est éxécuté via le Cron. Par contre, dans le cas des services, il sera précisé dans sa définition. Elles sont à adapter selon vos désirs.
De même les lignes en rouge permettent l'exécution en boucle infinie.
Ces deux types de blocs seront activés ou non selon les divers cas présentés ci-dessous.
Utilisation du Cron
Une première utilisation de se script peut être faire via le Cron.
Il faut utiliser dans ce cas la version du script Bash dont les lignes en rouge sont éliminées et les lignes en vert sont maintenues.
On ajoute alors dans le fichier "/etc/crontab" la ligne suivante:
# Check Garb */10 * * * * root /manager/galera/checkgarb.bat > /manager/galera/gb.log
Il va s'exécuter toutes les dix minutes.
Services n°1 avec target Timer
Les procédures ci-dessus seront lancées à intervalles réguliers par Systemd.
En premier, on crée le service "checkgarbd.service" dans le répertoire de Systemd "/etc/systemd/system" dont voici le contenu:
[Unit] Description=Check Garbd After=network.target [Service] Type=simple WorkingDirectory=/manager/galera ExecStart=/manager/galera/checkgarb.bat [Install] WantedBy=multi-user.target
Adaptez le répertoire où se trouve les procédures selon votre situation.
Comme cette procédure s'exécute et s'arrête rapidement, il faut la relancer à intervalle régulier. On crée un autre service de type "Timer". On nomme ce fichier sur la même base "checkgarbd.timer" dans le même répertoire de Systemd "/etc/systemd/system" dont voici le contenu:
[Unit] Description=Timer for the checkgarb service [Timer] OnBootSec=4min OnUnitActiveSec=3min [Install] WantedBy=timers.target
Le service ne s'activera que 4 minutes après le démarrage de la machine et s'exécutera toutes les 3 minutes. Ces temps sont indicatifs.
Comme le paramétrage de Systemd a été modifié, il faut le recharger:
systemctl daemon-reload
On active et lance le service:
systemctl enable checkgarbd.timer systemctl start checkgarbd.timer
Service n°2 à traitement périodique
Une troisième utilisation va utiliser toutes les possibilités du script. La partie en rouge du script reste mais la partie en vert est éliminée car la variable CHEMIN est définie implicitement par l'option "WorkingDirectory".
Voici le contenu de ce service que l'on nommera "checkgarb.service" et qu'on place dans le répertoire "/etc/systemd/system":
[Unit] Description=Check Garbd After=network.target [Service] Type=simple WorkingDirectory=/manager/galera ExecStart=/manager/galera/checkgarb.bat ExecStopPost=systemctl stop garbd.service [Install] WantedBy=multi-user.target
Il boucle sur lui-même à interval de 20 secondes comme défini dans le script Bash. Dans le script Bash, les commandes "echo", notées en rouge, se retrouvent dans l'affichage du statut du service:
systemctl status checkgarb.service
On l'active et on le lance:
systemctl enable checkgarb.service systemctl start checkgarb.service
Dès que ce service est arrêté:
systemctl stop checkgarb.service
Le service "garbd.service" est également arrêté.
→ retour au menu de Galera - Cluster de MariaDB