Comment mettre en place MariaDB Galera Cluster sur Debian 11 ?

I. Présentation

Dans ce tutoriel, nous allons apprendre à mettre en place MariaDB Galera Cluster afin de créer un cluster de trois serveurs de bases de données MySQL / MariaDB et assurer la haute disponibilité d'une base de données. Il existe plusieurs solutions techniques pour assurer la disponibilité des bases de données, et la solution Galera Cluster en est une. Ce qui est appréciable avec cette solution, au-delà du fait qu'elle soit open source et gratuite, c'est qu'elle offre plusieurs avantages, notamment :

  • Cluster avec une topologie multi maîtres, donc si un nœud tombe, les autres nœuds continuent d'assurer le service de façon transparente sans avoir besoin d'effectuer des manipulations complexes pour retrouver l'état initial (contrairement à MySQL Replication)
  • Cluster actif-actif avec l'ensemble des nœuds
  • Réplication synchrone des informations, c'est-à-dire en temps réel
  • Lecture et écriture sur l'ensemble des nœuds
  • Souple : fonctionne aussi bien sur le LAN que sur le WAN
  • Support des environnements géo-distribués : plusieurs centres de données, multi-Cloud, etc.
  • Ajout d'un nouveau nœud au cluster en quelques minutes (avec les bons paquets et un seul fichier de configuration)

Enfin, sachez que Galera Cluster est un projet soutenu par MariaDB, Red Hat et la Commission Européenne.

II. Les prérequis

Avant de mettre en place un cluster Galera, il faut prendre en compte certains prérequis, et notamment le nombre de nœuds qui constituent ce cluster : il doit être forcément impair, donc vous pouvez constituer un cluster avec 3 nœuds, 5 nœuds voire même 7 nœuds. La raison est simple : c'est pour éviter le phénomène du split-brain car si vous avez seulement deux nœuds et qu'il y a un nœud qui crash, le nœud restant ne sait pas si l'autre nœud est réellement en panne, ou si c'est lui-même qui a un problème, car il ne voit plus le second. De ce fait, il se peut que la bascule ne fonctionne pas !

Afin de respecter ce prérequis, je vais utiliser trois machines virtuelles sous Debian 11 dans le cadre de ce tutoriel :

  • SRV-DEB-1
    • Adresse IP : 192.168.100.51/24
  • SRV-DEB-2
    • Adresse IP : 192.168.100.52/24
  • SRV-DEB-3
    • Adresse IP : 192.168.100.53/24

Mon objectif étant d'héberger sur ce cluster la base de données d'un site sous WordPress et accessible par l'intermédiaire d'un serveur Web représenté par une quatrième machine virtuelle. Actuellement, la base de données est hébergée uniquement sur le serveur SRV-DEB-1. Les machines virtuelles utilisées dans le cadre de cette démonstration ont peu de ressources : 2 Go de RAM (512 Mo, ça peut suffire pour tester), 2 vCPU et 20 Go d'espace disque. En production, il sera nécessaire de prévoir plus large, notamment pour l'espace disque, en fonction de la taille de la base de données et du nombre de connexions à gérer.

Si vous n'avez pas la possibilité d'avoir trois nœuds, ce qui peut se comprendre, car cela nécessite des ressources supplémentaires, vous devez tout de même envisager un troisième serveur avec le rôle Galera Arbitrator.

Tenez compte également des informations suivantes :

  • Utilisez des nœuds avec les mêmes ressources, car le cluster sera aussi lent que le nœud du cluster le plus lent
  • Galera Cluster fonctionne uniquement sur Linux / Unix
  • Avec un cluster géo-distribués, vous devez contrôler la latence entre vos différents nœuds, car l'idéal c'est qu'elle ne dépasse pas 300 ms
  • Vos bases de données (et vos serveurs) doivent utiliser le moteur de stockage InnoDB ou XtraDB, donc MyISAM n'est pas pris en charge
  • Toutes les tables de votre base de données répliquée doivent avoir une clé primaire
  • Le pare-feu de vos serveurs doit autoriser les ports suivants : 3306, 4444, 4567 et 4568

