Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Langsame MySQL-Startzeit im GTID-Modus? Die Größe der binären Protokolldatei kann das Problem sein

Haben Sie langsame MySQL-Startzeiten im GTID-Modus erlebt? Wir sind kürzlich bei einer unserer MySQL-Hosting-Bereitstellungen auf dieses Problem gestoßen und haben uns daran gemacht, das Problem zu lösen. In diesem Blog erläutern wir das Problem, das Ihre MySQL-Neustartzeiten verlangsamen könnte, wie Sie Fehler in Ihrer Bereitstellung beheben und was Sie tun können, um Ihre Startzeit zu verkürzen und Ihr Verständnis der GTID-basierten Replikation zu verbessern.

Wie wir das Problem gefunden haben

Wir untersuchten langsame MySQL-Startzeiten bei einer plattenbasierten Low-End-Installation von MySQL 5.7.21, bei der der GTID-Modus aktiviert war. Das System war Teil eines Master-Slave-Paares und war einer mäßigen Schreiblast ausgesetzt. Beim Neustart während einer geplanten Wartung stellten wir fest, dass der Datenbankserver 5-10 Minuten brauchte, um hochzufahren und Verbindungen zu akzeptieren. Diese Art von Verzögerung ergab keinen Sinn, also haben wir uns auf die Suche gemacht.

Debuggen Ihrer langsamen MySQL-Startzeit

Wir haben das beliebte Percona-Tool pt-ioprofile verwendet, um zu sehen, was die Datenbank macht. pt-ioprofile ist ein sehr wichtiges Dienstprogramm im beliebten Toolkit von Percona, das zum Debuggen von MySQL-Problemen verwendet wird, und Sie können die vollständige Liste der Funktionen in ihrer Dokumentation einsehen. Das pt-ioprofile Werkzeug verwendet strace und lsof um die E/A eines Prozesses zu beobachten und eine Tabelle mit Dateien und E/A-Aktivitäten auszudrucken.

Also starteten wir MySQL, warteten auf mysqld Prozess, um gespawnt zu werden, und pt-ioprofile gestartet um zu sehen, was das Problem sein könnte:

# pt-ioprofile --profile-process mysqld --run-time 200
Tue Oct 9 15:42:24 UTC 2018
Tracing process ID 18677
total      pread       read     pwrite      write      fsync  fdatasync       open      close   getdents      lseek      fcntl filename
...
216.550641   0.000000  216.550565   0.000000   0.000000   0.000000   0.000000   0.000015   0.000040   0.000000   0.000021   0.000000 /mysql_data/binlogs/mysql-bin.000014
...

Was verlangsamt Ihren MySQL-Neustart?

Bei mehrmaliger Ausführung haben wir Folgendes beobachtet:

  • Der mysqld Der Prozess verbrachte die meiste Zeit damit, die neueste Binärlogdatei zu lesen. Dies war auch dann der Fall, wenn der Server ordnungsgemäß beendet wurde und keine Wiederherstellung nach einem Absturz usw. erforderlich war.
  • Der Server verbrachte auch viel Zeit damit, die InnoDB-Datendateien zu laden, aber diese Zeit war viel kürzer im Vergleich zu der Zeit, die zum Lesen der neuesten Binärlogdatei aufgewendet wurde.
  • Wenn der Server sofort neu gestartet würde, wäre dieser nachfolgende Neustart viel schneller.
  • Da das Herunterfahren der Datenbank das Binärlog löscht und beim Start ein neues erstellt, haben wir ein zusätzliches Experiment durchgeführt – vor dem Herunterfahren des Servers haben wir die Binärlogs geleert. Der anschließende Serverstart war wieder flott.

Diese Beobachtungen wiesen eindeutig darauf hin, dass MySQL viel Zeit damit verbrachte, die neueste Binärlogdatei zu lesen. Wenn die Datei klein war, wie es beim Leeren der Protokolldatei vor einem Herunterfahren der Fall wäre, war der Start schnell.

Langsame MySQL-Startzeit in GTID? Die Größe Ihrer binären Protokolldatei kann das Problem seinClick To Tweet

Grundlegendes zur Binlog-GTID-Wiederherstellung

Wie sich herausstellt, muss der MySQL-Server die binären Protokolldateien parsen, um die Werte von gtid_executed und gtid_purged zu füllen.

