...

Comprendre la cohérence de la réplication de base de données et le split-brain dans les clusters MySQL

Je montre comment Cohérence de la réplication dans les configurations MySQL et pourquoi même de petites perturbations du réseau peuvent déclencher un split-brain. J'explique de manière pratique comment la réplication, les modèles de cohérence et les mécanismes de quorum interagissent et comment je peux rapidement endiguer les scénarios d'erreur.

Points centraux

Je vais d'abord résumer les principaux garde-fous pour que tu puisses définir correctement les priorités et Risques évalue la topologie. Chaque décision concernant la topologie a une influence sur la cohérence, la latence et la récupérabilité, alors évaluez-la de manière consciente et documentée. Le quorum, la gestion de l'écriture et les règles de basculement permettent d'éviter les disputes pour le nœud actif et de maintenir la sécurité. charge d'écriture proprement canalisé.

  • Objectifs de cohérence définir clairement (RPO/RTO, Read-after-Write)
  • Topologie choisir de manière appropriée (primaire-réplique, multi-master, cluster)
  • Quorum sécuriser (majorité, troisième site, dispositif)
  • Basculement contrôler strictement (read_only, VIP/DNS, orchestration)
  • Suivi développer (lag, latence, health, alarmes)

Ces points de repère me donnent une boussole stable pour les décisions et évitent l'activisme en cas de défaillance. Ainsi, je maintiens la cohérence et je garde Disponibilité en main.

Comment fonctionne la réplication MySQL

Je réplique les écritures du Primaire sur une ou plusieurs répliques afin de pallier les pannes et de répartir les accès en lecture. Les topologies Primary-Replica centralisent les écritures, tandis que les réplicas sont responsables des lectures, des sauvegardes et des analyses. Les multi-maîtres répartissent les écritures sur plusieurs nœuds, mais exigent des règles de conflit strictes. Les clusters avec niveau de coordination couplent le niveau des données et le quorum, ce qui fait qu'un nœud ne reste actif qu'avec une majorité. Si vous souhaitez lire les variantes en détail, vous trouverez des informations sur le site Types de réplication MySQL une bonne vue d'ensemble que j'utilise comme point de départ. En fin de compte, ce qui compte, c'est que les écrits soient clairement guidés et que je contrôle consciemment les chemins de lecture, afin que la consistance ne se cache pas derrière l'image. Mise à l'échelle souffre.

Niveaux d'isolation et conception des transactions

Je planifie toujours la réplication en même temps que le Projet de transaction. MySQL utilise par défaut REPEATABLE READ : c'est robuste pour l'OLTP, mais cela génère plus rapidement des données pour les transactions longues. Lag, car de nombreuses anciennes versions sont conservées. Pour les charges de travail avec de nombreuses mises à jour ponctuelles, j'utilise en partie READ COMMITTED afin de réduire les blocages et les effets secondaires. Je veille à ce que les modifications par lots soient effectuées dans de petits fichiers, temporaire Les transactions peuvent être décomposées au lieu d'effectuer des „méga-commits“ de plusieurs minutes. Ainsi, les logs binaires restent compacts, les threads SQL de réplication ne se bloquent pas, et Décalage de réplication se construit plus lentement. De plus, j'évite les fonctions non déterministes sous forme d'état (par exemple NOW() sans fixation) si je ne veux pas Row-Based je réplique - sinon je risque des divergences.

Les modèles de cohérence expliqués de manière compréhensible

Je fais la distinction entre fort Consistance, Eventual Consistency et Read-after-Write. La cohérence forte exige un commit que plusieurs nœuds confirment avant que le client ne reçoive un message de réussite. Eventual Consistency accepte des différences de courte durée jusqu'à ce que les réplicas rattrapent leur retard. Read-after-Write garantit que l'utilisateur qui écrit lit immédiatement sa modification, même si d'autres voient encore d'anciennes données. Dans les processus critiques pour l'entreprise, je mise sur une cohérence forte ou Read-after-Write, tandis que j'utilise Eventual Consistency pour le reporting. Cet équilibre permet de limiter la latence tout en protégeant les données. Intégrité des données.

Types de réplication et latence

