Pour faire suite à mon article sur la réplication Master-Slave, voici comme mettre en place une réplication Master-Master complète de manière à avoir 2 serveurs MySQL identiques en tout point.
Le principe est le même que précédemment, sauf que mes serveurs maîtres seront esclaves de leurs voisins.
Je vais prendre une architecture simple :
Master01 : 192.168.0.101 Master02 : 192.168.0.102
Master01 sera esclave de Master02 et vice versa.
Je pars du principe que le serveur Master01 est en production et qu’il contient déjà des bases avec des données critiques et que les logs binaires ne sont pas activés. Master02 quand à lui est tout neuf.
Attention, je n’ai testé cette procédure qu’avec des schémas assez simples. J’ai même réussi à désynchroniser les 2 serveurs en écrivant cette procédure (sans casse, il suffit de repartir d’un dump et de réaligner les 2 serveurs). Donc à réaliser avec prudence.
Première chose à faire, des sauvegardes :
mysqldump -u root -p --all-databases > all-databases.`date +%Y%m%d`.sql cp /etc/mysql/my.cnf /etc/mysql/my.cnf.`date +%Y%m%d`
Configuration de Master02 :
Afin de réduire l’interruption de service, on commence par préparer le Master02.
On l’arrête :
service mysql stop
Dans la section [mysqld] :
bind-address = 0.0.0.0 server-id = 102 auto_increment_offset = 2 #Le pas des auto incréments, il faut le choisir de manière #à ne pas avoir de collisions entre les différents masters auto_increment_increment = 2 log-bin = /var/log/mysql/master02.bin log-slave-updates master-host = 192.168.0.101 master-port = 3306 master-user = replicationMM master-password = replicationMMpassword master-connect-retry = 10
On relance le serveur.
service mysql start
Dans le cas d’une Debian (je ne sais pas pour les autres distributions), un utilisateur de maintenance (debian-sys-maint) est créé avec un mot de passe aléatoire, c’est avec ce compte que les scripts init.d arrêtent ou démarrent notre serveur. Comme on va faire une réplication totale, ce compte ne va plus fonctionner.
On va donc lui mettre le même mot de passe que sur Master01, on trouve ces informations dans le fichier /etc/mysql/debian.cnf qu’il suffit de recopier à l’identique sur Master02 (attention le mot de passe apparait 2 fois). Dès lors, il ne faut plus arrêter Master02 tant que l’opération n’est pas terminée.
On se connecte à Master02 pour arrêter la réplication (qui ne pourrait pas fonctionner de toute manière à cette étape) :
STOP SLAVE;
Configuration de Master01 :
Dans la section [mysqld] :
#bind-address = 127.0.0.1 bind-address = 0.0.0.0 server-id = 101 auto_increment_offset = 1 #Le pas des auto increments, il faut le choisir de manière #à ne pas avoir de collisions entre les différents masters auto_increment_increment = 2 log-bin = /var/log/mysql/master01.bin log-slave-updates master-host = 192.168.0.102 master-port = 3306 master-user = replicationMM master-password = replicationMMpassword master-connect-retry = 10
On relance le serveur et on vérifie que tout est OK (c’est un serveur de production).
A partir de ce moment, toutes les modifications seront sauvées dans les logs binaires.
Si votre base bouge beaucoup, il vaut mieux en couper l’accès le temps de finir l’opération.
service mysql restart
On se connecte à Master01 en root afin d’arrêter la réplication (qui ne …) et de créer notre utilisateur de réplication :
STOP SLAVE; GRANT REPLICATION SLAVE ON *.* TO 'replicationMM'@'192.168.0.101' IDENTIFIED BY 'replicationMMpassword'; GRANT REPLICATION SLAVE ON *.* TO 'replicationMM'@'192.168.0.102' IDENTIFIED BY 'replicationMMpassword';
Puis on fait un dump afin de donner à Master02 toutes les données d’avant l’activation des logs binaires :
mysqldump -u root -p --add-drop-database --master-data=2 --all-databases --lock-all-tables > all-databases.sql
Dump qu’on importe dans Master02 :
mysql -u root -p < all-databases.sql
Il est temps de lancer la réplication.
Sur Master01 :
SHOW MASTER STATUS /G
->File: master01.000001 ->Position: 516
Sur Master02 :
CHANGE MASTER TO MASTER_HOST='192.168.0.101', MASTER_USER='replicationMM', MASTER_PASSWORD='replicationMMpassword', MASTER_LOG_FILE='master01.000001', MASTER_LOG_POS=516; FLUSH PRIVILEGES; START SLAVE;
Puis dans l’autre sens :
Sur Master02 :
SHOW MASTER STATUS /G
->File: master02.000001 ->Position: 518
Sur Master01 :
CHANGE MASTER TO MASTER_HOST='192.168.0.102', MASTER_USER='replicationMM', MASTER_PASSWORD='replicationMMpassword', MASTER_LOG_FILE='master02.000001', MASTER_LOG_POS=518; FLUSH PRIVILEGES; START SLAVE;
Il faut maintenant vérifier que tout s’est bien déroulé.
Sur les 2 serveurs :
SHOW SLAVE STATUS /G
Slave_IO_Running et Slave_SQL_Running doivent être à Yes sur les 2 serveurs.
Si c’est le cas, nos 2 serveurs sont maintenant en réplication Master-Master
Il faut également vérifier que les bases sont identiques. En ce qui me concerne, je ne connais pas mieux que diff pour ce genre de choses.
Je fais un dump simultané (ce qui n’est pas toujours possible) de toutes les bases des 2 serveurs que je compare avec diff. S’il n’y a pas pas de différence, c’est bon signe.
Il est temps de tester le résultat.
Arrêt de Master02
Je vais commencer par arrêter Master02, ce qui va permettre de vérifier que le compte debian-sys-maint fonctionne toujours (si ce n’est pas le cas, vous aurez un failed).
service mysql stop
Puis je fais quelques modifications dans Master01 (la création d’une base temporaire avec quelques tables et un jeu de données par exemple).
Je relance Master02 :
service mysql start
Et je vérifie que les nouvelles données sont bien présentes sur les 2 serveurs.
Puis le dernier test, je supprime ma base temporaire depuis Master02.
Si elle est également supprimée sur Master01, je peux ré-ouvrir l’accès au serveur de production.
Nous disposons maintenant de 2 serveurs identiques et qui doivent le rester. La prochaine étape est d’utiliser cette architecture derrière un load balancer en Actif/Passif (je n’ai pas encore assez confiance pour faire de l’Actif/Actif).
Source :