En complément, vous pouvez lire cet article qui regroupe les limitations connues de MariaDB Galera Cluster.

III. Quel est le moteur de stockage utilisé ?

Commençons par regarder quel est le moteur de stockage utilisé par la base de données que vous souhaitez intégrer au cluster. Je vous rappelle qu'il doit être InnoDB ou XtraDB, et que MyISAM n'est pas pris en charge. En fait, InnoDB est le plus populaire, mais il vaut mieux vérifier cette information dès maintenant.

À partir de mon serveur SRV-DEB-1, où se situe actuellement ma base de données, je vais me connecter à l'instance MariaDB :

mysql -u root -p

Ensuite, la requête ci-dessous va m'afficher quel est le moteur de stockage utilisé par défaut sur cette instance :

show variables like 'default_storage_engine';

La valeur retournée est "InnoDB", ce qui est une bonne nouvelle !

Néanmoins, cela ne signifie pas que votre base de données en elle-même n'utilise pas un autre moteur... Pour être sûr que les tables de votre base de données n'utilisent pas le moteur MyISAM, exécutez la requête ci-dessous en remplaçant "wordpress" par le nom de votre base de données.

SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'wordpress' and ENGINE = 'myISAM';

Dans l'idéal, cette requête ne retourne aucune table. Si ce n'est pas le cas, vous pouvez suivrez le tutoriel ci-dessous pour basculer sur InnoDB.

IV. Installation de MariaDB et Galera 4 sur tous les nœuds

Désormais, nous allons commencer la préparation des différents serveurs ! Pour ma part, je vais utiliser Galera 4, car mes instances MariaDB vont utiliser MariaDB 10.5 qui est actuellement disponible par défaut dans les dépôts de Debian 11. Vous devez utiliser la même version de MariaDB sur l'ensemble de votre cluster !

  • MariaDB 10.4 est compatible avec Galera 4
  • MariaDB 10.3 est compatible avec Galera 3

Au sujet des compatibilités entre les versions, regardez cette documentation : Galera Versions.

Sur mon serveur SRV-DEB-1, MariaDB est actuellement installé en version 10.5.15 et Galera 4 s'installe automatiquement lorsque l'on met en place cette version, et même si l'on n’envisage pas de l'utiliser.

Sur les serveurs SRV-DEB-2 et SRV-DEB-3, nous allons installer le serveur MariaDB (vous devez le faire aussi sur le premier nœud si vous partez de zéro).

sudo apt-get update
sudo apt-get install mariadb-server

En complément, et si vous avez un doute sur le fait que Galera 4 soit bien installé, exécutez cette commande :

sudo apt-get install galera-4

Ce paquet permet de bénéficier du provider "wsrep" indispensable pour la réplication des données.

V. Configuration de MariaDB Galera Cluster

Nous allons déclarer la configuration de notre cluster sur le serveur SRV-DEB-1. Pour cela, nous devons modifier le fichier de configuration "60-galera.cnf" qui se situe dans le dossier "/etc/mysql/mariadb.conf.d/". Vous pouvez le vérifier avec cette commande :

ls /etc/mysql/mariadb.conf.d/

Normalement, ce fichier est livré par défaut avec les versions récentes de MariaDB. Si ce n'est pas le cas, vous pouvez éditer directement un autre fichier de configuration de votre instance (exemple : "my.cnf"). C'est le moment d'éditer le fichier "60-galera.cnf" sur le premier nœud :

sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf

Actuellement, le contenu est le suivant :

Fichier 60-galera.cnf

C'est un template, comme nous pouvons le voir, tout en sachant qu'il y a un autre fichier utile sur lequel s'appuyer pour créer notre configuration :

/usr/share/mysql/wsrep.cnf