J'utilise la réplication asynchrone lorsque j'ai besoin d'une latence d'écriture maximale et d'un certain niveau de sécurité. RPO accepte. Le semi-synchrone réduit le risque de perte de données, mais coûte du temps par commit. Les procédures synchrones assurent une forte cohérence, mais sont sensibles à la latence du réseau et à la perte de paquets. Plus la distance entre les nœuds augmente, plus le temps d'aller-retour augmente, ce qui ralentit sensiblement les commandes synchrones. Si un retard se produit, je vérifie activement le Réplication retardée dans MySQL, J'optimise les modèles d'écriture et répartis les demandes de lecture de manière ciblée. Ainsi, je maintiens l'équilibre entre rythme et Sécurité.

Mode Comportement de commit Latence RPO Utilisation typique Risque de split brain
Asynchrone Primary confirme immédiatement Faible Plus haut Débit élevé, lectures de rapports Moyen (en cas de basculement sans guidage)
Semi-synchrone Au moins une réplique confirmée Moyens Faible Transactions critiques avec tampon de latence Plus bas (meilleur guidage possible)
Synchrone/cluster La majorité enregistre de façon permanente Plus haut Très faible Clusters avec exigences de quorum Faible (si le quorum est propre)

Format Binlog, GTIDs et crash safety

Je mise de manière cohérente sur GTIDs (gtid_mode=ON, enforce_gtid_consistency=ON) pour que le basculement se fasse sans casse-tête de position. Je gère les canaux de réplication avec auto_position=1, de sorte que les réplicas se classent eux-mêmes après une commutation. Pour le binlog, je préfère Row-Based (binlog_format=ROW), car il est déterministe et évite les conflits avec les fonctions ou le non-déterminisme. Je n'utilise plus le mixte/la déclaration que de manière ciblée.

J'assure la sécurité en cas de collision avec sync_binlog=1 et innodb_flush_log_at_trx_commit=1 si le RPO doit être pratiquement nul. Si la sensibilité à la latence est plus élevée, je choisis des compromis, mais je les documente clairement. Pour que les réplicas nettoient proprement en cas de crash, j'active relay_log_recovery et laisse log_replica_updates (anciennement log_slave_updates) pour que les cascades restent stables. Pour le débit, il faut Réplication parallèle: replica_parallel_workers (par ex. 8-32) plus binlog_transaction_dependency_tracking=WRITESET optimisent la disposition sans violation des rangées.

Split-Brain : causes et symptômes

Un split-brain se produit lorsqu'un composé se divise et que plusieurs parties en même temps écrivent. Souvent, une partition réseau ou une interconnexion défectueuse déclenche le problème. Des scripts de basculement erronés ou des règles de quorum peu claires aggravent la situation. Il existe alors deux vérités d'écriture qui ne se voient pas l'une l'autre. Des collisions d'auto-incrément, des mises à jour contradictoires et des suppressions perdues en sont la conséquence immédiate. Plus cette situation perdure, plus il sera difficile d'y remédier par la suite. Fusionner.

Scénarios de risque spécifiques à MySQL

Je vois les plus grands dangers dans les configurations maître-maître asynchrones, sans une stricte Guide. Si les deux pages sont inscriptibles et que le réseau scintille, les outils promeuvent facilement les deux en primaires. Sans offsets d'auto-incrément, les clés primaires entrent immédiatement en collision. En l'absence d'une logique de commutation VIP ou DNS, les clients écrivent en parallèle sur deux nœuds. Même les clusters avec un quorum erroné permettent aux deux côtés de continuer à écrire. Ces constellations décomposent la cohérence plus rapidement qu'une équipe ne peut s'orienter, c'est pourquoi je préconise des règles claires. Runbooks de l'information.

Stratégies pour assurer la cohérence

J'établis une règle d'écriture claire : une primaire, toutes les autres strictement read_only. Pour les commutations, j'utilise VIP ou un court DNS-TTL, de sorte que les écritures ne vont toujours que sur le nœud actif. Dans les conceptions multi-maîtres, je délimite les espaces de données par mandant, région ou espace clé. J'utilise en outre des décalages d'auto-incrément, une puissance d'idéation et des champs de version. Du côté de l'application, je respecte la lecture après l'écriture avec la stickiness de la session ou des lectures primaires ciblées. Le monitoring contrôle le lag, la latence et la santé, tandis que les alarmes signalent à temps. Ainsi, j'appuie la cohérence sur plusieurs Niveaux en même temps.

Read-after-Write dans la pratique

