Réplication des bases de données MySQL. introduction

Un système de production moderne se passe rarement de réplication de base de données. C'est un outil puissant pour améliorer les performances du système et la tolérance aux pannes, et il est très important pour le développeur moderne d'avoir au moins une compréhension de base de la réplication. Dans cet article, je vais partager quelques connaissances de base sur la réplication et vous montrer un exemple simple de configuration de la réplication dans MySQL à l'aide de Docker.



image



Qu'est-ce que la réplication et pourquoi est-elle nécessaire



En soi, la réplication fait référence au processus de synchronisation de plusieurs copies d'un objet. Dans notre cas, un tel objet est le serveur de base de données et les données elles-mêmes sont de la plus grande valeur. Si nous avons deux serveurs ou plus et que nous maintenons de quelque manière que ce soit un ensemble synchronisé de données sur eux, nous avons implémenté la réplication du système. Même l'option manuelle c mysqldump -> mysql load



est également la réplication.



Il faut comprendre que la réplication de données elle-même n'a aucune valeur et n'est qu'un outil pour résoudre les tâches suivantes:



  • améliorer les performances de lecture des données. Avec l'aide de la réplication, nous pourrons conserver plusieurs copies du serveur et répartir la charge entre elles.
  • . , . , .
  • . , , , .
  • . , ( , ), , .
  • . , , .
  • . .


MySQL



Le processus de réplication implique la propagation des modifications de données du serveur maître (généralement appelé maître ) vers un ou plusieurs serveurs esclaves (esclave, esclave ). Il existe également des configurations plus complexes, notamment avec plusieurs serveurs maîtres, mais pour chaque modification sur un serveur maître spécifique, les maîtres restants deviennent conditionnellement esclaves et consomment ces modifications.



En général, la réplication MySQL comprend trois étapes:



  1. Le serveur maître écrit les modifications de données dans le journal. Ce journal est appelé journal binaire et les modifications sont appelées événements de journal binaire .
  2. L'esclave copie les modifications apportées au journal binaire dans son propre journal, appelé journal de relais .
  3. L'esclave rejoue les modifications du journal du relais, en les appliquant à ses propres données.


Types de réplication



Il existe deux approches fondamentalement différentes de la réplication: commande par commande et ligne par ligne . Dans le cas de la réplication commande par commande, les demandes de modification de données (INSERT, UPDATE, DELETE) sont enregistrées dans le journal principal et les esclaves reproduisent exactement les mêmes commandes. Avec la réplication ligne par ligne, le journal modifiera directement les lignes dans les tables, et les mêmes modifications réelles seront ensuite appliquées à l'esclave.



Comme il n'y a pas de solution miracle, chacune de ces méthodes présente des avantages et des inconvénients. La réplication par commande est plus facile à implémenter et à comprendre, et réduit la charge sur le maître et sur le réseau. Cependant, la réplication par commande peut entraîner des effets imprévisibles lors de l'utilisation de fonctions non déterministes telles que NOW (), RAND (), etc. Il peut également y avoir des problèmes causés par des données désynchronisées entre le maître et l'esclave. La réplication ligne par ligne conduit à des résultats plus prévisibles, car les modifications de données réelles sont capturées et reproduites. Cependant, cette méthode peut augmenter considérablement la charge sur le serveur maître, qui doit consigner chaque modification dans le journal, et sur le réseau via lequel ces modifications se propagent.



MySQL prend en charge les deux méthodes de réplication, et la valeur par défaut (on peut dire que celle recommandée) a changé en fonction de la version. Les versions modernes comme MySQL 8 utilisent par défaut la réplication basée sur les lignes.



Le deuxième principe de division des approches de réplication est le nombre de serveurs maîtres... La présence d'un serveur maître implique que lui seul accepte les modifications de données, et constitue une sorte de référence à partir de laquelle les modifications sont déjà propagées à de nombreux esclaves. Dans le cas de la réplication maître-maître, nous obtenons à la fois des bénéfices et des problèmes. L'un des avantages, par exemple, est que nous pouvons donner aux clients distants des mêmes Sydney et Helsinki une opportunité tout aussi rapide d'écrire leurs modifications dans la base de données. Cela conduit au principal inconvénient si les deux clients ont simultanément modifié les mêmes données, dont les modifications sont considérées comme définitives, dont la transaction est validée et dont la transaction est annulée.