Voici la configuration que je vous propose d'utiliser au sein du fichier "60-galera.cnf" :

[galera]
# Mandatory settings
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "Galera_Cluster_IT-Connect"
wsrep_cluster_address = gcomm://192.168.100.51,192.168.100.52,192.168.100.53
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_force_primary_key = 1

# 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
log_error = /var/log/mysql/error-galera.log

Quelques explications sont nécessaires pour que vous puissiez bien comprendre....

  • wsrep_on = ON : activer la réplication en écriture via le provider wsrep
  • wsrep_provider : emplacement de la librairie wsrep
  • wsrep_cluster_name : nom du cluster, doit être identique sur tous les nœuds de votre cluster Galera
  • wsrep_cluster_address : adresses IP (ou le nom, mais préférez l'adresse IP) des différents nœuds du cluster (séparées par une virgule) donc ici les adresses IP de mes trois serveurs
  • binlog_format : format des logs en ROW, par défaut
  • default_storage_engine : moteur de stockage par défaut, ici InnoDB comme définit au niveau de l'instance MariaDB
  • innodb_autoinc_lock_mode : mode pour l'auto-incrémentation, 2 est recommandé, mais les autres valeurs possibles sont "0" ou "1"
  • innodb_force_primary_key : s'assurer que toutes les tables ont bien une clé primaire pour éviter les erreurs
  • bind-address = 0.0.0.0 : accepter les connexions sur toutes les interfaces
  • log_error : emplacement du fichier de log des erreurs (qui contient aussi des logs d'informations, en fait)

Par défaut, dans les journaux, Galera Cluster va utiliser le nom d'hôte du serveur. Si l'on souhaite utiliser une autre valeur, dans ce cas, il faut définir cette option (voir ici) à laquelle on peut aussi ajouter l'adresse IP :

wsrep_node_name = "SRV-DEB-1-Noeud-1"
wsrep_node_address = "192.168.100.51"

Si l'on veut parler un peu d'optimisation des performances, alors l'option "wsrep_applier_threads" est intéressante afin de jouer sur le nombre de threads actifs pour traiter les opérations de réplication. A ce sujet, il n'y a pas de formule magique, mais il faut que ce soit au moins égal au nombre de cœurs de votre processeur, voire même le double ne me choque pas.

wsrep_applier_threads = 2

La configuration est prête : enregistrez le fichier de configuration afin de passer à la suite ! Gardez le contenu de ce fichier de configuration de côté, car il faudra réutiliser les mêmes données sur les autres nœuds du cluster : SRV-DEB-2 et SRV-DEB-3.

VI. Démarrer le cluster Galera

Dans le but d'initialiser notre cluster Galera avec son nœud primaire, nous allons poursuivre sur le serveur SRV-DEB-1 qui contient notre configuration (60-galera.cnf) et la base de données à répliquer. Commençons par stopper MariaDB :

sudo systemctl stop mariadb

Une fois que c'est fait (et c'est important d'arrêter MariaDB), démarrez l'initialisation du cluster Galera avec cette commande :

sudo galera_new_cluster

Maintenant, on va se connecter à notre instance locale MariaDB pour regarder combien de nœuds constituent notre cluster : en toute logique un seul.

mysql -u root -p

Exécutez la requête suivante pour récupérer la valeur de la propriété "wsrep_cluster_size" :

show status like 'wsrep_cluster_size';

Ce qui donne :

On voit bien que c'est égal à "1", ce qui est une bonne nouvelle ! Si vous avez "0", c'est qu'il y a un problème... Dans ce cas, exécutez la requête ci-dessous pour obtenir l'état général du provider wsrep et essayer de comprendre ce qui se passe :

show global status like 'wsrep%';

Nous pouvons passer à la suite : l'ajout des nœuds supplémentaires à notre cluster.

VII. Ajouter des nœuds au cluster Galera

Premièrement, vous devez configurer le fichier "60-galera.cnf" sur les deux autres serveurs, à savoir SRV-DEB-2 et SRV-DEB-3 dans mon cas. Copiez-collez la configuration à l'identique, en reprenant le contenu du fichier du premier nœud (modifiez seulement les options "wsrep_node_name" et "wsrep_node_address" si vous les utilisez).

Remarque : les bases de données existantes des nœuds SRV-DEB-2 et SRV-DEB-3 seront supprimées. Il n'y a que les bases de données du premier nœud qui vont exister suite à l'intégration au cluster.

Actuellement, sur le nœud SRV-DEB-2, je n'ai pas de base de données, à l'exception des bases natives.

Dès que le fichier de configuration "60-galera.cnf" est prêt, il suffit de redémarrer l'instance MariaDB de SRV-DEB-2 pour l'intégrer au cluster :

sudo systemctl restart mariadb

Ensuite, sur le serveur SRV-DEB-1, si je regarde le nombre de nœuds présent dans le cluster, j'ai bien la valeur "2". De plus, si l'on consulte le fichier de log, on peut voir clairement qu'il s'est passé quelque chose et qu'un nouveau nœud a intégré le cluster :

Il ne reste plus qu'à faire la même chose sur le troisième nœud : configuration du fichier "60-galera.cnf" puis redémarrage du service MariaDB. Ensuite, le nombre de nœuds dans notre cluster passe à trois :

Sur les deux nœuds venant d'être intégrés au cluster, si on liste les bases de données (show databases;), nous verrons une nouvelle base de données correspondante à celle répliquée à partir de SRV-DEB-1. Désormais, si une base de données est ajoutée sur l'un des nœuds, elle sera synchronisée avec les autres nœuds !

VIII. L'état des nœuds du cluster Galera

Sur chaque nœud, il est possible d'obtenir des informations sur l'état local, notamment en se connectant à l'instance MariaDB et en regardant certaines propriétés du provider "wsrep". La requête ci-dessous donne l'état du nœud, qui normalement doit être "Synced".

show status like 'wsrep_local_state_comment';

Par ailleurs, la requête ci-dessous permet de voir si le nœud local est capable de traiter suffisamment rapidement les opérations de réplication qu'il reçoit. Lorsque la valeur est égale à "0", c'est tout bon. Par contre, si la valeur est supérieure à 0, cela signifie qu'il n'arrive pas à suivre.

show status like 'wsrep_local_recv_queue_avg';

Enfin, la requête ci-dessous permet de voir si l'hôte est actuelle sur l'état "Primary" ou pas.

show status like 'wsrep_cluster_status';

Dans le cas où il n'est plus dans la grappe primaire, il ne sera plus sollicité même s'il est en ligne, dans ce cas, il faut simplement relancer le service MariaDB sur ce nœud. Ce phénomène peut se produire si le nœud est isolé à cause d'un problème réseau et qu'il ne parvient plus à contacter les deux autres nœuds de notre cluster à trois nœuds.

sudo systemctl restart mariadb

Je vous recommande de regarder la documentation officielle pour la partie monitoring : Monitoring Cluster.

IX. Comment utiliser le cluster Galera ?

Nous venons de voir comment mettre en place le cluster Galera afin d'assurer la haute disponibilité de notre base de données, en l'occurrence ici pour un site WordPress. Par contre, au niveau du serveur Web (même si j'en ai qu'un seul dans cet exemple, en production il en faudrait plusieurs pour aller jusqu'au bout des choses), comment déclarer le cluster ? Si l'on prend l'exemple de WordPress, on déclare uniquement une adresse IP (ou un nom de domaine) pour le serveur de base de données, alors comment faire quand il y en a trois ou plus ?

Pour rappel, c'est dans le fichier wp-config.php, que le serveur de base de données se déclare de cette façon :

/** MySQL hostname */
define( 'DB_HOST', 'db.it-connect.tech:3306' );

Si l'on met l'adresse IP "192.168.100.51" correspondante à notre nœud SRV-DEB-1, cela signifie qu'en cas de panne du nœud, les autres nœuds seront actifs, mais non utilisés par notre serveur Web, donc on peut dire que le cluster ne sera pas réellement utile. L'idéal serait d'utiliser une adresse IP virtuelle (VIP) afin que le cluster soit identifiable par une seule adresse IP grâce à un mécanisme d'IP failover. Pour cela, il existe plusieurs solutions, notamment :

  • Keepalived
  • MariaDB MaxScale
  • HAProxy (en frontal)

Personnellement, il faut que je prenne le temps d'étudier ces différentes solutions (si vous avez des retours sur le sujet, je suis preneur), mais il existe une alternative : l'enregistrement DNS. En créant l'enregistrement DNS "db.it-connect.tech" et en associant à cet enregistrement trois adresses IP (192.168.100.51, 192.168.100.52 et 192.168.100.53) de manière à assurer la continuité de service si une adresse IP ne répond pas. Pour créer cet enregistrement DNS, on peut s'appuyer sur un serveur DNS interne à l'entreprise, ou utiliser le fichier host (/etc/hosts) du serveur Web pour essayer :

192.168.100.51 db.it-connect.tech
192.168.100.52 db.it-connect.tech
192.168.100.53 db.it-connect.tech

Désormais, si un nœud plante, le serveur Web va s'appuyer sur un autre nœud de façon transparente et continuer de travailler. Lorsque le nœud HS sera de nouveau en ligne, il va se resynchroniser avec les autres maîtres du cluster afin de récupérer les dernières informations.

Pour finir, sachez que lorsque le serveur MySQL / MariaDB n'est pas situé sur le même serveur que le serveur Web en lui-même, il faut autoriser les connexions distantes dans MySQL sur chaque nœud. Pour cela, il faut éditer le fichier de configuration suivant :

nano /etc/mysql/mariadb.conf.d/50-server.cnf

Par défaut, la propriété "bind-address" est définie sur "127.0.0.1" donc on autorise uniquement les requêtes provenant de l'hôte local. Cette valeur doit être modifiée pour que le serveur écoute sur une adresse IP spécifique ou toutes ses adresses IP :

#bind-address = 127.0.0.1
bind-address = 0.0.0.0

Ensuite, il faut donner des autorisations à l'utilisateur "utilisateur-bdd-wp" utilisé par WordPress pour administrer la base de données "wordpress" correspondante au site, à partir de l'adresse IP du serveur Web. Ce qui nécessite de se connecter à l'instance MySQL pour créer une autorisation comme ceci :

GRANT ALL privileges ON `wordpress`.* TO 'utilisateur-bdd-wp'@'<adresse-ip-serveur-web>' IDENTIFIED BY 'Mot-de-Passe' WITH GRANT OPTION;
FLUSH PRIVILEGES;

A partir de là, les modifications dans la base de données effectuées par l'intermédiaire de WordPress, sont bien répliquées entre les différents nœuds du cluster. Par exemple, lors de la création d'un nouvel article sur WordPress ou la mise à jour d'un article existant !

Ce premier article sur la mise en place d'un cluster de base de données avec MariaDB Galera Cluster est terminé ! D'autres articles à ce sujet seront certainement mis en ligne par la suite ! 🙂

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian BURNEL

Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

Nombre de posts de cet auteur : 5554.Voir tous les posts

9 thoughts on “Comment mettre en place MariaDB Galera Cluster sur Debian 11 ?

  • Super tutoriel,

    J’av ais déjà mis en place auparavant un cluster avec 3 noeuds avec HaProxy en frontal il y a un peu plus d’un an,
    Ca marche super bien même si pour le coup ca oblige à avoir une frontal supplémentaire pour faire le lien en cas de chute d’un nœud

    Ta solution de t’affranchir d’une frontal en faisant un enregistrement DNS est pour le coup super bien pensé, je ferais surement une bascule vers cette solution pour m’affranchir de Haproxy

    Répondre
  • Hello. Bel article bien documenté. J’avais fait de même avec du haproxy entre l’application et le cluster de bdd. J’avais mis le haproxy sur la même machine que apache/php qui loader balançait sur les 3 nœuds et l’application appelait le port 3306 en local.

    Répondre
    • Hello Guillaume,
      L’idée est intéressante, faut que je teste 🙂
      Tu avais utilisé une VIP en complément ?

      Répondre
  • Salut, excellent article, je voudrais juste apporter my 2 cents:
    – Le simili load-balancing par DNS est-il efficace ? Il se peut que la résolution t’envoie toujours vers un serveur HS. Il est possible d’utiliser une VIP à la place, (avec Corosync si on veut de la bascule auto par exemple). Ou encore un proxy SQL.
    – Dans ton exercice tu as 3 nœuds, donc 3x les data, ce qui peut représenter une volumétrie énorme dans des gros clusters (c’est peut-être voulu). Il est possible de monter un Galera Arbitrator à la place d’un nœud (un witness quoi) afin d’économiser un peu d’espace.
    – Par défaut il n’y a pas vraiment de sécu, le trafic entre les nœuds n’est ni chiffré ni authentifié. Il peut être intéressant de glisser du TLS/SSL avec une CA.

    Répondre
    • Hello Utux 🙂
      Merci pour ton commentaire. Le load-balancing via DNS semble fonctionner d’après les tests que j’ai fait, mais je suis d’accord avec toi qu’il vaut mieux préférer la mise en place d’une VIP. J’ai prévu un article pour améliorer ce point en utilisant Keepalived, tu as déjà testé ?
      Pour Galera Arbitrator et le manque de chiffrement, c’est ce que j’ai vu aussi dans les docs officielles, donc ton commentaire me rassure et me conforte dans l’idée d’explorer ces pistes 😉 – D’ailleurs je trouve que le Galera Arbitrator est particulièrement intéressant sur un cluster géo-distribué pour optimiser les coûts 🙂

      Répondre
      • Yop !
        J’ai monté du cluster Galera il y a plus de 4 ans, je ne me rappelle plus pourquoi j’avais écarté keepalived au profil de Corosync, mais c’était une partie un peu chiante car il fallait s’assurer de ne pas basculer la VIP pour rien, ou pire, l’avoir en double.
        Bon courage pour la suite.

        Répondre
  • Bonjour Florian et merci pour ce tuto récent
    J’ai debian 11 et MariaDB 10.5.15 sur mes machines
    Je connaissais déjà la procédure et elle diffère un peu chez toi notamment sur le paramètre « wsrep_cluster_address » où il n’est renseigné qu’après la commande galera_new_cluster mais dans la doc je vois bien que c’est comme tu fais. (dans une autre doc c’était comme ça)

    Là où je comprends pas c’est que je suis à la lettre ce que tu fais et pourtant je n’arrête pas d’avoir ce message d’erreur au moment de lancer galera_new_cluster :

    Job for mariadb.service failed because a fatal signal was delivered to the control process.
    See « systemctl status mariadb.service » and « journalctl -xe » for details.

    J’ai un snapshot pour revenir bien comme il faut et je n’arrive plus à passer cette étape
    Merci

    Répondre
  • Update :

    sudo galera_new_cluster ne m’a pas retourné d’erreur sans ces paramètres dans le fichier 60-galera.cnf

    wsrep_node_name
    wsrep_node_address
    wsrep_applier_threads

    On va continuer comme ça et ils ne sont peut être pas obligatoires (ce que je croyais du moins pour l’ adresse IP)

    Merci

    Répondre
  • /usr/sbin/mariadbd: unknown variable ‘wsrep_applier_threads=2’

    Répondre

Répondre à Bob Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.