Hier ist die Zusammenfassung der Empfehlung für die MySQL 5.7-Dokumentationsmethode basierend auf einem FALSCH- oder WAHR-Lesen:

Wenn binlog_gtid_simple_recovery =FALSCH:

Zur Berechnung von gtid_executed:

  • Iterieren Sie Binärprotokolldateien ab der neuesten und stoppen Sie bei der ersten Datei mit einem Previous_gtids_log_event Eintrag.
  • Konsumiere alle GTIDs aus Previous_gtids_log_event und Gtid_log_events aus dieser binären Protokolldatei und speichern diesen GTID-Satz intern. Es wird als gtids_in_binlog. bezeichnet
  • Wert von gtid_executed wird als Vereinigung von gtids_in_binlog berechnet und die GTIDs in der mysql.gtid_executed-Tabelle .

Dieser Vorgang kann sehr zeitaufwändig sein, wenn eine große Anzahl binärer Protokolldateien ohne GTIDs vorhanden ist, die beispielsweise im gtid_mode erstellt wurden =AUS.

Ähnlich, um gtid_purged: zu berechnen

  • Iterieren Sie binäre Protokolldateien von der ältesten zur neuesten und stoppen Sie beim ersten binären Protokoll, das entweder ein nicht leeres Previous_gtids_log_event enthält (hat mindestens eine GTID) oder die mindestens ein Gtid_log_event hat .
  • Lesen Sie Previous_gtids_log_event aus dieser Datei. Berechnen Sie die interne Variable gtids_in_binlog_not_purged da dieser GTID-Satz von gtids_in_binlog. abgezogen wird
  • Wert von gtid_purged auf gtid_executed gesetzt ist , minus gtids_in_binlog_not_purged .

Das bildet also die Grundlage für unser Verständnis darüber, wie die Dinge früher in älteren Versionen funktionierten. Bestimmte Optimierungen können jedoch bei binlog_gtid_simple_recovery vorgenommen werden ist wahr. Das ist der Fall, an dem wir interessiert sind:

Wenn binlog_gtid_simple_recovery =WAHR:

(Beachten Sie, dass dies der Standard in MySQL 5.7.7 und höher ist)

  • Lesen Sie nur die ältesten und neuesten Binärlogdateien.
  • Computegtid_purged aus dem Previous_gtids_log_event oder Gtid_log_event gefunden in der ältesten binären Protokolldatei.
  • Berechnen Sie gtid_executed aus dem Previous_gtids_log_event oder Gtid_log_event gefunden in neuster binärer Protokolldatei.
  • Also nur zwei binäre Protokolldateien werden während des Serverneustarts oder beim Löschen von Binärlogs gelesen.

Also werden für die MySQL-Versionen 5.7.7 und höher während des Systemstarts immer die neuesten und die alten Binärprotokolldateien gelesen, um die GTID-Systemvariablen korrekt zu initialisieren. Das Lesen der ältesten binären Protokolldatei ist nicht so teuer, da das von MySQL gesuchte Ereignis, Previous_gtids_log_event, immer das erste Ereignis in einer binären Protokolldatei ist.

Allerdings, um gtid_executed korrekt zu berechnen , muss der Server die gesamte neueste Binärprotokolldatei lesen und alle Ereignisse in dieser Datei erfassen. So wird die Systemstartzeit direkt proportional zur Größe der letzten binären Protokolldatei .

Beachten Sie, dass die Situation noch schlimmer ist, wenn binlog_gtid_simple_recovery ist FALSE . Da dies in neueren Versionen nicht mehr die Standardoption ist, ist dies kein großes Problem.

So beheben Sie Ihre langsame Startzeit

Nachdem wir die Ursache des Problems verstanden hatten, auf das wir gestoßen sind, war die Lösung, für die wir uns entschieden haben, ziemlich offensichtlich – reduzieren Sie die Größe der binären Protokolldateien. Die Standardgröße von Binärprotokolldateien beträgt 1 GB. Es dauert einige Zeit, eine Datei dieser Größe während des Starts zu parsen, daher ist es sinnvoll, den Wert von max_binlog_size zu verringern auf einen niedrigeren Wert.

Wenn es keine Option ist, die Größe der binären Protokolldatei zu verringern, kann es hilfreich sein, die binären Protokolldateien kurz vor einem Wartungs-Shutdown des mysqld-Prozesses zu leeren um die Binlog-GTID-Wiederherstellungszeiten zu verkürzen.