Chapitre 6 Réplication de MySQL

Table des matières

6.1 Introduction à la réplication
6.2 Présentation de l'implémentation de la réplication
6.3 Détails d'implémentation de la réplication
6.3.1 Etat de réplication du maître
6.3.2 Etats du thread esclave d'E/S
6.3.3 Etats des esclaves de réplication
6.3.4 Fichiers de relais et de statut de la réplication
6.4 Comment mettre en place la réplication
6.5 Compatibilité de la réplication entre les versions de MySQL
6.6 Changer de version de réplication
6.6.1 Passer à la réplication version 4.0
6.6.2 Passer à la réplication version 5.0
6.7 Fonctionnalités de la réplication et problèmes connus
6.8 Options de démarrage de la réplication
6.9 FAQ de la réplication
6.10 Correction de problèmes courants
6.11 Rapporter des bugs de réplication

Les possibilités de réplication, permettant à un serveur d'être recopié à l'identique sur un autre serveur, ont été introduites en MySQL 3.23.15. Cette section décrit les différentes fonctionnalités de la réplication MySQL. Elle sert de référence pour les options disponibles avec la réplication. Vous y trouverez une introduction à la réplication.

Vers la fin, vous y trouverez les questions et problèmes les plus fréquents, avec leur solution.

Pour une description de la syntaxe des commandes de réplication, voyez Section 13.6, « Commandes de réplication ».

Nous vous suggérons de visiter notre site web http://www.mysql.com/ souvent pour y lire les mises à jour de cette section. La réplication est constamment améliorée, et nous modifions souvent le manuel.

6.1 Introduction à la réplication

Depuis la version 3.23.15, MySQL supporte la réplication unidirectionnelle interne. Un serveur sert de maître, et les autres serveurs servent d'esclaves. Le serveur entretient des logs binaires de toutes les modifications qui surviennent. Il entretient aussi un fichier d'index des fichiers de logs binaires, pour garder la trace de la rotation des logs. Chaque esclave, après connexion réussie au serveur maître, indique au maître le point qu'il avait atteint depuis la fin de la dernière réplication, puis rattrappe les dernières modifications qui ont eu lieu, puis se met en attente des prochains événements en provenance du maître.

Un esclave peut aussi servir de maître à son tour, pour réaliser une chaîne de réplication.

Notez que lorsque vous utilisez la réplication, toutes les modifications de tables sont répliquées, et doivent intervenir sur le serveur maître. Sinon, vous devez être prudents dans vos interventions, pour ne pas créer de conflits entre les modifications de tables sur le maître et celles qui interviennent sur l'esclave.

La réplication unidirectionnelle permet de renforcer la robustesse, la vitesse et l'administration du serveur :

  • La robustesse est augmentée par la configuration maître/esclave. Dans le cas où un problème survient sur le maître, vous pouvez utiliser un esclave comme serveur de secours.

  • L'accélération provient de la répartition de la charge de traitement des requêtes clients entre le maître et les esclaves, permettant un meilleur temps de réponse. Les requêtes SELECT peuvent être envoyées aux esclaves pour réduire la charge du maître. Les requêtes de modifications des données sont envoyées au maître, qui les transmettra aux esclaves. Cette stratégie de répartition de charge est efficace si les lectures sont plus nombreuses que les écritures, ce qui est la situation la plus courante.

  • Un autre avantage de la réplication est que vous pouvez faire des sauvegardes non-bloquantes de vos données sur l'esclave et non plus sur le serveur principal : ce dernier n'est pas perturbé. See Section 5.7.1, « Sauvegardes de base de données ».

6.2 Présentation de l'implémentation de la réplication

La réplication MySQL est basée sur le fait que le serveur va garder la trace de toutes les évolutions de vos bases (modifications, effacements, etc.) dans un fichier de log binaire et les esclaves vont lire les requêtes du maître dans ce fichier de log, pour pouvoir exécuter les mêmes requêtes sur leurs copies. See Section 5.9.4, « Le log binaire ».

Il est très important de comprendre que le fichier de log binaire est simplement un enregistrement des modifications depuis un point fixe dans le temps (le moment où vous activez le log binaire). Tous les esclaves que vous activez auront besoin de la copie des données qui existaient au moment du démarrage du log. Si vous démarrez vos esclaves sur sans qu'ils ne disposent des données identiques à celles du maître au moment du démarrage du log binaire, votre réplication va échouer.

Depuis la version 4.0.0, vous pouvez utiliser la commande LOAD DATA FROM MASTER pour configurer un esclave. Soyez bien conscient qu'actuellement, LOAD DATA FROM MASTER ne fonctionne que si toutes les tables du maître sont du type MyISAM, et qu'il est possible d'obtenir un verrou de lecture global, pour qu'aucune lecture ne se fasse durant le transfert des tables depuis le maître. Cette limitation est de nature temporaire, et elle est dûe au fait que nous n'avons pas encore programmé un système de sauvegarde des tables sans verrou. La limitation sera supprimée dans la future version 4.0 une fois que nous aurons programmé le système de sauvegarde, qui permettra à LOAD DATA FROM MASTER de fonctionner sans bloquer le maître.

Etant donné la limitation ci-dessus, nous vous recommandons actuellement d'utiliser la commande LOAD DATA FROM MASTER uniquement si le jeu de données du maître est petit, ou si un verrou prolongé sur le maître est acceptable. Suivant la vitesse de lecture de LOAD DATA FROM MASTER en fonction des systèmes, une règle de base indique que le transfert se fera au rythme de 1 Mo par seconde. Vous pourrez ainsi obtenir une estimation du temps qu'il vous faudra pour transférer les données, si le maître et l'esclave sont connectés sur un réseau de 100 MBit/s, avec des configurations à base de Pentium 700 MHz. Bien sur, votre cas particulier pourra varier en fonction de votre système : la règle ci-dessus vous donnera une première évaluation du temps à attendre.

Une fois que l'esclave est correctement configuré, et qu'il fonctionne, il va simplement se connecter au maître et attendre des requêtes de modifications. Si le maître est indisponible ou que l'esclave perd la connexion avec le maître, il va essayer de se reconnecter toutes les master-connect-retry secondes jusqu'à ce qu'il soit capable d'établir la communication, et de recommencer à appliquer les modifications.

Chaque esclave garde la trace du point où il en était rendu. Le serveur maître n'a pas de notions du nombre d'esclave qui se connectent, ou qui sont à jour à un moment donné.

6.3 Détails d'implémentation de la réplication

Les capacités de réplication de MySQL sont implémentées à l'aide de trois threads : un thread sur le maître et deux sur l'esclave. Lorsque la commande START SLAVE est envoyée, l'esclave crée un thread d'I/O (Entrée/Sortie). Le thread d'I/O se connecte au maître et lit les commandes qui ont été stockées dans le log binaire. Le maître crée un thread pour envoyer le contenu des logs binaire à l'esclave. Ce thread peut être identifié comme le thread Binlog Dump dans le résultat de la commande SHOW PROCESSLIST. Le thread esclave I/O lit ce que le thread maître Binlog Dump lui envoie, et le stocke dans un fichier local à l'esclave. Le troisième thread SQL lit ces commandes et les exécute.

Dans la description précédente, il y a trois threads par esclave. Pour un maître avec de nombreux esclaves, il crée un thread par esclave simultanément connecté, et chaque esclave a son propre thread I/O et SQL.

Pour les versions de MySQL avant 4.0.2, la réplication implique uniquement deux threads : un sur le maître et un sur l'esclave. Les threads I/O et SQL sont combinés en un seul thread, et il n'y a pas de log de relais.

L'avantage d'utiliser deux threads est que la lecture et l'exécution des requêtes sont découplées. La tâche de lecture n'est pas ralentie par l'exécution. Par exemple, si l'esclave n'a pas fonctionné depuis un bon moment, le thread d'I/O peut lire rapidement le contenu de toutes les commandes à appliquer, même si le thread SQL met du temps à les concrétiser. Si l'esclave s'arrête avant que toutes les commandes n'ait été exécutées, le thread d'I/O aura au moins lu les commandes, et elles sont désormais locales. Cela permettra au maître de purger ces lignes, si les autres esclaves n'en ont pas besoin non plus.

La commande SHOW PROCESSLIST affiche des informations qui vous indiquent ce qui se passe sur le maître et sur l'esclave, concernant la réplication.

L'exemple ci-dessous montre les trois threads dans le résultat de SHOW PROCESSLIST. Le format qui est présenté est celui de SHOW PROCESSLIST pour MySQL version 4.0.15, où le contenu de la colonne State a été changé pour être plus significatif.

Sur le serveur maître, le résultat de SHOW PROCESSLIST ressemble à ceci :

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to
         be updated
   Info: NULL

Ici, le thread 2 est le thread de réplication pour un esclave connecté. L'information indique que toutes les requêtes ont été envoyées à l'esclave, et que le maître attend de nouvelles instructions.

Sur le serveur esclave, le résultat de SHOW PROCESSLIST ressemble à ceci :

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O
         thread to update it
   Info: NULL

Cette information indique que le thread 10 est le thread d'I/O, en communication avec le serveur, et le thread 11 est le thread SQL, qui traite les commandes stockées dans le log de relais. Actuellement, les deux threads sont oisifs, et attendent des instructions.

Notez que la valeur de la colonne Time vous indique le retard de l'esclave par rapport au maître. See Section 6.9, « FAQ de la réplication ».

6.3.1 Etat de réplication du maître

La liste suivante montre les états les plus courants que vous verrez dans la colonne State pour le thread maître Binlog Dump. Si vous ne voyez pas le thread Binlog Dump sur le maître, la réplication ne fonctionne pas. C'est à dire qu'aucun esclave n'est connecté.

  • Envoi de log binaire à l'esclave (Sending binlog event to slave)

    Le log binaire contient les événements, qui sont les commandes de modifications des tables, ainsi que d'autres informations supplémentaire.s Le thread a lu un événement dans le log binaire, et il l'envoie à l'esclave.

  • Fini de lire le log binaire. Passe au fichier de log suivant (Finished reading one binlog; switching to next binlog)

    Le thread a fini de lire le fichier de log binaire, et il en ouvre un nouveau, pour l'envoyer à l'esclave.

  • A envoyé tous les logs binaire à l'esclave; attente de nouveau événements dans le log binaire (Has sent all binlog to slave; waiting for binlog to be updated)

    Le thread a lu toutes les commandes de modification dans le log binaire, et les a envoyé à l'esclave. Il est inactif, attend de nouveaux événements dans le log binaire pour reprendre ses activités.

  • Attente de la finalisation (Waiting to finalize termination)

    Un état très bref qui survient lorsque le thread s'arrête.

6.3.2 Etats du thread esclave d'E/S

