# MySQL/Réplication

* Introduction
* PhpMyAdmin
* Parcourir les bases de données
* Spécifier les noms
* LDD, LMD et LCD
* Variables utilisateurs
* Alias
* Types de données
* Manipulation de base
** mysqldump
* Manipulation de table
* Manipulation de données
* Requêtes
* NULL
* Opérateurs
* Fonctions
* Procédures stockées
* Regex
* Bases de données spatiales
* Importer et exporter
* Réplication
* Optimisation
* API
* Sécurité
* Mots réservés
* Débogage
* Introduction
* PhpMyAdmin
* Parcourir les bases de données
* Spécifier les noms
* LDD, LMD et LCD
* Variables utilisateurs
* Alias
* Types de données
* Manipulation de base
** mysqldump
* Manipulation de table
* Manipulation de données
* Requêtes
* NULL
* Opérateurs
* Fonctions
* Procédures stockées
* Regex
* Bases de données spatiales
* Importer et exporter
* Réplication
* Optimisation
* API
* Sécurité
* Mots réservés
* Débogage
[ Modifier le sommaire ]

## Principe

La réplication signifie que les données écrites sur le master MySQL sont envoyées à des slaves faisant office de copies.
Applications :
* Sauvegardes : backup automatique alternatif à mysqldump.
* Distribution : accès en lecture de la même base depuis plusieurs serveurs pour augmenter les performances.
* Failover : système de secours.
Il y a deux types de réplication :
* Asynchrone (master/slave).
* Semi-asynchrone (réplication asynchrone plus avec un slave avant de terminer la requête).
Configurations des réplications :
* standard : master->slave
* double maître : master<->master
En Master-Master les deux hôtes sont tour à tour master et slave : le serveur A se réplique sur le serveur B qui se réplique sur le serveur A. Il n'y a pas de vérification de consistance des données, même si auto_increment_increment/auto_increment_offset est configuré les deux serveurs ne doivent pas être utilisés pour des accès concurrents.

## Réplication asynchrone

C'est le cas le plus simple, un master écrit un fichier de log binaire, et les slaves peuvent lire ce dernier (potentiellement sélectivement) pour rejouer les commandes de la requête.
Étant asynchrone, le master et les slaves peuvent avoir différents états au même moment. Cette configuration peut résister aux coupures réseau.

### Configuration du master

Dans /etc/mysql/my.cnf, section [mysqld] :
* Définir un identifiant de serveur ; par exemple 1 :
* La réplication est basée sur les logs binaires, donc les activer :
Créer un nouvel utilisateur pour que le slave puisse se connecter :
Vérifier l'identifiant de serveur :

### Configuration de chaque slave

Dans /etc/mysql/my.cnf, section [mysqld] :
* Définir un identifiant de serveur différent du master et des autres slaves :
* Vérifier avec :
* Il est aussi possible de déclarer le nom de la machine slave dans le master (cf. SHOW SLAVE HOSTS) :
Déclarer le master :
Si la réplication sert de backup, spécifier le point de départ :
Démarrer la réplication :
Cela va créer un fichier master.info, typiquement dans /var/lib/mysql/master.info ; contenant la configuration et le statut.

### Vérifier la réplication
#### Sur le slave

Ou bien pour avoir un résultat formaté plus lisible :
Exemple :
Vérifier en particulier :
On peut supposer une nature réplication asynchrone :
Voir aussi :

#### Sur le master

Vérifier les connexions des slaves :

### Consistance

La réplication est une simple copie, similaire aux sorties mysqldump dans le client mysql.
par conséquent, pour maintenir cette consistance :
* Ne pas écrire sur le slave ;
* Démarrer la réplication avec des données initiales identiques sur le master et le slave ;
* Utiliser les mêmes versions de MySQL sur eux peut aider.

### Réparer

Par défaut, la réplication stoppe en cas d'erreur (provenant du réseau ou d'une requête).
Dans ce cas, regarder la trace dans le log (généralement /var/log/syslog) :
La meilleure façon et de relancer la réplication entièrement.
On peut aussi tenter de réparer, par exemple faire sauter à MySQL la commande 1 :
Attention en définissant ce nombre car il contient toutes les commandes, pas seulement les erreurs.
Une autre façon est d'utiliser les outils Maatkit :
* mk-slave-restart (pour relancer la réplication du slave si SQL_SLAVE_SKIP_COUNTER ne peut pas aider)
* mk-table-checksum (pour faire un checksum des tables sur le master et le slave)
* mk-table-sync (pour synchroniser le slave avec le master basé sur des statistiques générés par mk-table-checksum).

### Désinstaller

Pour supprimer une réplication :
* MySQL met le slave en pause et remplace la configuration avec les valeurs par défaut. master.info est effacé.
* Relancer MySQL pour effacer toute la configuration.
Attention : STOP SLAVE arrêt la réplication. Elle peut être relancée manuellement ensuite, ou bien automatiquement lors de la relance du serveur MySQL. Pour éviter ce lancement automatique :
Pour arrêter d'utiliser la réplication, vérifier que la configuration est bien vide :

## Hints SQL

Avant chaque requête, des indications concernant la réplication peuvent être placées en commentaire. Par exemple via le plugin Mysqlnd de PHP.
* MYSQLND_MS_MASTER_SWITCH : force la requête sur le master.
* MYSQLND_MS_SLAVE_SWITCH : force la requête sur l'esclave.
* MYSQLND_MS_LAST_USED_SWITCH: force la requête sur le dernier serveur utilisé.

## Tables fédérées

Sur MySQL 8 et sur MariaDB depuis la version 10.0, une alternative à la réplication et au clustering existe. Il s'agit du moteur de stockage Federated, qui permet de créer une table sur un serveur qui se synchronisent avec la même sur un autre.

### CREATE SERVER

Pour éviter de définir le mot de passe du serveur distant dans la requête SQL, on peut utiliser :
Ces serveurs sont stockés dans :
Pour en supprimer un :

## Partitionnement

Pour optimiser les performances, il est possible de découper les tables en plusieurs partitions selon une clé définie lors de la création de la table.
En MySQL, il existe :
* PARTITION BY RANGE
* PARTITION BY LIST
* PARTITION BY HASH
* PARTITION BY KEY

## Références

* ↑ https://dev.mysql.com/doc/connectors/en/apis-php-mysqlnd-ms.quickstart.sqlhints.html
* ↑ https://dev.mysql.com/doc/refman/8.0/en/federated-create-server.html
* ↑ https://mariadb.com/kb/en/federated-storage-engine/
* ↑ https://dev.mysql.com/doc/refman/8.0/en/partitioning.html