---
categories: databases
title: Réplication MySQL avec Galera
...

* Documentation : <https://mariadb.com/kb/en/galera-cluster/>

Galera est un module de réplication synchrone et multi-master avec une
tolérance de panne transparente. Il se base sur la _Write-Set Replication API_
(_wsrep API_) de MySQL.

La réplication est totalement transparente pour l'application, aucun potentiel
délai de réplication ou gestion des locks entre les serveurs n'est à prévoir.
Cependant les tables non-transactionnelles de type MyISAM ne sont pas
supportées par la réplication et ne seront donc pas répliquées !

Il est conseillé d'avoir au minimum 3 serveurs en cas de conflit de
réplication, mais 2 peuvent suffire.


## Installation

Depuis Debian 9 (Stretch), le MariaDB plugin de réplication Galera est présent dans le paquet MariaDB serveur. De même, le paquet galera-4 (ou galera-3 suivant la version de MariaDB) est une dépendance de mariadb-serveur. Il n'y a donc aucune action supplémentaire à faire.

Pour revoir la partie installation de MariaDB, il y a notre [Howto MySQL](/HowtoMySQL)

## Mise en place

### Configuration réseau / Firewalling

La réplication Galera utilise des ports réseau dédiés. Il est donc nécessaire d'autoriser les ports suivant dans les pare-feu des machines :

  - 4567/tcp, 4567/udp
  - 4568/tcp
  - 4444/tcp

### Configuration de MariaDB


Ajouter la configuration suivante dans le fichier _/etc/mysql/mariadb.conf.d/galera.cnf_, sur toutes les machines du cluster :

~~~
[mysqld]

# The following MySQL options are mandatory for Galera to work

bind-address=0.0.0.0

default-storage-engine=innodb
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=<votre innodb_buffer_pool_size actuel + ~ 5% pour Galera>

binlog_format=ROW

# Galera cluster configuration

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_provider_options="gcache.size=300M; gcache.page_size=300M"

wsrep_cluster_name="<nom arbitraire du cluster>"
wsrep_cluster_address="gcomm://<liste des adresses IP des machines du cluster, séparées par des virgules>"

wsrep_sst_method=rsync

wsrep_node_address="<adresse IP de la machine - Communication inter-noeuds>"
wsrep_node_name="<nom de la machine>"
wsrep_retry_autocommit=4
~~~

*Note Importante :* seul _wsrep_node_address_ et _wsrep_node_name_ sont différents d'une machine à l'autre.

Bien s'assurer que le fichier est lisible par MariaDB :

~~~
# chmod 644 /etc/mysql/mariadb.conf.d/galera.cnf
~~~

### Amorce d'un cluster

Pour initialiser le nouveau cluster, il est nécessaire de démarrer l'une des machines avec l'option `--wsrep-new-cluster`.

Avant tout, s'assurer que MariaDB est éteint sur chaque serveur :

~~~
# systemctl stop mariadb.service
~~~

Depuis MariaDB 10.1 (Debian stretch), il y a le script _galera_new_cluster_ qui s'occupe de l'amorce du cluster. il est préférable de l'utiliser pour la première initialisation. Cette invocation soit être réalisée sur **un seul serveur**

~~~
# galera_new_cluster
~~~

Dès que la commande est terminée, on peut démarrer les autres noeuds MariaDB de manière normale

~~~
# systemctl start mariadb.service
~~~

## Administration

Vérifier l'état du cluster :

~~~
mysql> SHOW STATUS LIKE 'wsrep_%';
+---------------------------+------------+
| Variable_name             | Value      |
+---------------------------+------------+
...
| wsrep_local_state_comment | Synced (6) |
| wsrep_cluster_size        | 3          |
| wsrep_ready               | ON         |
+---------------------------+------------+
~~~

_wsrep_cluster_size_ indique ici le nombre de machine dans le cluster.

## Monitoring

### Nagios

Pour un monitoring simple du cluster, on peut utiliser le check nagios suivant <https://github.com/fridim/nagios-plugin-check_galera_cluster> sur chaque noeuds. 

Celui-ci surveillera : 

* Qu'il y ait assez de noeuds actifs dans le cluster
* Que le noeud surveillé soit master (ie: donc cluster opérationel)
* Que le cluster n'ait pas mis le noeud en pause trop longtemps pour qu'il récupère du retard (en surveillant `wsrep_flow_control_paused`)

### Munin

TODO

## Plomberie

### Récupération d’un cluster complètement arrêté.

Dans certains cas, on peut se retrouver dans une situation ou tous les nœuds du cluster sont arrêtés. Lors du démarrage d'un noeud il devient impossible de rejoindre le cluster, car il n’existe plus.

Cela nécessite de réamorcer manuellement le cluster. Commencer par inspecter le fichier `/var/lib/mysql/grastate.dat` sur chaque machines pour identifier le nœud qui contient la version la plus avancée de la base de donnée.

Si tous les nœuds ont bien été arrêtés, c’est donc le nœud avec le "seqno" le plus grand qui contient la dernière version de la base. C’est lui qui doit servir de point de départ.

Il se peut que `seqno` soit à -1. Dans ce cas-là, le nœud n’a pas été arrêté proprement. On peut alors récupérer le numéro de séquence avec la commande `mysqld --wsrep-recover`. L’information peut être récupéré dans `/var/log/mysql/error.log`

Voici les étapes pour réamorcer manuellement à partir du nœud le plus à jour: 

* Modifier `/etc/mysql/mariadb.conf.d/galera.cnf` pour définir `wsrep_cluster_address="gcomm://"` et ainsi le forcer à démarrer seul
* Démarrer mariadb : `systemctl start mariadb`
* Rétablir la configuration du cluster dans `/etc/mysql/mariadb.conf.d/galera.cnf` (Un redémarrage n’est pas nécessaire)

Après le démarrage correct du premier nœud, on peut démarrer un à un les autres nœuds du cluster

### Récupération d'un noeud avec un datadir corrompu

Dans une situation de corruption de données sur un noeud (causée par exemple par une saturation disque), on peut alors détruire le datadir pour le forcer à se resynchroniser de zéro.
Simplement créer le dossier avec les bon droits suiffit. Galera s'occupera du reste.

**Remarque importante** : Attention, il est préférable d'avoir deux noeuds "sains". En effet, le noeud corrompu va récupérer l'état du cluster via un des noeuds sains avec un rsync des données. Mais pendant l'opération, le noeud sain source du rsync, va passer en état "DONOR", et donc ne pas accepter de faire des écritures.
S'il n'y a qu'un seul noeud sain, l'opération va donc causer une interruption de service.

~~~
# mv /var/lib/mysql /var/lib/mysql.delete_me
# mkdir /var/lib/mysql
# chmod 700 /var/lib/mysql
# chown mysql: /var/lib/mysql
# systemctl start mariadb
~~~

