Cet article présente la procédure de switchover et de failover dans le cas d'une réplication maitre / esclave avec un maitre et un esclave.
Le switchover est une opération plannifiée qui consiste à échanger les roles entre maitre et esclave.
Le failover est une opération en cas de perte du maitre
Nous verrons en dernier lieu comment rediriger le client vers le maitre de manière dynamique.
La configuration de cet article est la suivante :
Version mysql :
mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.25 | +-----------+Configuration master :
[mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql log-error = /var/log/mysql/error.log server-id = 1 gtid-mode = ON enforce-gtid-consistency = ON log-slave-updates = OFFConfiguration slave :
[mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql log-error = /var/log/mysql/error.log server-id = 1 gtid-mode = ON enforce-gtid-consistency = ON log-slave-updates = OFF
L'utilisation des GTID est fortement conseillée : elle simplifie le switchover.
Le parametre log-slave-updates doit etre mis à OFF. Ce parametre ne sert que dans le cas d'esclaves en cascade.
Etape 1 : arrêter les mises à jour sur le maitre
Ceci est important car dans le cas contraire :
Sur le master :
USE my_database; FLUSH TABLES WITH READ LOCK; SET GLOBAL read_only = 1;
Sur le slave :
SET GLOBAL read_only = 1;
Etape 2 : promouvoir le master
Sur le slave :
STOP REPLICA IO_THREAD;
STOP REPLICA SQL_THREAD;
RESET REPLICA;
RESET MASTER;
SHOW MASTER STATUS\G
    *************************** 1. row ***************************
                 File: binlog.000001
             Position: 156
         Binlog_Do_DB:
     Binlog_Ignore_DB:
    Executed_Gtid_Set:
Le reset du master a pour effet de remettre réinitialiser les binlog.
Etape 3 : reconfigurer le slave
Sur l'ancien master :
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST = '192.168.56.32',
  SOURCE_PORT = 3306,
  SOURCE_USER = 'repl',
  SOURCE_PASSWORD = 'repl',
  SOURCE_AUTO_POSITION = 1;
    
START REPLICA;
SHOW REPLICA STATUS\G
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.56.32
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: binlog.000001
              Read_Master_Log_Pos: 1034
                   Relay_Log_File: mysql01-relay-bin.000002
                    Relay_Log_Pos: 1243
            Relay_Master_Log_File: binlog.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: 1034
                  Relay_Log_Space: 1454
                  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: 2
                      Master_UUID: 77258615-c9ae-11eb-8ec0-080027a13959
                 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: 77258615-c9ae-11eb-8ec0-080027a13959:1-4
                Executed_Gtid_Set: 36e909d0-c8a4-11eb-a259-080027df3a71:1-19,
    77258615-c9ae-11eb-8ec0-080027a13959:1-4
                    Auto_Position: 1
             Replicate_Rewrite_DB:
                     Channel_Name:
               Master_TLS_Version:
           Master_public_key_path:
            Get_master_public_key: 0
                Network_Namespace:
Etape 4 : rétablir les écritures
Il est important de délocker les tables sur le nouveau slave, car sinon la réplication est bloquée.
Sur l'ancien master :
USE my_database; UNLOCK TABLES; -- On laisse le slave en READ ONLY, celà ne bloque pas la réplication SET GLOBAL read_only = 1;
Sur le nouveau master :
SET GLOBAL read_only = 0;
On considère ici que le maitre n'est plus accessible. La seule opération consiste à passer l'esclave en maitre.
Sur le slave :
STOP REPLICA IO_THREAD;
STOP REPLICA SQL_THREAD;
RESET REPLICA;
RESET MASTER;
SET GLOBAL read_only = 0;
SHOW MASTER STATUS\G
    *************************** 1. row ***************************
                 File: binlog.000001
             Position: 156
         Binlog_Do_DB:
     Binlog_Ignore_DB:
    Executed_Gtid_Set:
Le reset du master a pour effet de remettre réinitialiser les binlog.La réplication classique MySQL présente quelques désavantages coté exploitation :
Une solution pour palier au manque de coordination maitre/esclave est d'utiliser un Cluster InnoDB. Ce cluster utilise les Groupes de Réplication.
D'étude détaillée du cluster InnoDB ne rentre pas dans le cadre de cet article.
Il existe quelques solutions gratuites pour offrir au client un accès au master de manière dynamique :
L'étude détaillée de ces solutions n'entre pas dans le cadre de cet article.