En outre, il convient de noter que la présence d'un maître de réplication maître ne peut généralement pas augmenter les performances d'écriture de données dans le système. Imaginons que notre seul maître puisse traiter jusqu'à 1000 requêtes à la fois. En y ajoutant un second master répliqué, nous ne pourrons pas traiter 1000 requêtes sur chacune d'elles, car en plus de traiter «leurs» requêtes, ils devront appliquer les modifications apportées sur le second master. Cela, dans le cas de la réplication commande par commande, rendra la charge totale possible sur les deux pas plus que sur le plus faible d'entre eux, et avec la réplication ligne par ligne, l'effet n'est pas entièrement prévisible, il peut être positif ou négatif, selon les conditions spécifiques.



Un exemple de création d'une réplication simple dans MySQL



Il est maintenant temps de créer une configuration de réplication simple dans MySQL. Pour cela, nous utiliserons les images Docker et MySQL de dockerhub , ainsi que la base de données mondiale .



Pour commencer, nous allons lancer deux conteneurs, dont l'un que nous configurerons plus tard en tant que maître, et le second en tant qu'esclave. Réseautons-les pour qu'ils puissent se parler.



docker run -d --name samplereplication-master -e MYSQL_ALLOW_EMPTY_PASSWORD=true -v ~/path/to/world/dump:/docker-entrypoint-initdb.d  mysql:8.0

docker run -d --name samplereplication-slave -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:8.0

docker network create samplereplication
docker network connect samplereplication samplereplication-master
docker network connect samplereplication samplereplication-slave

      
      





La connexion de volume avec le dump world.sql est spécifiée pour le conteneur maître afin de simuler la présence d'une base initiale dessus. Lors de la création d'un conteneur, mysql téléchargera et exécutera des scripts sql situés dans le répertoire docker-entrypoint-initdb.d.



Pour travailler avec des fichiers de configuration, nous avons besoin d'un éditeur de texte. N'importe quel modèle pratique peut être utilisé, je préfère vim.



docker exec samplereplication-master apt-get update && docker exec samplereplication-master apt-get install -y vim 
docker exec samplereplication-slave apt-get update && docker exec samplereplication-slave apt-get install -y vim

      
      





Tout d'abord, nous allons créer un compte sur le maître qui sera utilisé pour la réplication:



docker exec -it samplereplication-master mysql

      
      





mysql> CREATE USER 'replication'@'%';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';

      
      





Ensuite, modifions les fichiers de configuration du serveur maître:



docker exec -it samplereplication-master bash
~ vi /etc/mysql/my.cnf

      
      





Les paramètres suivants doivent être ajoutés au fichier my.cnf dans la section [mysqld]:



server_id = 1 #     
log_bin = mysql-bin #       

      
      





Lors de l'activation / de la désactivation du journal binaire, un redémarrage du serveur est nécessaire. Dans le cas de Docker, le conteneur est rechargé.



docker restart samplereplication-master

      
      





Assurez-vous que le journal binaire est activé. Des valeurs spécifiques telles que le nom et la position du fichier peuvent varier.



mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      156 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

      
      





Pour démarrer la réplication des données, il est nécessaire de «remonter» l'esclave dans l'état du maître. Pour ce faire, vous devez bloquer temporairement l'assistant lui-même pour créer un instantané des données réelles.



mysql> FLUSH TABLES WITH READ LOCK;

      
      





Ensuite, en utilisant mysqldump, exportons les données de la base de données. Bien sûr, dans cet exemple, vous pouvez utiliser le même world.sql, mais rapprochons-nous d'un scénario plus réaliste.



docker exec samplereplication-master mysqldump world > /path/to/dump/on/host/world.sql

      
      





Après cela, il est nécessaire d'exécuter à nouveau la commande SHOW MASTER STATUS et de mémoriser ou d'écrire les valeurs de fichier et de position. Ce sont les soi-disant coordonnées du journal binaire. C'est d'eux que nous indiquerons en outre de démarrer l'esclave. Maintenant, nous pouvons à nouveau déverrouiller le maître:



mysql> UNLOCK TABLES;

      
      





Le maître est configuré et prêt à être répliqué sur d'autres serveurs. Passons maintenant à l'esclave. Tout d'abord, chargez-y le vidage obtenu du maître.



docker cp /path/to/dump/on/host/world.sql samplereplication-slave:/tmp/world.sql
docker exec -it samplereplication-slave mysql
mysql> CREATE DATABASE `world`;
docker exec -it samplereplication-slave bash
~ mysql world < /tmp/world.sql

      
      





Et puis nous changerons la configuration de l'esclave en ajoutant des paramètres:



log_bin = mysql-bin  #      
server_id = 2  #   
relay-log = /var/lib/mysql/mysql-relay-bin #    
relay-log-index = /var/lib/mysql/mysql-relay-bin.index  #        
read_only = 1  #     “ ”

      
      





Après cela, rechargez l'esclave:



docker restart samplereplication-slave

      
      





Et maintenant, nous devons dire à l'esclave quel serveur sera le maître et par où commencer la réplication des données. Au lieu de MASTER_LOG_FILE et MASTER_LOG_POS, vous devez remplacer les valeurs obtenues à partir de SHOW MASTER STATUS sur le maître. Ces paramètres sont collectivement appelés coordonnées log binaires.



mysql> CHANGE MASTER TO MASTER_HOST='samplereplication-master', MASTER_USER='replication', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=156;

      
      





Commençons à rejouer le journal du relais et vérifions l'état de la réplication:



mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G

      
      





STATUT D'ESCLAVE
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: samplereplication-master
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 156
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 156
              Relay_Log_Space: 533
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: c341beb7-3a33-11eb-9440-0242ac110002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
       Master_public_key_path:
        Get_master_public_key: 0
            Network_Namespace:
1 row in set, 1 warning (0.00 sec)
      
      







Si tout s'est bien passé, votre statut devrait être similaire. Paramètres clés ici:



  • Slave_IO_State - en fait, l'état de réplication.
  • Read_Master_Log_Pos est la dernière position lue dans le journal principal.
  • Relay_Master_Log_File - Le fichier journal principal actuel.
  • Seconds_Behind_Master - retard de l' esclave derrière le maître, en secondes.
  • Last_IO_Error , Last_SQL_Error - erreurs de réplication, le cas échéant.


Essayons de changer les données sur le maître:



docker exec -it samplereplication-master mysql

      
      





mysql> USE world;
mysql> INSERT INTO city (Name, CountryCode, District, Population) VALUES ('Test-Replication', 'ALB', 'Test', 42);

      
      





Et vérifiez s'ils sont apparus sur l'esclave.



docker exec -it samplereplication-slave mysql

      
      





mysql> USE world;
mysql> SELECT * FROM city ORDER BY ID DESC LIMIT 1;
+------+------------------+-------------+----------+------------+
| ID   | Name             | CountryCode | District | Population |
+------+------------------+-------------+----------+------------+
| 4081 | Test-Replication | ALB         | Test     |         42 |
+------+------------------+-------------+----------+------------+
1 row in set (0.00 sec)

      
      





Excellent! L'enregistrement saisi est également visible sur l'esclave. Félicitations, vous venez de créer votre première réplication MySQL!



Conclusion



J'espère que dans le cadre de cet article, j'ai pu donner une compréhension de base des processus de réplication, me familiariser avec l'utilisation de cet outil et essayer d'implémenter indépendamment un exemple simple de réplication dans MySQL. Le sujet de la réplication, et son application pratique, est extrêmement vaste, et si ce sujet vous intéresse, je peux recommander les sources suivantes à étudier:



  • Rapport "Comment fonctionne la réplication MySQL" par Andrey Aksenov (Sphinx)
  • Le livre «MySQL au maximum. Optimisation, réplication, sauvegarde »- Baron Schwartz, Petr Zaitsev, Vadim Tkachenko
  • "Highload" - vous trouverez ici des recettes spécifiques pour la réplication de données


J'espère que vous avez trouvé cet article utile et que vous serez heureux de recevoir vos commentaires et commentaires!



All Articles