Je sécurise les lectures après écriture en envoyant les sessions d'écriture pendant une période définie au Primaire épingler. Sinon, je ne laisse les lectures sur les réplicas que lorsque leurs gtid_executed contient le write de l'utilisateur. En pratique, j'utilise des jetons (p. ex. le GTID de la transaction) que le chemin de lecture vérifie. En l'absence de confirmation, le read va de manière ciblée vers le primary ou attend brièvement que le replica ait rattrapé son retard. Pour les API, j'utilise des en-têtes de réponse avec „lecture-après-écriture requise“, afin que les frontaux décident en connaissance de cause s'ils souhaitent frais Forcer les données ou vivre avec des lectures éventuellement consistantes.

Gestion des stocks et conception de requêtes

Je construis le lag principalement via Discipline Query à partir de : les SELECT longs ont des limites de temps et des index appropriés, je décompose les hotspots par sharding ou par des clés alternatives. J'effectue les mises à jour/suppressions importantes par lots avec des pauses afin de ne pas submerger le binlog. Je planifie les reconstructions (par ex. ALTER TABLE) par fenêtre et si possible en ligne, afin de ne pas bloquer les threads de réplication. Au niveau de l'application, je limite les rafales d'écriture parallèles par Rate-Limiting et je lisse les pics de trafic par des files d'attente. Un petit tableau de heartbeat m'aide à mesurer le lag à la seconde près et Limites d'alerte de manière réaliste.

Quorum, interconnexion et basculement

Je conçois le Quorum de manière à ce que seule une partie avec Majorité peut écrire. Un troisième site ou un quorum device permet de séparer proprement les splits de deux. Les interconnexions redondantes réduisent le risque d'îlots isolés. Avant chaque basculement, je vérifie si l'ancienne primaire est vraiment partie ou clairement coupée. Les outils d'orchestration ne peuvent promouvoir qu'avec des blocages et des contrôles clairs. Les réplicas restent protégés contre les écritures accidentelles par read_only=ON et super_read_only=ON jusqu'à ce que je les libérer.

Orchestration, fencing et promotions sécurisées

J'utilise l'orchestration strictement en tant que Gardien de la portePromotion autorisée uniquement si l'ancienne primaire est activement défendue (par ex. VIP retiré), super_read_only=ON, (le statut de la réplique est cohérent). Mes règles comprennent

  • Choix clair du leader avec contrôle de la majorité et „no-dual-primary“-Verrouillage
  • Promotion uniquement si server_uuid clairement, read_only et que les canaux de réplication sont propres
  • Commutateur DNS/VIP uniquement après le contrôle d'intégrité et de décalage, pas avant
  • chemin de retour en arrière : En cas de doute, le système préfère rester court en lecture seule, Au lieu de prendre des risques en écrivant

Important : read_only ne protège pas des writes des SUPER-utilisateurs - c'est pourquoi j'utilise toujours super_read_only. En outre, j'isole les comptes admin pour qu'en cas de stress, aucune écriture „accidentelle“ n'atterrisse sur un réplica.

Runbooks pour les cas d'urgence

Si un split-brain se produit, j'agis immédiatement et je bloque les deux nœuds d'écriture actifs pour les nouveaux Transactions. Je fais des sauvegardes ou des snapshots récents des deux sites avant de connecter quoi que ce soit. Ensuite, je stoppe toute réplication afin que les données ne se mélangent pas davantage. Vient ensuite l'analyse : quelles tables sont concernées, quelles périodes, quelles actions des utilisateurs ? Les journaux d'audit, les horodatages et les versions me montrent l'évolution. Je définis une „source de vérité“, j'introduis les modifications de manière sélective et je redémarre la réplication. Enfin, je valide avec des contrôles d'intégrité et une surveillance étroite. Suivi.

Comparer et guérir les tableaux de données

Pour la comparaison, j'utilise des checksums, des horodatages et des Champs de version, pour détecter avec certitude les lignes divergentes. Lorsque c'est possible, je reconstruis l'ordre à partir des logs write-ahead ou des logs binaires. En cas de conflit, je décide selon des règles claires, par exemple Last-Writer-Wins ou Domain-Logik par attribut. Je remplace les domaines fortement divergents par des restaurations à partir d'un snapshot cohérent afin d'éviter les effets secondaires. Je documente chaque importation de manière exhaustive afin que les audits ultérieurs puissent retracer le chemin parcouru. Après la guérison, j'impose une réinitialisation complète des réplicas, de sorte que tous les nœuds aient des valeurs identiques. Points de départ ont.

