Maison > Article > Tutoriel système > Analyser les scénarios d'utilisation de la synchronisation maître-esclave mysql et asynchrone
La raison de mener des recherches sur ce contenu est principalement de répondre à deux doutes sans réponse rencontrés auparavant :
a. Il existe un système en ligne. L'état semi-synchrone passe souvent de semi-synchrone à asynchrone, puis revient immédiatement à semi-synchrone. La raison spécifique est inconnue. Bien que je l'ai déjà deviné, je n'en suis toujours pas complètement sûr.
b. Il y a quelque temps, en raison des exigences du scénario commercial, nous avons effectué un test de réplication asynchrone entre salles de machines. Lorsque le qps d'écriture MySQL est très élevé, on constate que de nombreux journaux n'ont pas eu le temps d'être envoyés à la bibliothèque esclave. C'est-à-dire que la vitesse de génération des journaux binlog dans la bibliothèque principale est supérieure à la vitesse de transmission vers la bibliothèque esclave. Cette différence de vitesse existe toujours, donc lorsque la bibliothèque principale continue d'être élevée. Lorsque le binlog était généré sous pression, de plus en plus de binlogs n'étaient pas transmis à la bibliothèque esclave, mais le trafic réseau à ce moment-là n'était qu'environ 18 M/S ( un maître, un esclave). Selon les connaissances conventionnelles, la vitesse de transmission du réseau Gigabit peut atteindre 100 M, mais la vitesse de transmission actuelle entre le maître et l'esclave n'atteint qu'environ 18 M. Quelle en est la raison ? Est-ce un problème de réseau ? Ou pour d'autres raisons.
Principe de réplication maître-esclave Dump thread et io threadLorsque la relation de réplication maître-esclave est établie, il existe un thread de vidage sur la bibliothèque maître, qui est utilisé pour transmettre le journal binlog généré dans la bibliothèque maître, et le thread io sur la bibliothèque esclave est utilisé pour recevoir les données envoyées. par le thread de vidage vers la bibliothèque esclave via le journal binlog du réseau, et est responsable de son écriture dans le journal de relais. Il s'agit du mécanisme de réplication maître-esclave. En même temps, comme il s'agit d'une réplication asynchrone, le processus de transmission ne nécessite pas de confirmation d'accusé de réception.
La question se pose également ici : comme il s'agit d'une transmission asynchrone, si elle est simplement comprise comme une transmission réseau directe des fichiers binlog, la vitesse devrait être très rapide, mais la situation réelle : dans notre environnement de test, la vitesse de transmission des journaux binlog est seulement 18 M/s, ce qui est inférieur à la vitesse d'environ 22 M/s générée par le journal. Pourquoi n'utilise-t-il que cette vitesse et n'utilise-t-il pas pleinement la bande passante du réseau ? quelle est la raison?
Détails de livraison du journalDans la structure de réplication maître-esclave, il y a un thread de vidage sur la bibliothèque maître et un thread io sur la bibliothèque esclave, il n'y a donc pas d'envoi et de réception simultanés de plusieurs threads. Il vous suffit de comprendre le mécanisme de fonctionnement du binlog. dump thread pour comprendre tous les détails.
En analysant le fichier binlog, nous pouvons savoir qu'une transaction peut contenir plusieurs événements. Voici les informations enregistrées dans le binlog de la chose la plus simple :
# at 33580 #170531 17:22:53 server id 153443358 end_log_pos 33645 CRC32 0x4ea17869 GTID last_committed=125 sequence_number=126 SET @@SESSION.GTID_NEXT= ‘e1028e43-4123-11e7-a3c2-005056aa17e6:198’/*!*/; # at 33645 #170531 17:22:53 server id 153443358 end_log_pos 33717 CRC32 0x66820e00 Query thread_id=4 exec_time=0 error_code=0 SET TIMESTAMP=1496222573/*!*/; BEGIN /*!*/; # at 33717 #170531 17:22:53 server id 153443358 end_log_pos 33770 CRC32 0x22ddf25e Table_map: `test`.`xcytest` mapped to number 222 # at 33770 #170531 17:22:53 server id 153443358 end_log_pos 33817 CRC32 0x61051ea0 Write_rows: table id 222 flags: STMT_END_F BINLOG ‘ bYsuWRMeXCUJNQAAAOqDAAAAAN4AAAAAAAEABHRlc3QAB3hjeXRlc3QAAgMPAlgCAl7y3SI= bYsuWR4eXCUJLwAAABmEAAAAAN4AAAAAAAEAAgAC//x9AAAABQBzZGZhc6AeBWE= ‘/*!*/; ### INSERT INTO `test`.`xcytest` ### SET ### @1=125 /* INT meta=0 nullable=0 is_null=0 */ ### @2=’sdfas’ /* VARSTRING(600) meta=600 nullable=1 is_null=0 */ # at 33817 #170531 17:22:53 server id 153443358 end_log_pos 33848 CRC32 0x630805b4 Xid = 303 COMMIT/*!*/;
Chaque segment xxxxx est un événement.
La fonction Binlog_sender::send_events est la fonction qui envoie des événements événementiels dans binlog:
Paramètres de fonction :end_pos, la position finale du fichier binlog actuellement lu.
log_cache, l'enregistrement contient les informations du journal actuellement transmis, y compris l'emplacement du journal binlog qui a été transmis et le fichier journal binlog.
Analyse logique des fonctions :Si la position log_pos actuellement envoyée est inférieure à la position finale end_pos du fichier obtenu, cela indique qu'il y a encore des journaux binlog qui n'ont pas été envoyés et la boucle est entrée.
Circulation dans le corps :
a. Appelez d'abord la fonction read_event pour obtenir un événement.
b. Log_event_type event_type= (Log_event_type)event_ptr[EVENT_TYPE_OFFSET];
Cette instruction est utilisée pour obtenir le type d'événement puis effectuer une vérification de type
check_event_type(event_type, log_file, log_pos), si la vérification n'est pas réussie, 1 sera renvoyé directement à la fonction supérieure.
c.log_pos= my_b_tell(log_cache); Mettre à jour la position log_pos, c'est-à-dire déplacer le curseur qui lit la position binlog vers la position actuelle.
d. Appelez ensuite la fonction send_packet() pour envoyer binlog.
Il s'avère que quel que soit le nombre de binlogs actuellement non synchronisés avec la bibliothèque esclave, la granularité de la bibliothèque principale qui envoie les binlogs envoie toujours les événements un par un. Avant l'envoi, le type de l'événement doit être vérifié. Comme il est envoyé par petits paquets, le trafic réseau n’est pas important.
Mais nous devons expliquer les conditions préalables à ce phénomène : dans notre environnement de test, les qps d'écriture de la base de données atteignaient à ce moment-là plus de 50 000, donc il y avait beaucoup d'événements qui devaient être envoyés même si c'était asynchrone, le thread de vidage à thread unique n'a pas eu le temps d'envoyer le journal des événements générés en cours.
Lorsque les qps écrits sont énormes, il peut arriver qu'il soit trop tard pour envoyer le journal.
RésuméRegardons maintenant les problèmes rencontrés en ligne : « L'état de synchronisation passe souvent d'un état semi-synchrone à un état asynchrone, puis est restauré à un état semi-synchrone dans le temps. un système d'analyse et effectue parfois des mises à jour et des importations par lots. Dans le même temps, le format du journal binaire défini par la base de données est en mode ligne. Pour une transaction qui met à jour plusieurs lignes, elle contient de nombreux événements (une ligne est un événement), donc l'envoi du journal binaire de cette transaction prendra beaucoup de temps et ne pourra pas être effectué. être envoyé dans un délai d'une seconde Terminé (le délai d'attente de semi-synchronisation est défini sur 1), de sorte que l'état de semi-synchronisation devient asynchrone.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!