[Problembeschreibung] Unsere Produktionsumgebung verfügt über einen Cluster aus mehreren MySQL-Servern (MySQL 5.6.21), die von Zeit zu Zeit abstürzen. Das Fehlerprotokoll zeichnet jedoch nur die Neustartinformationen auf, nicht jedoch den Absturzstapel: mysqld_safe Anzahl der derzeit laufenden Prozesse: 0 mysqld_safe mysqld neu gestartet Überprüfen Sie als Nächstes die Systemprotokolldatei /var/log/message. Beim Absturz gibt es keine weiteren abnormalen Informationen und der Absturz wird nicht durch OOM verursacht. 【Ideen zur Fehlerbehebung】 Denn im Log werden keine wertvollen Informationen festgehalten. Um die Ursache des Absturzes zu ermitteln, aktivieren Sie zunächst die MySQL-Core-Dump-Funktion. So aktivieren Sie den Core Dump: 1. Fügen Sie der Datei my.cnf zwei Konfigurationselemente hinzu [mysqld] Kerndatei [mysqld_safe] Kerndateigröße = unbegrenzt 2. Systemparameter ändern und suid_dumpable konfigurieren echo 1 >/proc/sys/fs/suid_dumpable 3. Starten Sie den MySQL-Dienst neu und die Konfiguration wird wirksam 【Problemanalyse】 Nachdem der Core Dump aktiviert wurde, wird beim erneuten Serverabsturz eine Core-Datei generiert. Mithilfe von gdb zur Analyse der generierten Core-Datei können Sie die Stapelinformationen zum Zeitpunkt des Absturzes wie folgt anzeigen: Anhand der Funktion Wir verfügen über ein internes DML-Analysetool, mit dem die Anzahl der Datenbankzugriffe für Hinzufügungen, Löschungen, Änderungen und Abfragen pro Minute gezählt wird. Die Datenquelle dieses Tools ist die Tabelle events_statements_summary_by_digest. Das Erfassungsprogramm erfasst einmal pro Minute Daten aus dieser Tabelle und führt nach Abschluss der Erfassung einen Kürzungsvorgang aus. Nachdem das DML-Sammelprogramm auf dieser Clustergruppe angehalten wurde, stürzte MySQL nicht mehr ab. Eine weitere Analyse mehrerer Kerndateien ergab, dass die letzten Funktionsaufrufe alle bei der Funktion _lf_pinbox_real_free erfolgten. In Kombination mit der Umgebung vor Ort gibt es zwei Bereiche, die einer Analyse wert sind: 1. Abnormaler Speicherwert. Beim Drucken der Variablen ist die Adresse der Variablen hier niedrig, was nicht normal ist: (gdb) p-Pins->Pinbox $2 = (LF_PINBOX *) 0x1367208 2. Der rote Teil ist der Vorgang, bei dem PFS Digest-Datensätze nacheinander freigibt. Beim Freigeben einer Datenzeile ist ein Fehler aufgetreten: void reset_esms_by_digest() { uint-Index; wenn (statements_digest_stat_array == NULL) zurückkehren; PFS_thread *thread = PFS_thread::get_current_thread(); wenn (unwahrscheinlich(Thread == NULL)) zurückkehren; für (Index = 0; Index < Digest_max; Index++) { Anweisungen_Digest_Stat_Array[Index].Reset_Index(Thread); statements_digest_stat_array[index].reset_data(); } Digest-Index = 1; } Es gibt zwei mögliche Fehlerursachen: 1. Bei hoher Parallelität treten Konflikte beim Speicherzugriff auf. 2. Ein spezielles SQL verursacht einen Fehler bei der Hash-Verarbeitung. Die Suche nach ähnlichen Problemen im Internet hat weitere Fortschritte gebracht und im Wesentlichen bestätigt, dass dieses Problem durch einen Fehler verursacht wird. Der folgende Mysql-Fehlerbericht beschreibt ein ähnliches Problem https://bugs.mysql.com/bug.php?id=73979 Eine detailliertere Beschreibung der Umgebung finden Sie unter folgendem Link https://bugs.launchpad.net/percona-server/+bug/1351148 Es stellte sich heraus, dass der Bugfix in 5.6.35 der Situation, die wir vorgefunden haben, sehr ähnlich war. Im Vergleich zur Modifikation von _lf_pinbox_real_free wurden in diesem Teil tatsächlich größere Anpassungen vorgenommen. Hier ist ein Codeausschnitt aus der MySQL 5.6.35-Funktion _lf_pinbox_real_free: statische Leere _lf_pinbox_real_free (LF_PINS-Pins) { LF_PINBOX Pinbox = Pins->Pinbox; Struktur st_match_and_save_arg arg = {Pins, Pinbox, Pins->Fegefeuer}; Pins->Fegefeuer = NULL; Pins->Fegefeuer_Anzahl = 0; lf_dynarray_iterate(&pinbox->pinarray, (lf_dynarray_func)abgleichen_und_speichern, &arg); wenn (arg.old_purgatory) { void *last = arg.altes_Fegefeuer; während (pnext_node(Pinbox, letzte)) letzte = pnext_node(Pinbox, letzte); Pinbox->Freifunktion(arg.altes_Fegefeuer, letztes, Pinbox->Freifunktion_arg); } } Unten sehen Sie einen Codeausschnitt der MySQL 5.6.21-Funktion _lf_pinbox_real_free statisches void _lf_pinbox_real_free (LF_PINS-Pins) { npins; ungültige Liste; void **Adresse = NULL; void erster = NULL, letzter = NULL; LF_PINBOX Pinbox = Pins->Pinbox; npins= Pinbox->Pins_im_Array+1; wenn (Pins->Stack_Ends_Here != NULL) { int alloca_size = Größe von (void) LF_PINBOX_PINSnpins; wenn (verfügbare Stapelgröße(&Pinbox, *Pins->Stapel endet hier) > Zuweisungsgröße) { Struktur st_harvester hv; Adresse = (void **) alloca(alloca_size); hv.granary = Adresse; hv.npins=npins; _lf_dynarray_iterate(&pinbox->pinarray, (lf_dynarray_func)Erntestifte, &hv); npins = hv.granary-addr; wenn (npins) qsort(Adresse, nPins, Größe von(void *), (qsort_cmp)ptr_cmp); } } Gleichzeitig wurde beobachtet, dass der problematische Cluster abnormale Indikatoren aufwies, mit QPS unter 6000 und Threads_connected fast 8000. (Im Vergleich zu anderen Clustern mit hoher Parallelität liegt QPS bei über 20.000 und Threads_connected bei nur etwa 300). Nachdem wir die Verbindungsmethode auf der Anwendungsseite überprüft hatten, stellten wir fest, dass eine der Anwendungen fast hundert Anwendungsserver hatte, die ohne sinnvolle Wiederverwendung der Verbindung gleichzeitig Anfragen initiieren konnten. Die Aufrechterhaltung einer großen Anzahl von Verbindungsthreads erhöhte die Wahrscheinlichkeit, dass Fehler auftraten. Die Beschreibung der behobenen Fehler lautet wie folgt:
【Lösung】 Wir haben die Kerndatei zum Zeitpunkt des Absturzes analysiert, die auslösenden Bedingungen des Absturzes gefunden, das DML-Sammelprogramm angehalten (Operation „Truncate Table events_statements_summary_by_digest“) und es dann fortgesetzt. Später erfuhr ich, dass es sich dabei um einen Fehler in MySQL handelte, der in MySQL Version 5.6.35 behoben wurde. Dieser Fehler wird eher ausgelöst, wenn die Anwendung eine große Anzahl von Verbindungen zur Datenbank herstellt. Zusammenfassen Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. |
>>: Lombok-Implementierung JSR-269
Frage Kürzlich musste ich mich bei einem privaten...
Inhaltsverzeichnis Nginx-Lastausgleichskonfigurat...
Code kopieren Der Code lautet wie folgt: <div ...
Inhaltsverzeichnis Überblick CommonJS-Spezifikati...
Beim Stichwort Bionik-Design denken viele an die E...
Zusätzliche Erklärung, Fremdschlüssel: Verwenden ...
Wenn wir über den Ausnahmefilter von Nestjs sprec...
Manchmal müssen wir bei unserer tatsächlichen Arb...
1. Grund der Sperrung Es gibt viele Gründe, warum...
Inhaltsverzeichnis verwenden Installieren Wie wir...
1. Melden Sie sich mit dem IE-Browser beim VPN an...
Laden Sie zuerst JDK herunter. Hier verwenden wir...
Centos7-Switch-Boot-Kernel Hinweis: Bei Bedarf wi...
Inhaltsverzeichnis Implementierungs-Effekt-Diagra...
Es gibt einige Unterschiede zwischen Filter und H...