Configurer la réplication dans MySQL est facile, mais la gérer en production n'a jamais été une tâche facile. Même avec le nouveau positionnement automatique GTID, cela peut toujours mal tourner si vous ne savez pas ce que vous faites. Après avoir configuré la réplication, toutes sortes de choses peuvent mal tourner. Des erreurs peuvent facilement être commises et avoir une fin désastreuse pour vos données.
Cet article mettra en évidence certaines des erreurs les plus courantes commises avec la réplication MySQL et comment vous pouvez les éviter.
Configuration de la réplication
Lors de la configuration de la réplication MySQL, vous devez amorcer les nœuds esclaves avec l'ensemble de données du maître. Avec des solutions comme le cluster Galera, cela est automatiquement géré pour vous avec la méthode de votre choix. Pour la réplication MySQL, vous devez le faire vous-même, donc naturellement vous prenez votre outil de sauvegarde standard.
Pour MySQL, il existe une grande variété d'outils de sauvegarde disponibles, mais le plus couramment utilisé est mysqldump. Mysqldump génère une sauvegarde logique de l'ensemble de données de votre maître. Cela signifie que la copie des données ne sera pas une copie binaire, mais un gros fichier contenant des requêtes pour recréer votre jeu de données. Dans la plupart des cas, cela devrait vous fournir une copie (presque) identique de vos données, mais il y a des cas où ce ne sera pas le cas, car le vidage se fait par objet. Cela signifie qu'avant même de commencer à répliquer les données, votre jeu de données n'est pas le même que celui du maître.
Il y a quelques ajustements que vous pouvez faire pour rendre mysqldump plus fiable comme dump en une seule transaction, et n'oubliez pas non plus d'inclure des routines et des déclencheurs :
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql
Une bonne pratique consiste à vérifier si votre nœud esclave est identique à 100 % en utilisant pt-table-checksum après avoir configuré la réplication :
pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass
Cet outil calculera une somme de contrôle pour chaque table sur le maître, répliquera la commande sur l'esclave, puis le nœud esclave effectuera la même opération de somme de contrôle. Si l'un des tableaux n'est pas le même, cela doit être clairement visible dans le tableau de somme de contrôle.
Utiliser la mauvaise méthode de réplication
La méthode de réplication par défaut de MySQL était la réplication dite basée sur les instructions. Cette méthode est exactement ce qu'elle est :un flux de réplication de chaque instruction exécutée sur le maître qui sera rejouée sur le nœud esclave. Étant donné que MySQL lui-même est multithread mais que sa réplication (traditionnelle) ne l'est pas, l'ordre des instructions dans le flux de réplication peut ne pas être identique à 100 %. De plus, la relecture d'une instruction peut donner des résultats différents lorsqu'elle n'est pas exécutée exactement au même moment.
Cela peut entraîner des ensembles de données différents entre le maître et l'esclave, en raison de la dérive des données. Ce n'était pas un problème pendant de nombreuses années, car peu d'entre eux exécutaient MySQL avec de nombreux threads simultanés, mais avec les architectures multi-processeurs modernes, cela est devenu très probable sur une charge de travail quotidienne normale.
La réponse de MySQL était la soi-disant réplication basée sur les lignes. La réplication basée sur les lignes répliquera les données dans la mesure du possible, mais dans certains cas exceptionnels, utilisera toujours des instructions. Un bon exemple serait le changement de DLL d'une table, où la réplication devrait alors copier chaque ligne de la table via la réplication. Comme cela est inefficace, une telle déclaration sera reproduite de manière traditionnelle. Lorsque la réplication basée sur les lignes détecte une dérive des données, elle arrête le thread esclave pour éviter d'aggraver les choses.
Ensuite, il existe une méthode entre les deux :la réplication en mode mixte. Ce type de réplication répliquera toujours les instructions, sauf lorsque la requête contient la fonction UUID(), des déclencheurs, des procédures stockées, des UDF et quelques autres exceptions. Le mode mixte ne résout pas le problème de la dérive des données et, avec la réplication basée sur les instructions, doit être évité.
Réplication circulaire
L'exécution de la réplication MySQL avec plusieurs maîtres est souvent nécessaire si vous disposez d'un environnement multi-centres de données. Étant donné que l'application ne peut pas attendre que le maître de l'autre centre de données reconnaisse votre écriture, un maître local est préférable. Normalement, le décalage d'incrément automatique est utilisé pour éviter les conflits de données entre les maîtres. Faire en sorte que deux maîtres effectuent des écritures l'une sur l'autre de cette manière est une solution largement acceptée.
Réplication MySQL maître-maîtreCependant, si vous devez écrire dans plusieurs centres de données dans la même base de données, vous vous retrouvez avec plusieurs maîtres qui doivent écrire leurs données les uns aux autres. Avant MySQL 5.7.6, il n'existait aucune méthode pour effectuer une réplication de type maillage, donc l'alternative serait d'utiliser une réplication en anneau circulaire à la place.
Topologie de réplication en anneau MySQLLa réplication en anneau dans MySQL est problématique pour les raisons suivantes :latence, haute disponibilité et dérive des données. En écrivant des données sur le serveur A, il faudrait trois sauts pour se retrouver sur le serveur D (via les serveurs B et C). Étant donné que la réplication MySQL (traditionnelle) est monothread, toute requête de longue durée dans la réplication peut bloquer l'ensemble de l'anneau. De plus, si l'un des serveurs tombait en panne, l'anneau serait rompu et il n'existe actuellement aucun logiciel de basculement capable de réparer les structures en anneau. Ensuite, une dérive des données peut se produire lorsque des données sont écrites sur le serveur A et sont modifiées en même temps sur le serveur C ou D.
Réplication en anneau briséEn général, la réplication circulaire ne convient pas à MySQL et doit être évitée à tout prix. Galera serait une bonne alternative pour les écritures multi-centres de données, car il a été conçu dans cet esprit.
Bloquer votre réplication avec des mises à jour volumineuses
Souvent, divers travaux de maintenance par lots effectueront diverses tâches, allant du nettoyage des anciennes données au calcul des moyennes des "j'aime" extraits d'une autre source. Cela signifie qu'à des intervalles définis, un travail créera beaucoup d'activité dans la base de données et, très probablement, réécrira beaucoup de données dans la base de données. Naturellement, cela signifie que l'activité au sein du flux de réplication augmentera également.
La réplication basée sur les instructions répliquera les requêtes exactes utilisées dans les travaux par lots, donc si la requête a pris une demi-heure à traiter sur le maître, le thread esclave sera bloqué pendant au moins la même durée. Cela signifie qu'aucune autre donnée ne peut être répliquée et que les nœuds esclaves commenceront à être en retard sur le maître. Si cela dépasse le seuil de votre outil de basculement ou proxy, il peut supprimer ces nœuds esclaves des nœuds disponibles dans le cluster. Si vous utilisez la réplication basée sur des instructions, vous pouvez éviter cela en analysant les données de votre travail en lots plus petits.
Maintenant, vous pensez peut-être que la réplication basée sur les lignes n'est pas affectée par cela, car elle répliquera les informations de ligne au lieu de la requête. C'est en partie vrai, car pour les modifications DDL, la réplication revient au format basé sur les instructions. De plus, un grand nombre d'opérations CRUD affecteront le flux de réplication :dans la plupart des cas, il s'agit toujours d'une opération à un seul thread et chaque transaction attendra donc que la précédente soit rejouée via la réplication. Cela signifie que si vous avez une forte simultanéité sur le maître, l'esclave peut se bloquer sur la surcharge de transactions lors de la réplication.
Pour contourner ce problème, MariaDB et MySQL proposent une réplication parallèle. L'implémentation peut différer selon le fournisseur et la version. MySQL 5.6 offre une réplication parallèle tant que les requêtes sont séparées par schéma. MariaDB 10.0 et MySQL 5.7 peuvent tous deux gérer la réplication parallèle entre les schémas, mais ont d'autres limites. L'exécution de requêtes via des threads esclaves parallèles peut accélérer votre flux de réplication si vous écrivez beaucoup. Cependant, si ce n'est pas le cas, il serait préférable de s'en tenir à la réplication traditionnelle à thread unique.
Modifications de schéma
Effectuer des modifications de schéma sur une configuration de production en cours d'exécution est toujours pénible. Cela est lié au fait qu'une modification DDL verrouille la plupart du temps une table et ne libère ce verrou qu'une fois la modification DDL appliquée. Cela s'aggrave encore une fois que vous commencez à répliquer ces modifications DDL via la réplication MySQL, où cela bloquera en outre le flux de réplication.
Une solution de contournement fréquemment utilisée consiste à appliquer d'abord le changement de schéma aux nœuds esclaves. Pour la réplication basée sur les instructions, cela fonctionne bien, mais pour la réplication basée sur les lignes, cela peut fonctionner jusqu'à un certain degré. La réplication basée sur les lignes permet à des colonnes supplémentaires d'exister à la fin de la table, donc tant qu'elle est capable d'écrire les premières colonnes, tout ira bien. Appliquez d'abord la modification à tous les esclaves, puis basculez vers l'un des esclaves, puis appliquez la modification au maître et attachez-le en tant qu'esclave. Si votre modification implique l'insertion d'une colonne au milieu ou la suppression d'une colonne, cela fonctionnera avec la réplication basée sur les lignes.
Il existe des outils qui peuvent effectuer des modifications de schéma en ligne de manière plus fiable. Le changement de schéma en ligne Percona (connu sous le nom de pt-osc) créera une table fantôme avec la nouvelle structure de table, insèrera de nouvelles données via des déclencheurs et remplira les données en arrière-plan. Une fois la création de la nouvelle table terminée, il remplacera simplement l'ancienne par la nouvelle table dans une transaction. Cela ne fonctionne pas dans tous les cas, surtout si votre table existante a déjà des déclencheurs.
Une alternative est le nouvel outil Gh-ost de Github. Cet outil de changement de schéma en ligne fera d'abord une copie de votre disposition de table existante, modifiera la table à la nouvelle disposition, puis connectera le processus en tant que réplique MySQL. Il utilisera le flux de réplication pour trouver de nouvelles lignes qui ont été insérées dans la table d'origine et en même temps il remplira la table. Une fois le remblayage terminé, les tables d'origine et les nouvelles basculeront. Naturellement, toutes les opérations sur la nouvelle table se retrouveront également dans le flux de réplication. Ainsi, sur chaque réplique, la migration se produit en même temps.
Tables de mémoire et réplication
Pendant que nous parlons de DDL, un problème courant est la création de tables de mémoire. Les tables mémoire sont des tables non persistantes, leur structure de table demeure mais elles perdent leurs données après un redémarrage de MySQL. Lors de la création d'une nouvelle table mémoire sur un maître et un esclave, les deux auront une table vide et cela fonctionnera parfaitement bien. Une fois l'un ou l'autre redémarré, la table sera vidée et des erreurs de réplication se produiront.
La réplication basée sur les lignes s'arrêtera une fois que les données du nœud esclave renvoient des résultats différents, et la réplication basée sur les instructions s'arrêtera une fois qu'elle tentera d'insérer des données qui existent déjà. Pour les tables de mémoire, il s'agit d'un briseur de réplication fréquent. La solution est simple :faites simplement une nouvelle copie des données, changez le moteur pour InnoDB et la réplication devrait maintenant être sécurisée.
Définition de la variable read_only sur True
Comme nous l'avons décrit précédemment, ne pas avoir les mêmes données dans les nœuds esclaves peut interrompre la réplication. Cela a souvent été causé par quelque chose (ou quelqu'un) altérant les données sur le nœud esclave, mais pas sur le nœud maître. Une fois que les données du nœud maître sont modifiées, elles seront répliquées sur l'esclave où il ne pourra pas appliquer la modification, ce qui entraînera l'interruption de la réplication.
Il existe une prévention simple pour cela :définir la variable read_only sur true. Cela empêchera quiconque d'apporter des modifications aux données, à l'exception des utilisateurs de réplication et root. La plupart des gestionnaires de basculement définissent cet indicateur automatiquement pour empêcher les utilisateurs d'écrire sur le maître utilisé pendant le basculement. Certains d'entre eux le conservent même après le basculement.
Cela laisse toujours l'utilisateur root exécuter une requête CRUD errante sur le nœud esclave. Pour éviter que cela ne se produise, il existe une variable super_read_only depuis MySQL 5.7.8 qui empêche même l'utilisateur root de mettre à jour les données.
Activation du GTID
Dans la réplication MySQL, il est essentiel de démarrer l'esclave à partir de la bonne position dans les journaux binaires. L'obtention de cette position peut être effectuée lors d'une sauvegarde (xtrabackup et mysqldump le supportent) ou lorsque vous avez arrêté l'asservissement sur un nœud dont vous faites une copie. Le démarrage de la réplication avec la commande CHANGE MASTER TO ressemblerait à ceci :
mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;
Commencer la réplication au mauvais endroit peut avoir des conséquences désastreuses :les données peuvent être écrites en double ou ne pas être mises à jour. Cela provoque une dérive des données entre le nœud maître et le nœud esclave.
De même, lorsque le basculement d'un maître vers un esclave implique de trouver la position correcte et de remplacer le maître par l'hôte approprié. MySQL ne conserve pas les journaux et les positions binaires de son maître, mais crée plutôt ses propres journaux et positions binaires. Pour réaligner un nœud esclave sur le nouveau maître, cela pourrait devenir un problème sérieux :la position exacte du maître lors du basculement doit être trouvée sur le nouveau maître, puis tous les esclaves peuvent être réalignés.
Pour résoudre ce problème, le Global Transaction Identifier (GTID) a été implémenté à la fois par Oracle et MariaDB. Les GTID permettent l'alignement automatique des esclaves, et dans MySQL et MariaDB, le serveur détermine par lui-même quelle est la position correcte. Cependant, les deux ont implémenté le GTID d'une manière différente et sont donc incompatibles. Si vous devez configurer la réplication de l'un à l'autre, la réplication doit être configurée avec un positionnement de journal binaire traditionnel. De plus, votre logiciel de basculement doit être averti de ne pas utiliser les GTID.
Conclusion
Nous espérons vous avoir donné suffisamment de conseils pour éviter les ennuis. Ce sont toutes des pratiques courantes chez les experts de MySQL. Ils ont dû l'apprendre à la dure et avec ces conseils, nous vous garantissons que vous n'aurez pas à le faire.
Nous avons quelques livres blancs supplémentaires qui pourraient vous être utiles si vous souhaitez en savoir plus sur la réplication MySQL.
Livres blancs associés MySQL Replication BlueprintLe livre blanc MySQL Replication Blueprint inclut tous les aspects d'une topologie de réplication avec les tenants et les aboutissants du déploiement, la configuration de la réplication, la surveillance, les mises à niveau, l'exécution de sauvegardes et la gestion de la haute disponibilité à l'aide de proxys.Télécharger MySQL Replication for High AvailabilityCe didacticiel couvre les informations sur la réplication MySQL, avec des informations sur les dernières fonctionnalités introduites dans les versions 5.6 et 5.7. Il existe également une section plus pratique sur la manière de déployer et de gérer rapidement une configuration de réplication à l'aide de ClusterControl.Télécharger