La liste suivante montre les états les plus courants que vous verrez dans la colonne State pour le thread esclave d'entrée/sortie. Depuis 4.1.1, cette information apparaît aussi dans la colonne Slave_IO_State affichée par la commande SHOW SLAVE STATUS. Cela signifie que vous pouvez avoir une bonne idée de ce qui se passe juste avec SHOW SLAVE STATUS.

  • Connexion au maître (Connecting to master)

    Le thread tente de se connecter au maître

  • Vérification de la version du maître (Checking master version)

    Un état très bref qui survient juste après la connexion au maître.

  • Enregistrement de l'esclave auprès du maître (Registering slave on master)

    Un état très bref qui survient juste après la connexion au maître.

  • Demande de l'export du log binaire (Requesting binlog dump)

    Un état très bref qui survient juste après la connexion au maître. Le thread envoie une requête au maître pour obtenir le contenu des logs binaires, en indiquant le fichier de log et la position de démarrage.

  • Attente de reconnexion avec un échec de demande de log binaire (Waiting to reconnect after a failed binlog dump request)

    Si la demande de log binaire a échoué (à cause d'une déconnexion), le thread passe dans cet état durant sa mise en sommeil, et essaie de se reconnecter périodiquement. L'intervalle entre deux tentative est spécifié avec l'option --master-connect-retry.

  • Reconnexion avec un échec de demande de log binaire (Reconnecting after a failed binlog dump request)

    Le thread tente de se reconnecter au maître.

  • Attente d'informations de la part du maître (Waiting for master to send event)

    Le thread est connecté au maître, et il attend les événement du log binaire. Cela peut durer longtemps sur le maître est inactif. Si l'attente de prolonge au-delà de slave_read_timeout secondes, un dépassement de délai survient. A ce moment, le thread considère que la connexion est perdue, et il va se reconnecter.

  • Ajoute un événement au log de relais (Queueing master event to the relay log)

    Le thread a lu un événement, et il le copie dans le log de relais, pour que le thread SQL puisse le lire.

  • Attente de reconnexion après un échec de lecture d'événement (Waiting to reconnect after a failed master event read)

    Une erreur est survenue durant la lecture, à cause d'une déconnexion. Le thread est en sommeil pour master-connect-retry secondes avant de tenter de se reconnecter.

  • Reconnexion après un échec de lecture d'événement (Reconnecting after a failed master event read)

    Le thread tente de se reconnecter au maître. Lorsque la reconnexion est faite, l'état deviendra Waiting for master to send event.

  • Attente d'espace pour le log de relais auprès du thread SQL (Waiting for the slave SQL thread to free enough relay log space)

    Si vous utilisez une valeur relay_log_space_limit non nulle, et que le log de relais a atteint sa taille maximale, le thread d'E/S va attendre que le thread SQL ait libéré suffisamment d'espace en traitant les requêtes pour qu'il puisse effacer un des fichiers de logs.

  • Attente du mutex de l'esclave (Waiting for slave mutex on exit)

    Un état très bref qui survient juste à l'extinction.

6.3.3 Etats des esclaves de réplication

La liste suivante présente les différents types les plus courants de valeurs de la colonne State pour un esclave SQL :

  • Lecture d'un événement dans le log de relais (Reading event from the relay log)

    Le thread a lu un événement dans le log de relais, et il le traite.

  • A lu tous les logs de relais; attente de l'esclave d'E/S (Has read all relay log; waiting for the slave I/O thread to update it)

    Le thread a traité tous les événements dans le log de relais et attend que le thread écrive de nouveaux événements dans le log de relais.

  • Attente du mutex de l'esclave pour terminer (Waiting for slave mutex on exit)

    Un état très bref qui survient lorsque le thread s'arrête.

La colonne State du thread d'E/S peut aussi afficher une commande. Cela indique que le thread a lu un événement dans le log de relais, a extrait la commande et est en train de l'exécuter.

6.3.4 Fichiers de relais et de statut de la réplication

Par défaut, les logs de relais sont nommés en utilisant des noms de la forme host_name-relay-bin.nnn, où host_name est le nom de l'hôte serveur esclave, et nnn est un numéro de séquence. Les fichiers de log de relais successifs sont créés en utilisant une séquence de nombre commen¸ant à 001. L'esclave garder la trace des logs avec un fichier d'index. Le nom du fichier d'index des logs de relais est host_name-relay-bin.index. Par défaut, ces fichiers sont créés dans le dossier de données de l'esclave. Les noms par défaut peuvent être remplacés grâce aux options --relay-log et --relay-log-index du serveur. See Section 6.8, « Options de démarrage de la réplication ».

Les logs de relais ont le même format que les logs binaires, et ils peuvent être lus avec mysqlbinlog. Un log de relais est automatiquement effacé par le thread SQL aussitôt qu'il n'en a plus besoin : c'est à dire aussitôt qu'il en a exécuté les commandes. Il n'y a pas de commande pour effacer les logs de relais, car le thread SQL se charge de le faire. Toutefois, depuis MySQL 4.0.14, la commande FLUSH LOGS effectue la rotation des logs de relais, qui influence leur effacement par le thread SQL.

Un nouveau log de relais est créé dans les conditions suivantes :

  • La première fois qu'un thread d'I/O démarre après le démarrage du serveur. Avec MySQL 5.0, un nouveau log de relais sera créé chaque fois que le thread d'I/O démarre, et pas seulement la première fois.

  • Une commande FLUSH LOGS ou mysqladmin flush-logs est émise (MySQL 4.0.14 et plus récent uniquement).

  • La taille du log de relais courant est trop grosse. ``trop grosse'' signifie :

    • max_relay_log_size, si max_relay_log_size > 0

    • max_binlog_size, si max_relay_log_size = 0 ou si MySQL est plus ancien que la version 4.0.14

Un serveur de réplication esclave crée deux autres petits fichiers dans le dossier de données. Ces fichiers sont appelés master.info et relay-log.info par défaut. Ils contiennent des informations comme celles affichées par la commande SHOW SLAVE STATUS (see Section 13.6.2, « Commandes SQL de contrôle des esclaves de réplication » pour une description de cette commande). En tant que fichier disques, ils survivent à l'extinction de l'esclave. Au prochain démarrage de l'esclave, ce dernier peut lire ces fichiers pour savoir où il en était du traitement des événements du maître et de leur lecture.

Le fichier master.info est modifié par le thread d'I/O. Avant la version 4.1, la correspondance entre les lignes du fichier et les colonnes affichées par SHOW SLAVE STATUS est la suivante :

LigneDescription
1Master_Log_File
2Read_Master_Log_Pos
3Master_Host
4Master_User
5Mot de passe (pas affiché par SHOW SLAVE STATUS)
6Master_Port
7Connect_Retry

Depuis MySQL 4.1, le fichier inclus un compteur de ligne et des informations sur les options SSL :

LineDescription
1Nombre de lignes dans le fichier
2Master_Log_File
3Read_Master_Log_Pos
4Master_Host
5Master_User
5Mot de passe (pas affiché par SHOW SLAVE STATUS)
7Master_Port
8Connect_Retry
9Master_SSL_Allowed
10Master_SSL_CA_File
11Master_SSL_CA_Path
12Master_SSL_Cert
13Master_SSL_Cipher
14Master_SSL_Key

Le fichier relay-log.info est modifié par le thread SQL. La correspondance entre les lignes du fichier et les colonnes affichées par SHOW SLAVE STATUS est la suivante :

LigneDescription
1Relay_Log_File
2Relay_Log_Pos
3Relay_Master_Log_File
4Exec_Master_Log_Pos

Lorsque vous sauvegardez les données de votre esclave, vous devriez aussi sauver ces deux fichiers, ainsi que les logs de relais. Ils ont nécessaires pour reprendre la réplication après une restauration de la base. Si vous perdez les logs de relais mais avez encore le fichier relay-log.info, vous pouvez l'étudier pour déterminer ce que le thread SQL a traité des logs binaires du maître. Puis, vous pouvez utiliser CHANGE MASTER TO avec les options MASTER_RELAY_LOG et MASTER_RELAY_POS pour dire au thread d'I/O de relire les logs depuis ce point. Cela impose que ces logs sont toujours disponibles sur le serveur.

Si votre esclave doit répliquer une commande LOAD DATA INFILE, vous devriez aussi sauver les fichiers SQL_LOAD-* qui existent dans le dossier que l'esclave utilise à cette fin. L'esclave aura besoin de ces fichiers pour reprendre la réplication des commandes LOAD DATA INFILE. Le chemin du dossier est spécifié avec l'option --slave-load-tmpdir. Sa valeur par défaut est tmpdir.

6.4 Comment mettre en place la réplication

Voici les instructions pour mettre en place la réplication sur votre serveur MySQL. Nous supposons que vous voulez répliquer toutes vos bases, et que vous ne l'avez jamais configuré auparavant. Vous aurez besoin d'éteindre brièvement le serveur principal pour suivre toutes les instructions.

La procédure est écrite pour configurer un esclave seul, mais elle peut être répétée pour configurer plusieurs esclaves.

Si cette méthode n'est pas la plus simple pour configurer un esclave, ce n'est pas la seule. Par exemple, si vous avez déjà une sauvegarde des données du maître, et que le maître a déjà un identifiant de serveur, et le log binaire activé, vous pouvez configurer l'esclave sans éteindre le serveur et sans bloquer les mises à jours. Pour plus de détails, voyez Section 6.9, « FAQ de la réplication ».

Si vous voulez administrer une architecture de réplication MySQL, nous vous suggérons de commencer par étudier, tester et expérimenter toutes les commandes mentionnées dans les chapitres Section 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication » et Section 13.6.2, « Commandes SQL de contrôle des esclaves de réplication ». Vous devriez aussi vous familiariser avec les options de démarrage décrites dans la section Section 6.8, « Options de démarrage de la réplication ».

  1. Assurez vous que vous avez une version récente de MySQL installée comme maître et comme esclave. Assurez vous que ces versions sont compatibles entre elles, conformément à la table présentée dans la section Section 6.6, « Changer de version de réplication ».

    Ne nous rapportez pas de bugs tant que vous n'avez pas vérifié que le problème persiste dans la dernière version de MySQL.

  2. Créez un utilisateur MySQL spécial pour la réplication sur le maître, avec les droits de FILE (dans les versions plus anciennes que la versions 4.0.2) ou le droit de REPLICATION SLAVE pour les nouvelles versions. Vous devez aussi lui donner les droits de connexion depuis tous les esclaves. Si l'utilisateur ne fait que de la réplication (ce qui est recommandé), vous n'avez pas à lui donner d'autres droits.

    Le nom d'hôte du compte doit être tel que chaque serveur esclave peut l'utiliser pour se connecter au maître. Par exemple, pour créer un utilisateur appelé repl qui peut accéder au maître, vous pourriez utiliser une commande comme :

    mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    Pour les versions de MySQL antérieure à la 4.0.2, utilisez cette commande :

    mysql> GRANT FILE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    Si vous envisagez d'utiliser LOAD TABLE FROM MASTER ou LOAD DATA FROM MASTER sur l'esclave, vous devez donner les droits supplémentaires suivants :

    • Donnez le droit de SUPER et RELOAD.

    • Donnez le droit de SELECT pour toutes les tables que vous voulez charger. Toutes les tables maîtres dans lesquelles l'esclave ne pourra pas utiliser SELECT seront ignorées par LOAD DATA FROM MASTER.

  3. Si vous utilisez des tables MyISAM, déchargez toutes les tables et blocs en utilisant la commande FLUSH TABLES WITH READ LOCK.

    mysql> FLUSH TABLES WITH READ LOCK;
    

    puis faire une sauvegarde des données de votre maître.

    Le plus simple pour cela (sous Unix) et d'utiliser la commande tar pour produire une archive de votre dossier de données total. Le dossier de données dépend de votre installation.

    shell> tar -cvf /tmp/mysql-snapshot.tar .
    

    Si vous voulez que vos archives incluent seulement une base de données appelée cette_base, utilisez cette commande :

    shell> tar -cvf /tmp/mysql-snapshot.tar ./cette_base
    

    Puis copiez le fichier d'archive dans le dossier /tmp sur le serveur esclave. Sur cette machine, placez vous dans le dossier de données du serveur et décompressez l'archive locale avvec cette commande :

    shell> tar -xvf /tmp/mysql-snapshot.tar
    

    Il n'est pas besoin de répliquer la base mysql. Si c'est le cas, vous pouvez l'exclure de votre archive. Vous n'avez pas besoin d'inclure les fichiers de log dans l'archive, ou les fichiers master.info ou relay-log.info.

    Lorsque le verrou de lecture a été posé par FLUSH TABLES WITH READ LOCK et est en action, lisez les valeurs courantes du fichie de log et de son offset sur le maître :

    mysql > SHOW MASTER STATUS;
    +---------------+----------+--------------+------------------+
    | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +---------------+----------+--------------+------------------+
    | mysql-bin.003 | 73       | test,bar     | foo,manual,mysql |
    +---------------+----------+--------------+------------------+
    1 row in set (0.06 sec)
    

    La colonne File montre le nom du fichier de log, et la colonne Position affiche l'offset. Dans l'exemple ci-dessus, le nom du fichier de log est mysql-bin.003 et son offset est 73. Notez ces valeurs. Vous en aurez besoin pour configurer l'esclave.

    Une fois que vous avez pris une sauvegarde et enregistré le nom de fichier, et son offset, vous pouvez réactiver l'activité sur votre maître :

    mysql> UNLOCK TABLES;
    

    Si vous utilisez des tables InnoDB, l'outil idéal est InnoDB Hot Backup, qui est disponible pour ceux qui achètent des licences commerciales MySQL, du support ou l'outil lui-même. Il fait un sauvegarde cohérente du maître, enregistre le nom du fichier de log binaire et son offset, pour que cette archive soit directement utilisée par l'esclave plus tard. Pour plus d'informations sur cet outil, voyez http://www.innodb.com/order.php.

    Sans Hot Backup, le mieux pour faire une sauvegarde rapide d'une base InnoDB est d'arrêter le serveur, puis de copier les fichiers de données InnoDB, leurs logs, et leur fichier de définition (.frm). Pour enregistrer le fichier de log courant et son offset, vous devez utiliser les commandes suivantes lors de l'extinction du serveur :

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    Et ensuite, enregistrer le nom du fichier et son offset, lu dans le résultat de la commande SHOW MASTER STATUS présentée précédemment. Une fois que vous avez ces informations, éteignez le serveur sans déverrouiller les tables, pour vous assurer qu'il va bien s'arrêter dans l'état que vous avez noté :

    shell> mysqladmin -uroot shutdown
    

    Une alternative, valable pour les deux types de tables MyISAM et InnoDB, est de prendre un export SQL du maître, au lieu d'une copie binaire. Pour cela, vous pouvez utiliser l'utilitaire mysqldump --master-data sur votre maître, puis exécuter les commandes SQL sur votre esclave. Toutefois, c'est plus lent que de faire une copie binaire.

    Si le maître fonctionnait sans l'option --log-bin, le nom du fichier de log et l'offset seront vides, lorsqu'ils sont demandé à SHOW MASTER STATUS et mysqldump sera vide aussi. Dans ce cas, utilisez la chaîne vide ('')comme nom de fichier de log, et la valeur 4 comme offset.

  4. Dans le fichier my.cnf du maître, ajoutez les options log-bin et server-id=unique number, où master_id doit être un entier positif entre 1 et 2^32 − 1, à la section [mysqld] et redémarrez le serveur. Il est très important que l'identifiant des esclaves soient différents de celui du maître. Pensez à server-id comme à une valeur comparable à une adresse IP : elle identifie de manière unique un serveur dans la communauté des réplicateurs.

    [mysqld]
    log-bin
    server-id=1
    

    Si ces options ne sont pas présentes, ajoutez-les, et redémarrez le serveur.

  5. Arrêtez le serveur qui va servir d'esclave, et ajoutez les lignes suivantes dans son fichier my.cnf :

    [mysqld]
    server-id=slave_id
    

    La valeur de slave_id, comme la valeur de master_id, doit être un entier, entre 1 et 2^32 − 1. De plus, il est très important que l'identifiant de l'esclave soit différent de celui du maître. Par exemple :

    [mysqld]
    server-id=2
    

    Si vous configurez plusieurs esclaves, chacun d'entre eux doit avoir une valeur server-id distincte de celle du maître et des autres esclaves. Pensez aux server-id comme étant des adresses IP : ces identifiants repèrent de manière unique un esclave dans la communauté de réplication.

    Si vous ne spécifiez pas de valeur pour server-id, il prendra la valeur de 1 si vous n'avez pas défini de valeur pour master-host, sinon, il prendra la valeur de 2. Notez que dans le cas où vous omettez server-id, un maître refusera laconnexion à tous les esclaves. Par conséquent, omettre server-id est uniquement valable pour des opérations de sauvegarde avec log binaire.

  6. Copiez la sauvegarde des données dans vos esclaves. Assurez vous que les droits sur ces données sont corrects. L'utilisateur qui fait fonctionner MySQL doit avoir les droits d'écriture et de lecture sur ces fichiers, tout comme le maître l'avait.

    Si vous avez fait une sauvegarde avec mysqldump, lancez d'abord les esclaves (voir prochaine étape).

  7. Redémarrez les esclaves. S'il était déjà configuré pour la réplication, lancez l'esclave avec l'option --skip-slave-start. Vous pouvez aussi lancer l'esclave avec l'option --log-warnings. De cette manière, vous aurez plus de détails sur les problèmes que l'esclave rencontrera (problèmes réseau, d'identification, etc.)

  8. Si vous avez fait une sauvegarde du maître avec l'utilitaire mysqldump, chargez l'export avec la commande suivante :

    shell> mysql -u root -p < dump_file.sql
    
  9. Exécutez la commande sur l'esclave, en rempla¸ant les valeurs entre crochets <> par les valeurs que vous aviez lu sur le maître, ou qui sont valables pour votre système :

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='<master host name>',
        ->     MASTER_USER='<replication user name>',
        ->     MASTER_PASSWORD='<replication password>',
        ->     MASTER_LOG_FILE='<recorded log file name>',
        ->     MASTER_LOG_POS=<recorded log offset>;
    

    La table suivante vous donne les tailles maximales de ces variables :

    MASTER_HOST60
    MASTER_USER16
    MASTER_PASSWORD32
    MASTER_LOG_FILE255
  10. Lancez les threads esclaves.

    mysql> START SLAVE; 
    

Après avoir suivi les instructions ci-dessus, les esclaves doivent se connecter au maître, et rattraper les modifications qui ont eu lieu depuis la sauvegarde des données.

Si vous avez oublié de spécifier un server-id pour un esclave, vous allez obtenir l'erreur suivante dans le fichier d'erreur :

Warning: one should set server_id to a non-0 value if master_host is set.
The server will not act as a slave.

Si vous avez oublié de le faire pour le maître, les esclaves ne pourront pas se connecter avec le maître.

Si un esclave n'est pas capable de faire la réplication pour une raison quelconque, vous allez trouvez le message d'erreur dans le fichier de log d'erreurs de l'esclave.

Une fois qu'un esclave a activé la réplication, vous trouverez deux fichiers dans son dossier de données : master.info et relay-log.info. L'esclave utilise ces deux fichiers pour savoir où il en est des logs du maître. Ne supprimer pas et n'éditez pas ces fichiers, à moins que vous ne sachiez bien ce que vous faites. Même dans ce cas, il est préférable d'utiliser la commande CHANGE MASTER TO.

NOTE : le contenu du fichier master.info est priorité par rapport a certaines versions spécifiées en ligne de commande, ou dans le fichier my.cnf. Voyez Section 6.8, « Options de démarrage de la réplication » pour plus de détails.

Une fois que vous avez une sauvegarde, vous pouvez l'utiliser pour configurer d'autres esclaves, en suivant la procédure concernant l'esclave, ci-dessus. Vous n'aurez pas besoin d'une autre sauvegarde du maître.

6.5 Compatibilité de la réplication entre les versions de MySQL

Le format de log binaire original de la réplication a été développé en MySQL 3.23. Il a changé en MySQL 4.0, et encore en MySQL 5.0. Cela a des conséquences lorsque vous mettez à jour votre architecture de réplication, tel que décrit dans la section Section 6.6, « Changer de version de réplication ».

Au niveau de la réplication, toutes les versions MySQL 4.1.x et 4.0.x sont identiques, car elles utilisent le même format de log binaire. Par conséquent, les serveurs dans cet intervalle de versions seront compatibles, et la réplication devrait fonctionner sans problèmes entre eux. Les exceptions à cette compatibilité sont que les versions de MySQL 4.0.0 à 4.0.2 étaient des versions de développement très récentes, et qu'elles ne doivent plus être utilisées. Elles représentent des versions alpha dans la série des 4.0. La compatibilité avec ces versions est toujours documentée dans le manuel, avec ces distributions.

La table suivante indique les compatibilités entre les esclaves et maîtres, pour différentes versions de MySQL.

  MaîtreMaîtreMaître
  3.23.33 et plus récent4.0.3 et plus récent or any 4.1.x5.0.0
Esclave3.23.33 et plus récentouinonnon
Esclave4.0.3 et plus récentouiouinon
Esclave5.0.0ouiouioui

En général, nous recommandons d'utiliser des versions récentes de MySQL, car la réplication s'améliore continuellement. Nous recommendons aussi d'utiliser la même version pour le maître et les esclaves.

6.6 Changer de version de réplication

Lorsque vous mettez à jour vos serveurs dans une architecture de réplication, la procédure pour changer les versions dépend des versions que vous abandonnez et de celle vers laquelle vous allez.

6.6.1 Passer à la réplication version 4.0

Cette section s'applique aux situations de mise à jour depuis une architecture MySQL 3.23 vers 4.0 ou 4.1. Un serveur 4.0 doit être en version 4.0.3 ou plus récent, tel que mentionné dans la section Section 6.5, « Compatibilité de la réplication entre les versions de MySQL ».

Lorsque vous mettez à jour un maître depuis MySQL 3.23 vers MySQL 4.0 ou 4.1, assurez vous d'abord que tous les esclaves et tous les maîtres sont déjà en versions 4.0 ou 4.1 (si ce n'est pas le cas, commencez par mettre à jour les esclaves comme indiqué ci-dessous). Une fois le maître mis à jour, vous ne devez pas relancer la réplication avec les vieux logs binaires 3.23, car cela va perturber les esclaves 4.0 et 4.1. La mise à jour peut être faites comme ceci, en supposant que vous avez un maître 3.23 à modifier, et des esclaves 4.0 ou 4.1 :

  1. Bloquez toutes les modifications sur le maître avec FLUSH TABLES WITH READ LOCK.

  2. Attendez que les esclaves ait rattrappé toutes les modifications du maître (utilisez SHOW MASTER STATUS sur le maître, et SELECT MASTER_POS_WAIT() sur les esclaves. Puis lancez STOP SLAVE sur les esclaves.

  3. Eteindez le serveur maître et passez le en MySQL 4.0 or 4.1.

  4. Relancez le serveur MySQL maître. Enregistrez le nom du nouveau log binaire du maître. Vous pouvez obtenir ce nom avec la commande SHOW MASTER STATUS sur le maître. Puis, lancez cette commande sur les esclaves :

    mysql> CHANGE MASTER TO MASTER_LOG_FILE='<name>', MASTER_LOG_POS=4;
    mysql> START SLAVE;
    

6.6.2 Passer à la réplication version 5.0

Cette section s'applique aux situations de mise à jour depuis une architecture MySQL 3.23, 4.0 ou 4.1 vers une version 5.0.0. Un serveur 4.0 doit être en version 4.0.3 ou plus récent, tel que mentionné dans la section Section 6.5, « Compatibilité de la réplication entre les versions de MySQL ».

D'abord, notez bien que MySQL 5.0.0 est actuellement en phase alpha; même s'il est supposé utilisable et meilleur que les vieilles versions (meilleure mise à jour, réplication de certaines variables de sessions importantes comme SQL_MODE; voyez Section C.1.7, « Changements de la version 5.0.0 (22 décembre 2003 : Alpha) »), il n'est pas encore totalement testé. Nous vous recommandons donc de ne pas l'utiliser pour des environnements de production.

Lorsque vous passez de MySQL 3.23 or 4.0 en 4.1 ou 5.0.0, vous devriez vous assurer que tous les esclaves de ce maître sont déjà en version 5.0.0 (si ce n'est pas le cas, vous devriez commencer par mettre à jour vos esclaves, comme expliqué ci-dessous.

Alors, éteignez le maître, passez le en version 5.0.0 et relancez le. Le maître version 5.0.0 sera capable de relire les anciens logs binaires (d'avant la mise à jour), et de les envoyer aux esclaves 5.0.0 qui reconnaîtront le vieux format, et le comprendront. Les nouveaux logs binaires créés par le maître seront au format 5.0.0, et seront reconnus par les esclaves.

Pour mettre à jour les esclaves, commencez par les éteindre, puis passez les en version 5.0.0, et relancez les, ou relancez la réplication. Les esclaves de version 5.0.0 seront capables de relire les vieux fichiers de logs binaires (ceux d'avant la mise à jour), et exécuter les commandes qu'ils contiennent. Les logs de relais créé après la mise à jour seront au format 5.0.0.

En d'autres termes, il n'y a pas de mesure à prendre lorsque vous passez en version 5.0.0, sauf que les esclaves doivent être mis à jour avant le maître. Notez que si vous descendez de version, cela ne fonctionnera pas automatiquement : vous devez commencer par effacer les logs binaires et de relais au format 5.0.0 avant de procéder.

6.7 Fonctionnalités de la réplication et problèmes connus

La liste suivante explique ce qui est supporté ou pas. Des informations spécifiques InnoDB sur la réplication sont disponibles dans la section Section 15.7.5, « InnoDB et la réplication MySQL ».

  • La réplication s'effectue correctement sur les valeurs AUTO_INCREMENT, LAST_INSERT_ID() et TIMESTAMP.

  • Les fonctions USER() et LOAD_FILE() sont répliquées dans modifications, et ne seront pas fiable une fois rendues sur le serveur esclave. C'est aussi vrai pour CONNECTION_ID() pour les esclaves de versions antérieures à la 4.1.1. La nouvelle fonction PASSWORD() de MySQL 4.1, est bien répliquée depuis les maîtres version 4.1.1; vos esclaves doivent être en version 4.1.0 ou plus récent pour la répliquer. Si vous avez d'anciens esclaves, et que vous devez répliquer la fonction PASSWORD() depuis un maître 4.1, vous devez lancer le maître avec l'option --old-password.

  • Les variables SQL_MODE, UNIQUE_CHECKS, SQL_AUTO_IS_NULL sont répliquées depuis la version 5.0.0. Les variables SQL_SELECT_LIMIT et TABLE_TYPE ne sont pas répliquées pour le moment. FOREIGN_KEY_CHECKS est répliquée depuis la version 4.0.14.

  • Vous devez utiliser le même jeu de caractères (--default-character-set) sur le maître et sur l'esclave. Sinon, vous risquez de rencontrer des erreurs de clés dupliquées, sur l'esclave, ces une valeur pourrait être considérée comme unique sur le serveur et non sur l'esclave. Les jeux de caractères seront répliqués en version 5.0.

  • Si vous utilisez des tables transactionnelles sur le maître et non-transactionnelle sur l'esclave, pour les mêmes tables, vous rencontrerez des problèmes si l'esclave est interrompu au milieu d'un bloc BEGIN/COMMIT, car l'esclave reprendra ultérieurement au début du bloc BEGIN. Ce problème est sur notre liste de tâche, et sera corrigé prochainement.

  • Les requêtes d'UPDATE qui utilisent des variables utilisateurs ne sont pas correctement répliquées sur les serveurs 3.23 et 4.0. C'est corrigé en 4.1. Notez que les noms de variables utilisateurs sont insensibles à la classe depuis la version 5.0, alors il est recommandé de prendre cela en compte lors de la configuration de la réplication entre un serveur version 5.0 et une version précédente.

  • L'esclave peut se connecter au maître avec la sécurisation SSL, si le maître et l'esclave sont tous les deux en versions 4.1.1 ou plus récentes.

  • Si la clause DATA DIRECTORY ou INDEX DIRECTORY est utilisée dans la commande CREATE TABLE sur le maître, la clause est aussi utilisée sur l'esclave. Cela peut causer des problèmes s'il n'existe pas de dossier correspondant sur le système de fichiers de l'esclave. Depuis MySQL 4.0.15, il y a une option de mode SQL sql_mode appelée NO_DIR_IN_CREATE. Si le serveur esclave fonctionne avec ce mode SQL, il va simplement ignorer ces clauses avant de répliquer les commandes CREATE TABLE. Le résultat est que les données MyISAM et les fichiers d'index seront créées dans le dossier de la base.

  • Même si nous n'avons jamais vu d'occurrence de ce problème, il est théoriquement possible pour les données du maître et de l'esclave de différer si une requête non-déterministe est utilisée pour modifier les données, c'est à dire si elle est laissé au bon vouloir de l'optimiseur, ce qui n'est pas une bonne pratique même sans la réplication. Pour plus d'informations, voyez Section 1.5.7.4, « Bugs connus / limitations de MySQL ».

  • Avant MySQL 4.1.1, les commandes FLUSH, ANALYZE, OPTIMIZE, REPAIR n'étaient pas stockées dans le log binaire, et donc, elles n'étaient pas répliquées avec les esclaves. Ce n'est pas normalement un problème, car FLUSH ne modifie pas les tables. Cela peut signifier que vous avez modifié des droits dans les tables MySQL directement sans la commande GRANT et que vous avez répliqué les droits de mysql sans pouvoir faire de commande FLUSH PRIVILEGES sur vos esclaves pour les prendre en compte. Depuis MySQL version 4.1.1, ces commandes sont écrites dans le log binaire, (hormis FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE, FLUSH TABLES WITH READ LOCK) à moins que vous ne spécifiez NO_WRITE_TO_BINLOG ou son alias LOCAL). Pour un exemple d'utilisation de la syntaxe, voyez Section 13.5.4.2, « Syntaxe de FLUSH ».

  • MySQL supporte uniquement un maître et plusieurs esclaves. Ultérieurement, nous allons ajouter un algorithme de choix automatique du maître. Nous allons aussi introduire une notion d'agent, qui aideront à équilibrer la charge en envoyer les commandes SELECT aux différents esclaves.

  • Lorsqu'un serveur s'arrête et repart, les tables MEMORY (HEAP) sont vidées. Depuis MySQL 4.0.18, le maître réplique cet effet comme ceci : la première fois que le maître utilise une table MEMORY après le démarrage, il indique aux esclaves que la table doit être vidée en ajoutant une commande DELETE FROM pour la table en question, dans son log binaire. Voyez Section 14.3, « Le moteur de table MEMORY (HEAP) » pour plus de détails.

  • Les tables temporaires sont répliquées depuis la version 3.23.29, à l'exception des cas où vous éteignez le serveur esclave (et pas juste le thread esclave), que vous avez des tables temporaires ouvertes et qu'elles sont utilisées dans des modifications ultérieures. (Si vous éteignez l'esclave, les tables temporaires utilisées par ces commandes ne sont plus disponibles au redémarrage de l'esclave). Pour éviter ce problème, n'éteignez jamais un esclave qui a des tables temporaires actives. Utilisez cette procédure :

    1. Utilisez la commande SLAVE STOP.

    2. Vérifiez la variable de statut Slave_open_temp_tables pour vérifier si elle vaut bien 0.

    3. Si elle vaut bien 0, exécutez mysqladmin shutdown.

    4. Si le nombre n'est pas 0, redémarrez l'esclave avec la commande SLAVE START.

    5. Répetez la procédure et voyez si vous avez plus de chance la prochaine fois.

    Nous envisageons de corriger ce problème prochainement.

  • Il est possible de connecter les serveurs MySQL en chaîne bouclée (chaque serveur est le maître du précédent et l'esclave du suivant, en boucle), avec l'activation de l'option log-slave-updates. Notez que de nombreuses requêtes ne vont pas fonctionner dans ce type de configuration à moins que votre code client ne soit écrit avec beaucoup de soin, pour qu'il se charge des problèmes qui pourraient arriver dans différentes séquences de modifications sur différents serveurs.

    Cela signifie que vous pouvez réaliser une configuration comme ceci :

    A -> B -> C -> A
    

    Les identifiants de serveurs sont inscrits dans les événements. A saura qu'un événement qu'il a déjà exécuté lui est revenu, et il ne l'exécutera pas deux fois : il n'y a pas de risque de boucle infinie. Mais dans une configuration circulaire, vous devez vous assurer que le code client n'effectue pas de modifications conflictuelles. En d'autres termes, si vous insérez des données dans A et C, vous devez vous assurez qu'il n'y a pas de conflit de clé unique. Ne modifiez pas non plus deux lignes simultanément sur deux serveurs, si l'ordre des modifications a une importance pour vous.

  • Si la requête sur l'esclave génère une erreur, le thread esclave s'arrête, et un message sera ajouté dans le fichier d'erreur. Vous devriez vous connecter pour corriger manuellement les données de l'esclave, puis relancer l'esclave avec la commande SLAVE START (disponible depuis la version 3.23.16. En version 3.23.15, vous devrez redémarrer le serveur.

  • Si la connexion au maître est perdue, l'esclave tente de se reconnecter immédiatement, et en cas d'échec, il va retenter toutes les master-connect-retry (par défaut, 60) secondes. A cause de cela, il est sage d'éteindre le serveur maître et de le redémarrer régulièrement. L'esclave sera capable de gérer les problèmes réseau. See Section 5.2.3, « Variables serveur système ».

  • Eteindre l'esclave proprement est sûr, car il garde la trace du point où il en est rendu. Les extinctions sauvages vont produire des problèmes, surtout si le cache disque n'a pas été écrit sur le disque avant que le système ne s'arrête. Votre niveau de tolérance aux pannes sera grandement amélioré si vous avez de bons onduleurs.

  • Etant donné la nature non transactionnelle des tables MySQL, il est possible qui va ne faire qu'une partie de la modification, et retourner une erreur. Cela peut arriver, par exemple, dans une insertion multiple dont une des lignes viole une contrainte d'unicité, ou si un très long UPDATE est interrompu au milieu du stock de ligne. Si cela arrive sur le maître, l'esclave va s'arrêter et attendre que l'administrateur décide quoi faire, à moins que l'erreur soit légitime, et que la requête arrive à la même conclusion. Si le code d'erreur n'est pas désirable, certaines erreurs (voire même toutes), peuvent être masquées avec l'option slave-skip-errors, depuis la version 3.23.47.

  • Si vous modifiez une table transactionnelle depuis une table transactionnelle, dans un bloc de transaction BEGIN/COMMIT, les modifications du log binaire peut être déphasées si un thread a fait une modification dans la table non-transactionnelle, avant la validation de la transaction. Les transactions sont écrites dans le log binaire au moment de leur validation.

  • Avant la version 4.0.15, les modifications sur des tables non-transactionnelles sont écrites dans le log binaire immédiatement, alors que les modifications d'une transaction sont écrites au moment du COMMIT ou ignorées si vous utilisez un ROLLBACK; vous devez prendre cela en compte lors de la modification de tables transactionnelles et non-transactionnelles dans la même transaction, si vous utilisez le log binaire pour les sauvegardes ou la réplication. En version 4.0.15, nous avons modifié le comportement du log pour les transactions, qui mèlent les modifications de tables transactionnelles et non-transactionnelles dans la même transaction, pour résoudre ce problème. L'ordre des requêtes est maintenant maintenu, et toutes les requêtes sont écrites, même en cas d'annulation ROLLBACK. Le problème qui reste est que lorsqu'une seconde connexion modifie une table non-transactionnelle durant la transaction de la première connexion, une erreur d'ordre dans les requêtes peut survenir, car la seconde transaction sera écrite immédiatement après sa réalisation.

  • Lorsque l'esclave 4.x réplique une commande LOAD DATA INFILE depuis un maître 3.23, les valeurs des colonnes Exec_Master_Log_Pos et Relay_Log_Space pour SHOW SLAVE STATUS sont incorrectes. L'erreur de Exec_Master_Log_Pos va causer un problème lorsque vous stopperez et relancerez la réplication. Il est donc bon de corriger cela avec la commande FLUSH LOGS sur le maître. Ces bogues sont corrigés pour les esclaves en MySQL 5.0.0.

La table suivante liste les problèmes de MySQL 3.23 qui sont corrigés en MySQL 4.0 :

  • LOAD DATA INFILE est correctement géré, tant que les données résident toujours sur le serveur maître au moment de la propagation.

  • LOAD LOCAL DATA INFILE sera ignoré.

  • En version 3.23 RAND() dans les modifications de lignes ne se propage pas correctement. Utilisez RAND(some_non_rand_expr) si vous répliquez des modifications qui incluent RAND(). Vous pouvez, par exemple, utiliser UNIX_TIMESTAMP() comme argument de RAND(). Ceci est corrigé en version 4.0.

6.8 Options de démarrage de la réplication

Sur le maître comme sur l'esclave, vous devez utiliser l'option server-id pour donner un identifiant unique ID à chaque serveur. Vous pouvez choisir un entier dans l'intervalle de 1 à 2^32 − 1 pour chaque maître et esclave. Exemple : server-id=3

Les options que vous pouvez utiliser sur le maître pour contrôler les logs sont décrites dans la section Section 5.9.4, « Le log binaire ».

La table suivante décrit les options que vous pouvez utiliser sur les serveurs esclaves. Vous pouvez les spécifier en ligne de commande, ou dans le fichier d'options.

Les gestionnaires de réplication gèrent les options de manière spéciale, sans le sens où elles sont ignorées si un fichier master.info existe lorsque l'esclave est lancé, et qu'il contient des valeurs pour les options. Les options suivantes sont gérées de cette manière :

  • --master-host

  • --master-user

  • --master-password

  • --master-port

  • --master-connect-retry

Depuis MySQL 4.1.1, les options suivantes sont gérées de manière particulière :

  • --master-ssl

  • --master-ssl-ca

  • --master-ssl-capath

  • --master-ssl-cert

  • --master-ssl-cipher

  • --master-ssl-key

Le format du fichier master.info de version 4.1.1 a changé pour inclure les options SSL. De plus, en version 4.1.1, le fichier inclut le nombre de lignes comme première ligne. Si vous passez d'une ancienne version vers un serveur 4.1.1, le nouveau serveur va mettre à jour le fichier master.info avec le nouveau format au démarrage. Toutefois, si vous rétrogradez en version 4.1.1, vous devrez supprimer la première ligne avant de relancer votre vieux serveur. Notez que dans ce cas, le serveur ancien ne pourra pas utiliser les connexions sécurisées pour communiquer avec le maître.

Si aucun fichier master.info n'existe lors du lancement de l'esclave, il utiliser les valeurs de ces options. Cela arrivera lorsque vous lancez un serveur de réplication en tant qu'esclave, pour la première fois, ou si vous avez utilisé la commande RESET SLAVE et arrêté puis relancé le serveur.

Cependant, si master.info existe lorsque l'esclave démarre, il utilisera les valeurs dans le fichier et ignorera les valeurs spécifiées en ligne de commande, ou dans le fichier d'options master.info.

Si vous redémarrez le serveur avec différentes options de démarrage que les valeurs qui sont dans le master.info, ces nouvelles valeurs n'auront pas d'effet, car le serveur continuera d'utiliser master.info. Pour utiliser différentes valeurs, vous devez relancer le serveur après avoir supprimé master.info, ou, de préférence, utilise la commande CHANGE MASTER TO pour remettre à zéro les valeurs durant l'exécution.

Supposez que vous spécifiez cette option dans votre fichier my.cnf :

[mysqld]
master-host=un_hote

La première fois que vous démarrez le serveur en tant qu'esclave de réplication, il va lire et utiliser cette option dans le fichier my.cnf. Le serveur va ensuite enregistrer les valeurs courantes dans le fichier master.info. Au prochain démarrage du serveur, il va lire les valeurs dans le fichier master.info. Si vous modifiez my.cnf pour spécifier un nouvel hôte, cela n'aura pas d'effet. Vous devez utiliser la commande CHANGE MASTER TO.

Comme le serveur donne la priorité au fichier master.info sur les options de démarrage décrites, vous pourriez ne pas souhaiter utiliser les options de démarrage pour ces valeurs, et plutôt, les spécifier avec la commande CHANGE MASTER TO. Voir Section 13.6.2.1, « CHANGE MASTER TO ».

Cet exemple illustre une utilisation plus complète des options de démarrage pour configurer un serveur esclave :

[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com

La liste suivante décrit les options de démarrage qui contrôlent la réplication : De nombreuses options peuvent être remises à zéro pendant que le serveur fonctionne, en utilisant la commande CHANGE MASTER TO. Sinon, des options comme --replicate-* peuvent être utilisées lorsque le serveur esclave démarre. Nous envisageons de corriger cela.

  • --log-slave-updates

    Dit à l'esclave d'enregistrer les modifications effectuées par son thread SQL dans son propre log binaire. Par défaut, cette option est à Off. Pour que cette option ait un effet, l'esclave doit être lancé avec le log binaire activé : c'est l'option --log-bin option. --log-slave-updates sert lorsque vous voulez faire une chaîne de serveur de réplication. Par exemple :

    A -> B -> C
    

    C'est-à-dire, A sert de maître à l'esclave B, et B sert de maître à l'esclave C. Pour que cela fonctionne, avec B qui sert d'esclave et de maître simultanément, vous devez lancer B avec l'option --log-slave-updates. A et B doivent être lancés avec le log binaire activé.

  • --log-warnings

    Fait que l'esclave affiche plus de message sur ses activités. Par exemple, il vous alertera s'il réussi à se reconnecter après un problème de connexion, ou le démarrage de thread esclaves.

    Cette option n'est pas limitée à la réplication. Elle produit des alertes sur toutes la gamme des activités du serveur.

  • --master-connect-retry=seconds

    Le nombre de secondes qu'un esclave attend avant de tenter de se reconnecter au maître, dans le cas où le maître et l'esclave perdent la connexion. La valeur du fichier master.info a priorité, si elle est disponible. Par défaut, elle vaut 60.

  • --master-host=host

    Spécifie l'hôte ou l'IP du maître de réplication. Si cette option n'est pas fournie, le thread esclave ne sera pas lancé. La valeur inscrite dans le fichier master.info a priorité, si elle peut être lue. Un meilleur nom pour cette option aurait été --bootstrap-master-host, mais il est trop tard.

  • --master-info-file=file_name

    Le nom à utiliser pour le fichier dans lequel l'esclave stocke les informations sur le maître. Par défaut, c'est mysql.info, dans le dossier de données.

  • --master-password=password

    Le mot de passe que l'esclave utilise lors de l'identification auprès du maître. Si le mot de passe n'est pas configuré, la chaîne vide est utilisée. La valeur inscrite dans le fichier master.info a priorité, si elle peut être lue.

  • --master-port=port_number

    Le port du maître que l'esclave utilise lors de l'identification auprès du maître. Si le port n'est pas configuré, la valeur de la variable MYSQL_PORT est utilisée. Si vous n'y avez pas touché lors de la compilation avec configure, ce doit être 3306. La valeur inscrite dans le fichier master.info a priorité, si elle peut être lue.

  • --master-ssl, --master-ssl-ca=file_name, --master-ssl-capath=directory_name, --master-ssl-cert=file_name, --master-ssl-cipher=cipher_list, --master-ssl-key=file_name

    Ces options servent à configurer la réplication chiffrée, lorsque la connexion avec le maître utilise SSL. Leurs significations respectives est la même que les options --ssl, --ssl-ca, --ssl-capath, --ssl-cert, --ssl-cipher, --ssl-key décrites dans Section 5.6.7.5, « Options SSL en ligne de commande ».

    Ces options sont disponibles depuis MySQL 4.1.1.

  • --master-user=username

    Le nom d'utilisateur que l'esclave utilise lors de l'identification auprès du maître. Le compte doit avoir les droits de REPLICATION SLAVE (avant MySQL 4.0.2, il devait avoir les droits de FILE). Si l'utilisateur maître n'est pas configuré, l'utilisateur test est utilisé. La valeur inscrite dans le fichier master.info a priorité, si elle peut être lue. Si l'utilisateur maître n'est pas configuré, la valeur test est utilisée.

  • --max-relay-log-size=#

    Pour faire la rotation automatique des logs. See Section 13.5.3.18, « Syntaxe de SHOW VARIABLES ».

    Cette option est disponible depuis MySQL 4.0.14.

  • --read-only

    Cette option fait que le serveur n'autorise aucune modification, hormis celles du thread esclave, ou celle des utilisateurs ayant les droits de SUPER. Cela peut être utile si vous voulez vous assurer que l'esclave ne re¸oit aucune modification des clients.

    Cette option est disponible depuis MySQL 4.0.14.

  • --relay-log=filename

    Pour spécifier la localisation et le nom qui doivent être utilisés pour les logs de relais. Les noms par défaut sont de la forme host_name-relay-bin.nnn, où host_name est le nom du serveur esclave et nnn indique le numéro de séquence du log de relais. Vous pouvez utiliser ces options pour avoir des noms de fichier de log de relais indépendants du nom d'hôte, ou si vos logs ont tendances à devenir très grands (et que vous ne voulez pas réduire la valeur de max_relay_log_size) et que vous devez les mettre dans un autre dossier, ou simplement pour accélérer la vitesse d'équilibrage entre deux disques.

  • --relay-log-index=filename

    Pour spécifier la localisation et le nom qui doivent être utilisés pour le fichier d'index du log de relais. Le nom par défaut est host_name-relay-bin.index, où host_name est le nom du serveur esclave.

  • --relay-log-info-file=filename

    Pour donner au fichier relay-log.info un autre nom ou pour le placer dans un autre dossier. Le nom par défaut est relay-log.info dans le dossier de données.

  • --relay-log-purge={0|1}

    Active ou désactive la vidange automatique des logs de relais, dès qu'ils ne sont plus utiles. C'est une variable globale, qui peut être dynamiquement modifiée avec SET GLOBAL RELAY_LOG_PURGE=0|1. Sa valeur par défaut est 1.

    Cette option est disponible depuis MySQL 4.1.1.

  • --relay-log-space-limit=#

    Limite la taille maximale de tous les fichiers de logs de relais sur l'esclave (une valeur de 0 signifie ``sans limite''). C'est utile lorsque vous avez un petit disque sur votre machine esclave. Lorsque la limite est atteinte, le thread d'I/O fait une pause : il ne lit plus rien dans le log binaire du maître, jusqu'à ce que le thread SQL ait avancé, et effacé des fichiers de logs. Notez que cette limite n,est pas absolue : il se peut que le thread SQL requiert plusieurs événements pour être capable d'effacer les fichiers de log de relais. Dans ce cas, le thread d'I/O va dépasser la limite, jusqu'à ce que l'effacement devienne possible. Sans cela, des blocages pourraient survenir, ce qui arrivait sur les versions antérieures à la 4.0.13). Avec --relay-log-space-limit, il ne faut pas utiliser de valeur inférieure à deux fois la taille de --max-relay-log-size (ou --max-binlog-size si --max-relay-log-size vaut 0) car dans ce cas, il y a des chances que le thread d'I/O attende de l'espace libre par ce que --relay-log-space-limit est dépassée, mais que le thread SQL n'ait pas de logs à effacer, et ne peut donc libérer le thread d'I/O, for¸ant le thread d'I/O à ignorer temporairement --relay-log-space-limit.

  • --replicate-do-db=db_name

    Indique à l'esclave qu'il doit restreindre la réplication aux commandes qui utilisent la base de données db_name par défaut (c'est à dire celle qui est sélectionnée avec la commande USE). Pour spécifier plusieurs base de données, utilisez cette option aussi souvent que nécessaire. Note que cela ne va pas autoriser les commandes multi-bases, comme UPDATE some_db.some_table SET foo='bar' si une base de données différente ou qu'aucune base de données n'est sélectionnée. Si vous avez besoin que les commandes multi-bases fonctionnent, assurez vous que vous avez MySQL 3.23.28 ou plus récent, et utilisez --replicate-wild-do-table=db_name.%. Lisez les notes qui suivent cette liste d'options.

    Un exemple qui pourrait ne pas fonctionner comme vous l'attendez : si l'esclave est lancé avec --replicate-do-db=sales et que vous émettez une commande sur le maître, la commande UPDATE suivante ne sera pas répliquée :

    USE prices;
    UPDATE sales.january SET amount=amount+1000;
    

    Si vous avez besoin de répliquer des commandes multi-bases, utilisez l'option --replicate-wild-do-table=db_name.% à la place.

    La raison principale de ce comportement ``vérifie juste la base par défaut'' est qu'il est difficile de savoir si une requête doit être répliquée, uniquement à partir de la requête. Par exemple, si vous utilisez une requête multi-tables DELETE oui multi-tables UPDATE, qui a des conséquences dans d'autres bases. La vérification de la base courante est aussi très rapide.

  • --replicate-do-table=db_name.table_name

    Dit à l'esclave qu'il doit restreindre la réplication à une table spécifiée. Pour spécifier plusieurs tables, il faut utiliser cette directive plusieurs fois, une fois par table. Cela fonctionnera pour les mises à jours multi-bases, au contraire de --replicate-do-db. Lisez les notes qui suivent cette liste d'options.

  • --replicate-ignore-db=db_name

    Indique à l'esclave qu'il doit ne doit pas assurer la réplication avec les commandes qui utilisent la base de données db_name par défaut (c'est à dire celle qui est sélectionnée avec la commande USE). Pour spécifier plusieurs base de données, utilisez cette option aussi souvent que nécessaire. Note que cela ne va pas autoriser les commandes multi-bases, comme UPDATE some_db.some_table SET foo='bar' si une base de données différente ou qu'aucune base de données n'est sélectionnée. Si vous avez besoin que les commandes multi-bases fonctionnent, assurez vous que vous avez MySQL 3.23.28 ou plus récent, et utilisez --replicate-wild-do-table=db_name.%. Lisez les notes qui suivent cette liste d'options.

    Un exemple qui pourrait ne pas fonctionner comme vous l'attendez : si l'esclave est lancé avec --replicate-ignore-db=sales et que vous émettez une commande sur le maître, la commande UPDATE suivante ne sera pas répliquée :

    USE prices;
    UPDATE sales.january SET amount=amount+1000;
    

    Si vous avez besoin de répliquer des commandes multi-bases, utilisez l'option --replicate-wild-ignore-table=db_name.% à la place.

  • --replicate-ignore-table=db_name.table_name

    Dit à l'esclave qu'il ne doit pas répliquer les commandes qui touche à la table spécifiée, même si d'autres tables sont modifiées dans la même commande. Pour spécifier plusieurs tables, il faut utiliser cette directive plusieurs fois, une fois par table. Cela fonctionnera pour les mises à jours multi-bases, au contraire de --replicate-ignore-db. Lisez les notes qui suivent cette liste d'options.

  • --replicate-wild-do-table=db_name.table_name

    Dit à l'esclave qu'il doit restreindre la réplication aux tables dont le nom vérifie le masque spécifié. Le masque peut contenir les caractères ‘%’ et ‘_’, qui ont la même signification que dans les expressions régulières de la clause LIKE. Pour spécifier plusieurs tables, il faut utiliser cette directive plusieurs fois, une fois par table. Cela fonctionnera pour les mises à jours multi-bases, au contraire de --replicate-do-db. Lisez les notes qui suivent cette liste d'options.

    Exemple : --replicate-wild-do-table=foo%.bar% va répliquer les mises à jour qui surviennent sur toutes les tables de toutes les bases qui commencent par foo, et dont le nom de table commence par bar.

    Notez que si vous utilisez --replicate-wild-do-table=foo%.%, alors la règle sera propagée à CREATE DATABASE et DROP DATABASE, c'est à dire que ces deux commandes seront répliquées si le nom de la base correspond au masque (foo% ici) (la magie est ici déclenchée par % comme masque de table.).

    Si le masque de noms de tables est %, il accepte tous les noms de tables et les options s'appliquent aux commandes de niveau base de données (comme CREATE DATABASE, DROP DATABASE et ALTER DATABASE). Par exemple, si vous utilisez --replicate-wild-do-table=foo%.%, les commandes de niveau de base de données seront répliquées si le nom de la base de données est accepté par le masque foo%.

    Si vous voulez faire la réplication des tables du type ma_petite%base (ceci est le nom exact de la base), mais que vous ne voulez pas répliquer la base ma1petiteAABCbase, vous devez protéger les caractères ‘_’ et ‘%’ : il faut utiliser une syntaxe équivalent à : replicate-wild-do-table=my\_own\%db. Et si vous spécifiez cette option en ligne de commande, suivant votre système, vous devrez protéger aussi le caractère \ (par exemple, en Shell bash, vous devez émettre une option sous la forme --replicate-wild-do-table=my\\_own\\%db).

  • --replicate-wild-ignore-table=db_name.table_name

    Dit à l'esclave qu'il ne doit pas répliquer les tables dont le nom vérifie le masque spécifié. Pour spécifier plusieurs tables, il faut utiliser cette directive plusieurs fois, une fois par table. Cela fonctionnera pour les mises à jours multi-bases, au contraire de --replicate-do-db. Lisez les notes qui suivent cette liste d'options.

    Exemple : --replicate-wild-ignore-table=foo%.bar% n'autorisera pas de modifications dans les tables des bases dont le nom commence par foo et dont le nom de table commence par bar.

    Pour des informations sur le fonctionnement du filtre, voyez l'option --replicate-wild-ignore-table. La règle pour inclure des caractères littéraux est la même que pour --replicate-wild-ignore-table.

  • --replicate-rewrite-db=from_name->to_name

    Dit à l'esclave de remplacer la base courante (celle qui est sélectionnée avec USE) par to_name si elle était from_name sur le maître. Seules les commandes impliquant des tables peuvent être affectées. (CREATE DATABASE, DROP DATABASE ne le seront pas), et uniquement si from_name était la base de données courante sur le maître. Cela ne fonctionnera pas pour les commandes multi-bases de données. Notez que la traduction est faite avant que les règles --replicate-* ne soient testées.

    Si vous utilisez cette option en ligne de commande, et que vous utilisez le caractère ‘>’, qui peut être spécial pour votre interpréteur Shell, protégez-le comme ceci :

    shell> mysqld --replicate-rewrite-db="olddb->newdb"
    

  • --replicate-same-server-id

    A utiliser sur les serveurs esclaves. Généralement, vous pouvez spécifier la valeur 0 pour éviter les réplications infinies. Si cette option vaut 1, l'esclave n'ignorera pas les événements de réplication, même s'ils portent son propre numéro d'identification. Normalement, cela n'est utile que pour de très rares configurations. Vous ne pouvez pas mettre cette option à 1 si --log-slave-updates est utilisé. Faîtes attention en démarrant MySQL 4.1, par défaut le thread d'E/S n'écrit pas les événements dans le log de relais s'ils portent l'identification du serveur esclave (c'est une optimisation pour économiser l'espace disque, par rapport à la version 4.0). Si vous voulez utiliser --replicate-same-server-id avec les versions 4.1, assurez vous de démarrer l'esclave avec cette option avant que l'esclave ne lise ses propres événements et qu'il les fasse exécuter au thread SQL.

  • --report-host=host

    Le nom d'hôte ou l'adresse IP de l'esclave, qui doit être indiquée lors de l'enregistrement de l'esclave chez le maître. Cela apparaîtra dans l'affichage de la commande SHOW SLAVE HOSTS. Laissez cette option vide pour que l'esclave ne s'enregistre pas sur le maître. Notez qu'il n'est pas suffisant pour que le maître lise l'adresse IP de l'esclave sur la socket, une fois que l'esclave se connecte. à cause du NAT et des problèmes de routages, cette IP peut être invalide pour se connecter au maître depuis l'hôte ou les autres esclaves.

    Cette option est disponible depuis MySQL 4.0.0.

  • --report-port=port_number

    Le port de connexion indiqué par l'esclave lors de son enregistrement chez le maître. Configurez cette option si l'esclave utilise un port autre que le port par défaut, ou si vous avez installé un tunnel spécial pour le maître ou les autres esclaves. Dans le doute, laissez cette option vide.

    Cette option est disponible depuis MySQL 4.0.0.

  • --skip-slave-start

    Dit à l'esclave de ne pas lancer les threads esclaves au démarrage du serveur L'utilisateur pourra les lancer manuellement, avec START SLAVE.

  • --slave_compressed_protocol=#

    Si cette option vaut 1, alors le protocole client/serveur compressé sera utilisé, si l'esclave et le maître le supportent.

  • --slave-load-tmpdir=filename

    Cette option vaut par défaut la variable tmpdir. Lorsque le thread SQL répliquer des commandes LOAD DATA INFILE, il extrait les fichiers à charger du log de relais dans un fichier temporaire, puis charge ce fichier dans la table. Si le fichier chargé sur le maître est immense, le fichier temporaire sera aussi grand. Il faudra donc dire à l'esclave que placer ces fichiers temporaires sur un grand disque, qui sera différent de tmpdir : utilisez cette option. Dans ce cas, vous pouvez aussi utiliser l'option --relay-log, car les fichiers de log de relais seront aussi grands. --slave-load-tmpdir doit pointer sur un système de fichier basés sur un disque, et non pas sur une portion de mémoire : l'esclave doit pouvoir accéder à ce fichier pour répliquer la commande LOAD DATA INFILE, même après un redémarrage.

  • --slave-net-timeout=#

    Le nombre de secondes à attendre des données du maître, avant d'annuler la lecture en considérant que la connexion est rompue, et de tenter de se reconnecter. La première reconnexion intervient immédiatement après l'expiration du délai. L'intervalle entre deux tentatives de connexion est contrôlé par l'option --master-connect-retry.

  • --slave-skip-errors= [err_code1,err_code2,... | all]

    Normalement, la réplication s'arrête lorsqu'une erreur survient, ce qui vous donne l'opportunité de résoudre les incohérences manuellement. Cette option Indique au thread SQL les erreurs qu'il doit ignorer durant la réplication.

    N'utilisez pas cette option si vous ne connaissez pas la raison des erreurs que vous rencontrez. S'il n'y a pas de bugs dans votre réplication, et qu'il n'y a pas de bug dans MySQL, vous ne devriez pas rencontrer d'erreurs, ni utiliser cette option. L'utilisation abusive de cette option conduit irrémédiablement l'esclave à être désynchronisé avec le maître sans que vous ne sachiez d'où vient l'erreur.

    Pour les codes d'erreur, il faut utiliser les numéros d'erreurs fournis par l'esclave dans le log d'erreur, et dans le résultat de SHOW SLAVE STATUS. La liste complète des messages d'erreurs est disponible dans la distribution source, dans le fichier Docs/mysqld_error.txt. Les codes d'erreur du serveur sont aussi disponibles sur Chapitre 26, Gestion des erreurs avec MySQL.

    Vous pouvez (mais ne devez pas) utiliser la valeur très déconseillée de all, qui va ignorer tous les messages d'erreur, et continuer à touiller les données sans se préoccuper de cohérence. Inutile d'insister sur le fait que l'intégrité de vos données n'est plus du tout garantie. Ne vous plaignez pas si les données de votre esclave ne ressemblent même pas du tout à celle de votre maître : vous aurez été prévenu.

    Exemples :

    --slave-skip-errors=1062,1053
    --slave-skip-errors=all
    

Voici l'ordre d'étude des règles r--eplicate-*, pour décider si une requête doit être exécutée par l'esclave ou ignorée :

  1. Existe-t-il des règles --replicate-do-db ou --replicate-ignore-db ?

    • Oui : les tester pour --binlog-do-db et --binlog-ignore-db (see Section 5.9.4, « Le log binaire »). Quel est le résultat?

      • ignorer la requête : ignore la requête et quitte.

      • exécute la requête : n'exécute pas la requête immédiatement, reporte la décision, et passe à l'étape d'après.

    • Non : passe à l'étape d'après.

  2. Y-t-il des règles --replicate-*-table?

    • Non : exécute la requête et quitte.

    • Oui : passe à l'étape d'après. Seules les tables qui doivent être modifiées seront utilisées dans les règles : (INSERT INTO sales SELECT * from prices: seule sales sera utilisée pour évaluer les règles. Si plusieurs tables doivent être modifiées (modifications multi-tables), la première table (qui correspond à un ``do'' ou ``ignore'') gagne. C'est à dire que la première table est utilisée dans les règles de comparaison, et si aucune décision ne peut être prise, la seconde table est utilisée...

  3. Y a-t-il des règles --replicate-do-table?

    • Oui : Est-ce qu'une table entre dans cette liste?

      • Oui : exécute la requête et quitte.

      • Non : passe à l'étape d'après.

    • Non : passe à l'étape d'après.

  4. Y a-t-il des règles --replicate-ignore-table?

    • Oui : Est-ce qu'une table entre dans cette liste?

      • Oui : ignore la requête et quitte.

      • Non : passe à l'étape d'après.

    • Non : passe à l'étape d'après.

  5. Y a-t-il des règles --replicate-wild-do-table?

    • Oui : Est-ce qu'une table entre dans cette liste?

      • Oui : exécute la requête et quitte.

      • Non : passe à l'étape d'après.

    • Non : passe à l'étape d'après.

  6. Y a-t-il des règles --replicate-wild-ignore-table?

    • Oui : Est-ce qu'une table entre dans cette liste?

      • Oui : ignore la requête et quitte.

      • Non : passe à l'étape d'après.

    • Non : passe à l'étape d'après.

  7. Aucune règle n'a fonctionné avec --replicate-*-table. Y a-t-il d'autres tables à tester?

    • Oui : boucle.

    • Non : Nous avons testé toutes les tables à mettre à jour, et nous n'avons pas trouvé de règle les concernant. Y a-t-il des règles --replicate-do-table ou --replicate-wild-do-table?

      • Oui : ignore la requête et quitte.

      • Non : exécute la requête et quitte.

6.9 FAQ de la réplication

Q : Comment puis-je configurer un esclave si le maître fonctionne déjà, et que je ne veux pas le stopper?

R : Il y a plusieurs solutions. Si vous avez effectué une sauvegarde du maître à un moment et enregistré le nom et l'offset du binlog (issu du résultat de la commande SHOW MASTER STATUS) correspondant à la sauvegarde, faites ceci :

  1. Assurez-vous qu'un identifiant unique est assigné à l'esclave.

  2. Exécutez la commande pour chaque valeur appropriée :

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='master_host-name',
        ->     MASTER_USER='master_user_name',
        ->     MASTER_PASSWORD='master_pass',
        ->     MASTER_LOG_FILE='recorded_log_name',
        ->     MASTER_LOG_POS=recorded_log_pos;
    
  3. Exécutez la commande SLAVE START

Si vous n'avez pas de copie de sauvegarde, voici un moyen rapide d'en faire une :

  1. Exécutez cette commande MySQL :

    mysql> FLUSH TABLES WITH READ LOCK;
    
  2. Exécutez cette commande Shell, ou toute variation de cette commande :

    shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
    
  3. Utilisez cette commande pour vous assurer de bien noter les informations de réplication. Vous en aurez besoin ultérieurement.

    mysql> SHOW MASTER STATUS;
    
  4. Libérez les tables :

    mysql> UNLOCK TABLES;
    

Un autre alternative est de faire un export SQL du maître, au lieu de faire une copie comme indiqué ci-dessus : pour cela, vous pouvez utiliser l'utilitaire mysqldump --master-data sur votre maître, et exécuter ce script ultérieurement sur votre esclave. Cependant, c'est une méthode plus lente que de faire une copie binaire.

Quelque soit la méthode que vous adoptez, après cela, suivez les instructions comme pour le cas où vous avez déjà votre sauvegarde, et que vous avez enregistré le nom et l'offset du point de contrôle du log binaire. Tant que les logs binaires du serveur sont toujours là, vous allez pouvoir rattrapper tout ce qui se fait sur le serveur principal. Vous pourriez même attendre plusieurs jours ou mois avant de mettre en place votre esclave. En théorie, le temps d'attente peut être infini. En pratique, les limitations sont l'espace disque du maître, et le temps que cela prendra à l'esclave pour rattrapper le temps.

Vous pouvez aussi utiliser LOAD DATA FROM MASTER. C'est une commande pratique pour faire une copie de la base, l'envoyer à l'esclave, et ajutser le point de contrôle du log binaire, tout en une seule commande. Dans le future, LOAD DATA FROM MASTER sera la méthode recommandée pour configurer un esclave. Soyez prévenus, que le verrou de lecture posé par la commande sur le serveur peut rester en place un très long moment, si vous utilisez cette commande : elle n'est pas encore implémentée de manière efficace. Si vous avez de grandes tables, préférez donc la méthode qui utilise la sauvegarde via l'utilitaire tar après avoir exécuté la commande FLUSH TABLES WITH READ LOCK.

Q : Est ce que l'esclave doit être connecté en permanance au serveur?

R : Non, il n'est pas obligé. Vous pouvez éteindre l'esclave et le laisser déconnecter plusieurs heures ou jours, puis le reconnecter pour le voir récupérer les modifications et rattrapper le temps. Puis, se déconnecter à nouveau. De cette fa¸on, vous pouvez, par exemple, configurer un esclave via une connexion modem, qui n'utilise que de brève période de connexions. L'implication de cela est qu'il n'est jamais garantit que l'esclave soit synchronisé avec le maître, à moins que vous ne preniez des mesures pour cela. Dans le futur, nous allons avoir l'option de bloquer le maître jusqu'à ce que au moins un des esclaves soit synchronisé.

Q : Comment puis-je mesurer le retard d'un esclave sur son maître? En d'autres termes, comme savoir quelle est la date de la dernière requête répliquée par l'esclave?

R : Si l'esclave est en version 4.1.1 pour plus récent, lisez la colonne Seconds_Behind_Master dans la commande SHOW SLAVE STATUS. Pour les versions plus anciennes, suivez cette procédure : Cela n'est possible que si un thread SQL existe, c'est à dire s'il existe dans la commande SHOW PROCESSLIST, See Section 6.3, « Détails d'implémentation de la réplication ».

En MySQL version 3.23, si le thread SQL esclave existe, c'est à dire, s'il apparait dans la commande SHOW PROCESSLIST, et s'il a exécuté au moins un événement lu auprès du maître, the thread modifie sa propre horloge pour prendre l'horaire du dernier événement répliqué (c'est pour cela que les colonnes TIMESTAMP sont bien répliquées. Dans la colonne Time du résultat de SHOW PROCESSLIST, le nombre de secondes affichées est le nombre de secondes entre la dernière commande exécutée sur le serveur maître et celle exécutée sur l'esclave. Notez que si votre esclave a été déconnecté du maître durant une heure, lorsqu'il se reconnecte, vous pouvez voir immédiatement la valeur 3600 dans la colonne Time, pour le thread esclave dans SHOW PROCESSLIST... Ceci est du au fait que la dernière requête exécuté date d'une heure.

Q : Comment puis-je forcer le maître à bloquer les modifications jusqu'à ce que l'esclave ait tout rattrappé?

R : Exécutez les commandes suivantes :

  1. Sur le maître, exécutez ces commandes :

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    Enregistrez le nom du fichier de log et l'offset, dans la commande SHOW.

  2. Sur l'esclave, utilisez la commande ci-dessous, où vous aurez reporté les arguments de coordonnées de réplication données par MASTER_POS_WAIT() :

    mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
    

    La commande SELECT va s'arrêter jusqu'à ce que l'esclave atteigne le fichier de log et l'offset. A ce point, l'esclave sera synchronisé avec le maître, et la commande se terminera.

  3. Sur le maître, utilisez la commande suivante pour permettre au maître de recommencer à traiter les modifications :

    mysql> UNLOCK TABLES;
    

Q : Quels sont vos conseils concernant la réplication bi-bidirectionnelle?

R : La réplication MySQL ne supporte aucun protocole de verrouillage entre le maître et l'esclave pour garantir l'atomicité d'une modification entre les serveurs. En d'autres termes, il est possible pour un client A de faire une modification sur le serveur 1 et que dans le même temps, avant que cela ne se soit propagé au serveur 2, un client B se connecte au serveur 2, et fasse une modification sur le serveur 2 qui ne débouchera pas sur le même état que celui dans lequel le serveur 1 est. C'est ainsi qu'il ne faut pas lier de cette fa¸on deux serveurs, à moins que les modifications ne puisse se faire dans n'importe quel ordre, ou que vous sachiez prendre en charge des modifications anarchiques.

Vous devez aussi réaliser que la réplication bi-directionnelle n'améliore pas beaucoup les performances, tout au moins au niveau des modifications. Les deux serveurs doivent faire la même quantité de modifications, ainsi qu'un serveur seul le ferait. La seule différence est qu'il va y avoir moins de verrous, car les modifications qui proviennent d'un autre serveur seront optimisé par l'esclave. Cet avantage peut aussi être annulé par les délais réseau.

Q : Comment puis-je utiliser la réplication pour améliorer les performances de mon système ?

R : Vous devez configurer un serveur en maître et y diriger toutes les écritures, puis configurer les autres en esclaves dans la limite de vos moyens, et y distribuer les lectures. Vous pouvez aussi démarrer les esclaves en mode --skip-bdb, --low-priority-updates et --delay-key-write=ALL pour accélérer les esclaves. Dans ce cas, l'esclave va utiliser les tables non transactionnelles MyISAM au lieu des tables BDB pour obtenir plus de vitesse.

Q : Que dois-je faire pour préparer mon code client à la réplication?

R : Si la partie de votre code qui réalise les accès aux bases de données a été proprement modularisée, la convertir en une configuration qui supporte la réplication ne sera pas un problème : modifiez simplement votre base pour qu'elle aille lire sur les esclaves et le maître, mais ne fasse que des modifications avec le maître. Si votre code n'a pas ce niveau d'abstraction, l'installation du système de réplication vous donnera alors la motivation ou la raison pour le faire. Vous devriez commencer par créer une couche d'abstraction ou un module avec les fonctions suivantes :

  • safe_writer_connect()

  • safe_reader_connect()

  • safe_reader_query()

  • safe_writer_query()

safe_ signifie que la fonction devra prendre en charge toutes les conditions d'erreurs. Naturellement, vous pouvez utiliser des noms différents pour les fonctions. L'important est de savoir clairement laquelle se connecte en écriture et laquelle se connecte en lecture, et laquelle lit et laquelle écrit.

Vous devriez alors convertir votre code client pour qu'il utilise cette bibliothèque. Cela peut être un processus laborieux et déroutant, mais il va s'avérer payant dans le long terme. Toutes les applications qui suivent la technique ci-dessus pourront alors prendre avantage des solutions de réplication. Le code sera aussi bien plus facilement entretenu, et ajouter des options sera trivial. Vous devrez modifier une ou deux fonctions, comme par exemple pour enregistrer le temps de calcul de certaines requêtes, ou les requêtes qui vous retournent des erreurs.

Si vous avez écrit beaucoup de code jusqu'ici, vous pourriez vouloir automatiser la conversion en utilisant l'utilitaire de Monty, replace, qui est distribué avec la distribution standard de MySQL, ou bien simplement en écrivant un script Perl. Avec un peu de chance, votre code suit des conventions connues. Si ce n'est pas le cas, alors vous serez peut être conduit à réécrire votre application de toutes manières, ou bien, à lui appliquer des méthodes à la main.

Q : Quand et combien de réplications de MySQL permettent d'améliorer les performances de mon système?

R : La réplication MySQL est particulièrement avantageuse pour les systèmes qui gèrent des lectures fréquentes, et des écritures plus rares. En théorie, en utilisant uniquement un maître et beaucoup d'esclaves, vous pouvez augmenter les performances de votre système jusqu'à saturation de la bande passante ou du maître, pour les modifications.

Afin de déterminer le nombre d'esclaves que vous pouvez obtenir voir les performances de votre système s'améliorer, vous devez bien connaître les types de requêtes que vous utilisez, et empiriquement déterminer la relation entre le nombre de lectures et d'écritures (par secondes, ou maximum absolu), pour un maître et un esclave. L'exemple ci-dessous va vous montrer comment faire des calculs simples.

Imaginons que votre charge système soit constituée de 10% d'écriture et de 90% de lectures. Nous avons aussi déterminé que le maximum de lectures max_reads = 1200 − 2 * max_writes, ou, en d'autres mots, notre système peut voir des pics de 1200 lectures par secondes sans aucune écritures, notre temps d'écriture moyen est deux fois plus temps qu'une lecture, et la relation est linéaire. Supposons que notre maître et notre esclave sont de la même capacité, et que nous avons N esclaves et un maître. Nous avons alors pour chaque serveur (maître ou esclave) :

lectures = 1200 - 2 * écriture (issue des tests)

lectures = 9* écriture / (N + 1) (lectures réparties, mais toutes les écritures vont à tous les serveurs)

9*écriture/(N+1) + 2 * écriture = 1200

écriture = 1200/(2 + 9/(N+1)

  • Si N = 0, ce qui signifie que nous n'avons pas de réplication, notre système peut gérer 1200/11, environs 109 écritures par secondes, ce qui signifie (que nous aurons 9 fois plus de lectures que d'écritures, étant donné la nature de notre application).

  • Si N = 1, nous pouvons monter à 184 écriture par seconde.

  • Si N = 8, nous pouvons monter à 400 écriture par seconde.

  • Si N = 17, nous pouvons monter à 480 écriture par seconde.

  • Eventuellement, si N se rapproche de l'infini (et notre budget de l'infini négatif), nous pourrons nous rapprocher de 600 écritures par secondes, en améliorant le système 5,5 fois. Toutefois, avec 8 serveurs, nous avons pu améliorer le système de 4 fois.

Notez que nos calculs ont supposés une bande passante infinie, et que nous avons négligé des facteurs qui pourraient être significatifs pour notre système. Dans de nombreux cas, nous ne pourrions pas faire de calculs précis pour prédire l'état de notre système avec N esclaves de réplication. Toutefois, répondre aux questions ci-dessus vous permettra de décider si la réplication est une solution à votre problème ou pas.

  • Quel est le ratio d'écriture/lecture de votre système?

  • Quelle est la charge maximale d'un serveur en écriture, si vous pouvez limiter les lectures?

  • Combien d'esclaves votre réseau peut supporter?

Q : Comment puis-je utiliser la réplication pour fournir un système à haute tolérance de panne?

R : Avec les fonctionnalités actuellement disponible, vous devez configurer un serveur et un esclave (ou plusieurs esclaves), et écrire un script qui va surveiller le maître pour voir si il fonctionne , et instruire votre application et les esclaves d'un changement de maître en cas d'échec. Voici des suggestions :

  • Utilisez la commande CHANGE MASTER TO pour changer un esclave en maître.

  • Un bon moyen de garder votre application informé du maître courant est d'utiliser les DNS dynamiques, vous pouvez attribuer au maître. Avec bind, vous pouvez utiliser nsupdate pour modifier dynamiquement votre DNS.

  • Vous devez faire fonctionner vos esclaves avec l'option log-bin et sans l'option log-slave-updates. De cette fa¸on, l'esclave sera prêt à prendre le relais dès que vous lui enverrez la commande STOP SLAVE; envoyez RESET MASTER et CHANGE MASTER TO aux autres esclaves.

    Par exemple, considérez l'architecture suivante (``M'' représente le maître, ``S'' les esclaves, ``WC'' les clients qui émettent des commandes de lecture et écriture. Les clients qui ne font que des lectures ne sont pas représentés, car ils n'ont pas à changer quoi que ce soit.

           WC   
            \  
             v
     WC----> M
           / | \  
          /  |  \     
         v   v   v
        S1   S2  S3  
    

    S1 (comme S2 et S3) est un esclave qui fonctionne avec les options --log-bin et sans --log-slave-updates. Comme les seules écritures faites sur S1 sont celles qui sont répliquées depuis M, le log binaire de S1 est vide : n'oubliez pas que S1 fonctionne sans --log-slave-updates. Puis, pour une raison quelconque, M devient inaccessible, et vous voulez que S1 devienne le nouveau maître (c'est à dire, les WC sont dirigées vers S1, et S2 et S3 répliquent S1.

    Assurez vous que tous les esclaves ont fini de traîter les requêtes de leur log de relais. Sur chaque esclave, faites STOP SLAVE IO_THREAD, puis vérifiez le résultat de la commande SHOW PROCESSLIST jusqu'à ce que vous lisiez Has read all relay log. Lorsque cela est vrai pour tous les esclaves, ils peuvent être reconfigurés vers un nouveau maître. Faites STOP SLAVE sur chaque esclave, et RESET MASTER sur celui qui devient le maître, puis CHANGE MASTER sur les autres.

    Aucun WC n'accède à M. Reconfigurez les WC pour qu'ils dirigent leurs requêtes sur S1. A partir de maintenant, les requêtes envoyées par WC à S1 sont écrites dans le log binaire. Le log binaire de S1 contient maintenant exactement chaque requête envoyée à S1 depuis que M est mort. Sur S2 (et S3), faites STOP SLAVE, CHANGE MASTER TO MASTER_HOST='S1' (où 'S1' est remplacé par le vrai nom d'hôte de S1). Pour changer le maître, utilisez la commande CHANGE MASTER, et ajoutez les informations de connexion à S1 depuis S2 et S3 (utilisateur, mot de passe, port). Dans CHANGE MASTER, il n'y a pas besoin de spécifier le nom du fichier de log binaire de S1, ou la position dans le log : nous savons que c'est le premier fichier et le premier offset (position 4), car ce sont les coordonnées par défaut utilisées par CHANGE MASTER. Finalement, lances START SLAVE sur S2 et S3, et maintenant, vous avez ceci :

           WC   
          /   
          |  
     WC   |  M(indisponible)
      \   | 
       \  | 
        v v
         S1<--S2  S3  
          ^       |
          +-------+
    

    Lorsque M est de nouveau disponible, vous devez utiliser la commande CHANGE MASTER comme vous l'avez fait avec S2 et S3, pour que M devienne l'esclave de S1 et rattrappe toutes les modifications que les WC ont émise, et qu'il a manqué. Puis, pour refaire de M le maître, suivez la même procédure que précédemment, comme si S1 était indispoinble et que M prenait le relais. Durant la procédure, n'oubliez pas d'utiliser la commande RESET MASTER sur M avant de faire de S1, S2 et S3 des esclaves de M, car ils risquent de reprendre les anciennes requêtes des WC, qui datent d'avant l'indisponibilité de M.

Nous travaillons actuellement à l'intégration automatique de l'élection d'un nouveau maître, mais jusqu'à ce que ce soit près, vous devez créer votre propre outil de surveillance.

6.10 Correction de problèmes courants

Si vous avez suivi les instructions, et que votre configuration de réplication ne fonctionne pas, commencez par supprimer les problèmes liés à l'utilisateur comme ceci :

  • Vérifiez les messages d'erreurs dans les logs. De nombreux utilisateurs ont perdu du temps en ne faisant pas cela en premier.

  • Est-ce que le maître enregistre dans le log binaire ? Vérifiez avec la commande SHOW MASTER STATUS. Si il le fait, la variable Position doit être non nulle. Si ce n'est pas le cas, vérifiez que vous avez donné au serveur l'option log-bin et que vous lui avez donné un server-id.

  • Est-ce que l'esclave fonctionne? Vérifiez le avec SHOW SLAVE STATUS. La réponse se trouve dans la colonne Slave_running. Si ce n'est pas le cas, vérifiez les options de l'esclave, et vérifiez le fichier de log d'erreurs.

  • Si l'esclave fonctionne, a-t-il établit une connexion avec le maître? Exécutez la commande SHOW PROCESSLIST, et recherchez un utilisateur avec la valeur system user dans la colonne User et none dans la colonne Host, et vérifiez la colonne State. Si elle indique connecting to master, vérifiez les droits de connexion pour l'utilisateur de réplication sur le serveur, ainsi que le nom de l'hôte, votre configuration DNS, le fonctionnement du maître, et si tout est OK, vérifiez le fichier de log d'erreurs.

  • Si l'esclave fonctionnait, mais s'est arrêté, vérifiez le résultat de la commande SHOW SLAVE STATUS, et vérifiez le fichier de log d'erreurs. Il arrive que certaines requêtes réussissent sur le maître mais échouent sur l'esclave. Cela ne devrait pas arriver si vous avez pris la bonne sauvegarde du maître, et que vous n'avez jamais modifié les données sur le serveur esclave, autrement que par le truchement de l'esclave de réplication. Si c'est le cas, c'est un bogue, et vous devez le rapporter. Voyez plus loin pour savoir comment rapporter un bogue.

  • Si une requête qui a réussit sur le maître, refuse de s'exécuter sur l'esclave, et qu'une synchronisation complète de la base ne semble pas possible, essayez ceci :

    1. Commencez par voir s'il n'y a pas de lignes différentes de celles du maître. Essayez de comprendre comment elle a plus se trouver là, effacez-la, et essayez de redémarrer l'esclave avec SLAVE START. (cela peut être un bug : lisez les logs sur le manuel MySQL, http://www.mysql.com/documentation, pour savoir si c'est un bug et s'il est corrigé).

    2. Si la solution ci-dessus ne fonctionne pas ou ne s'applique pas, essayez de comprendre si c'est risqué de faire une correction à la main (au besoin) puis, ignorez la prochaine requête du maître.

    3. Si vous avez décidé que vous pouvez vous passer de la prochaine requête, utilisez la commande suivante :

      mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
      mysql> START SLAVE;
      

      La valeur de n doit être de 1 si la requête n'utilise pas de valeur AUTO_INCREMENT ou LAST_INSERT_ID(). Sinon, la valeur doit être de 2. La raison pour utiliser la valeur 2 pour les requêtes qui utilisent AUTO_INCREMENT ou LAST_INSERT_ID() est qu'elles requièrent deux lignes dans le log binaire.

    4. Si vous êtes sûrs que l'esclave est parfaitement synchronisé avec le maître, et que personne n'a mis à jour les tables impliquées, rapportez nous un bug.

6.11 Rapporter des bugs de réplication

Lorsque vous avez bien vérifié qu'il n'y a pas de problèmes avec les utilisateurs impliqués, et que la réplication ne fonctionne pas ou qu'elle est instable, il est temps d'envoyer un rapport de bug. Nous avons besoin d'autant d'information que possible pour rechercher le bug. N'hésitez pas à investir quelques efforts lors de la préparation d'u rapport de bug.

Si vous avez un moyen de reproduire le bug, alors indiquez le dans notre base de bugs à l'adresse http://bugs.mysql.com/. Si vous avez un problème fantôme (un qui ne peut être réproduire ``à souhait''), utilisez la procéduire suivante :

  1. Vérifiez qu'il n'y a pas d'erreur utilisateur impliquée. Par exemple, si vous modifiez l'esclave sans passer par le thread esclave, les données seront désynchroniséez et vous pourrez alors rencontrer des problèmes de contraintes de clés uniques durant les modifications. Dans ce cas, l'esclave doit être arrêté et nettoyé manuellement pour être synchronisé avec le maître. Ce n'est pas un problème de réplication : c'est un problème d'interference extérieure, qui conduit à l'échec de la réplication.

  2. Exécutez l'esclave avec les options --log-slave-updates et --log-bin. Elles font que l'esclave va enregistrer les modifications qu'il re¸oit dans ses propres logs binaires.

  3. Sauvez toutes les preuves avant de remettre à zéro l'état de la réplication. Si vous n'avez aucune information, ou seulement des informations partielles, cela nous prendra plus de temps pour rechercher le problème. Les preuves que vous devez rassembler sont :

    • Tous les logs binaires du maître

    • Tous les logs binaires de l'esclave

    • Le résultat de la commande SHOW MASTER STATUS sur le maître au moment du problème.

    • Le résultat de la commande SHOW SLAVE STATUS sur l'esclave au moment du problème.

    • Les logs d'erreur du maître et de l'esclave.

  4. Utilisez mysqlbinlog pour éxaminer les logs binaires. La commande suivante doit permettre d'identifier la requête coupable :

    mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head
    

Une fois que vous avez rassemblez toutes ces preuves du problème fantôme, essayer de l'isoler dans des cas de tests indépendants. Puis, soumettez le problème dans notre base de bugs à l'adresse http://bugs.mysql.com/ avec toute autre information importante.