Chapitre 6. Réplication de MySQL
Précédent |  | Suivant

## Chapitre 6. Réplication de MySQL

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 unidreictionnelle 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 :

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

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

Line | Description
1 | Nombre de lignes dans le fichier
2 | `Master_Log_File`
3 | `Read_Master_Log_Pos`
4 | `Master_Host`
5 | `Master_User`
5 | Mot de passe (pas affiché par `SHOW SLAVE STATUS`)
7 | `Master_Port`
8 | `Connect_Retry`
9 | `Master_SSL_Allowed`
10 | `Master_SSL_CA_File`
11 | `Master_SSL_CA_Path`
12 | `Master_SSL_Cert`
13 | `Master_SSL_Cipher`
14 | `Master_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 :

Ligne | Description
1 | `Relay_Log_File`
2 | `Relay_Log_Pos`
3 | `Relay_Master_Log_File`
4 | `Exec_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 utiliez 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 uassi 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_HOST` | 60
   `MASTER_USER` | 16
   `MASTER_PASSWORD` | 32
   `MASTER_LOG_FILE` | 255

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ître | Maître | Maître
|  | 3.23.33 et plus récent | 4.0.3 et plus récent or any 4.1.x | 5.0.0
Esclave | 3.23.33 et plus récent | oui | non | non
Esclave | 4.0.3 et plus récent | oui | oui | non
Esclave | 5.0.0 | oui | oui | oui

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 applcation 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.

This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

Précédent |  | Suivant
Chapitre 5. Administration du serveur | Sommaire | Chapitre 7. Optimisation de MySQL