Sauvegardes, PITR et re-ensemencement

Je combine des physique Sauvegardes avec binlogs pour la récupération ponctuelle (PITR). Les sauvegardes sont exécutées sur une réplique afin de ménager la primaire et sont régulièrement relues à titre de test. Pour un re-seeding rapide, j'utilise - là où c'est disponible - le clone/hysical-shipping et je démarre ensuite la réplication avec GTID-auto-position. J'oriente les politiques de rétention sur la conformité et les objectifs RPO ; je conserve les binlogs aussi longtemps que mon horizon PITR maximal l'exige. Ce qui est critique, c'est que les sauvegardes Consistance (InnoDB-Flush, fenêtre de démarrage Binlog correcte), sinon la restauration et la réplication divergent.

Tests, drills et SLO

Je définis clairement SLOs (par exemple, RPO ≤ 30 secondes, RTO ≤ 5 minutes pour les services critiques) et les tester régulièrement dans des drills. Les scénarios incluent les partitions réseau, les échecs de disque, les interconnexions perturbées et les réplicas en retard. Je m'entraîne aux étapes „Fence - Promote - Switch Traffic - Validate“ et je mesure la rapidité d'intervention des alertes et des runbooks. En outre, j'injecte de manière ciblée du lag (pics de trafic, latence artificielle) pour voir comment réagissent le routage, la backpressure et les mécanismes de read-after-write. Seul ce que nous répétons fonctionne en cas d'urgence fiable.

Mise à l'échelle : sharding, régions et propriété

Je sépare les responsabilités d'écriture par client, région ou Domaines, pour réduire les zones de conflit. Le sharding régional réduit la latence et permet des primaires locales avec un guidage clair. Je sers les charges de travail de lecture globales à partir de répliques, tandis que les chemins d'écriture restent strictement locaux. Pour ceux qui souhaitent combiner le sharding, voir Sharding et réplication une bonne entrée en matière. Ce qui reste important : Les règles d'appropriation doivent être intégrées dans le code, les DDL et les runbooks, et pas seulement dans les têtes. Ainsi, la mise à l'échelle reste planifiable, sans consistance contre Tempo d'échanger.

Spécificités du cloud et multirégionales

Au-delà des régions, je prévois de manière offensive la latence et les risques de partition. Écrits restent locales, la réplication interrégionale se fait de manière asynchrone avec un RPO clairement défini. Les commutations DNS ou VIP reçoivent des TTL courts, mais seulement si les contrôles de santé et de quorum sont réussis. J'évite les écritures „transparentes“ distribuées globalement sans guidage dur - elles ont l'air confortables, mais génèrent des conflits difficiles à résoudre en cas de perturbations. Pour les scénarios DR, je tiens une région froide ou chaude à disposition, je re-seede régulièrement et je teste le basculement de région comme une solution complète. Exercice d'affaires, pas seulement comme démonstration technique.

Conformité, sécurité et auditabilité

Je protège les canaux de réplication avec TLS et j'installe des least privilege pour les utilisateurs de répliques. La rétention des binlogs et les checksums font partie de la capacité d'audit, tout comme les change-logs compréhensibles dans les pipelines DDL. Le cryptage at-rest (tablespace, sauvegardes) est standard ; la rotation des clés et les contrôles d'accès sont documentés et testés. Identités du serveur (server_uuid, server_id) restent stables et uniques, afin que l'orchestration et les GTID fonctionnent de manière fiable. Tout cela n'est pas une fin en soi : des traces d'audit propres accélèrent Analyses des causes profondes et réduisent les temps d'arrêt en cas d'urgence.

Bilan rapide : la cohérence avant la vitesse

Je ne planifie jamais la réplication de manière isolée, mais en suivant des lignes directrices claires. Objectifs de cohérence et des cas d'affaires. Des règles solides pour la direction, le quorum et le basculement empêchent qu'un cluster ne se désintègre à la première perturbation. La surveillance, les tests et les exercices permettent à mon équipe d'agir quand cela compte. En cas de split-brain, j'arrête les écritures, je sécurise les niveaux, je choisis une vérité et je redémarre systématiquement. Ainsi, la réplication MySQL reste utilisable de manière fiable, sans que la cohérence des données ne cède le pas à l'envie d'avoir des données plus fiables. Performance est victime.

Derniers articles