Eine Fallstudie zur Unterbrechung der MySQL-Verbindung, die durch eine Überlastung des TCP-Cache verursacht wird

Wie lässt sich die Möglichkeit analysieren, neben MySQL selbst auch auf andere Faktoren abzuzielen?

Autor: Gong Tangjie, Mitglied des ACOS DBA-Teams, ist hauptsächlich für den technischen Support von MySQL verantwortlich und beherrscht MySQL, PG und inländische Datenbanken.

Der von der Aikeson-Open-Source-Community erstellte Originalinhalt darf nicht ohne Genehmigung verwendet werden. Bitte wenden Sie sich an den Herausgeber und geben Sie die Quelle für den Nachdruck an.

Dieser Artikel umfasst etwa 1.200 Wörter und die Lektüre dauert voraussichtlich 3 Minuten.

Hintergrund

Während der Ausführung von Batch-Aufgaben ist in der Anwendung ein Problem aufgetreten: Die Datenbankverbindung für einige Aufgaben ging plötzlich verloren, was dazu führte, dass die Aufgabe nicht abgeschlossen werden konnte. Im Fehlerprotokoll der Datenbank wurden Informationen zum Verbindungsabbruch gefunden, die darauf hinweisen, dass die Kommunikation zwischen dem Client und dem Server ungewöhnlich unterbrochen wurde.

analysieren

Um die Ursache des Problems herauszufinden, haben wir zunächst erfahrungsgemäß einige häufige Situationen analysiert, die zu einem Verbindungsabbruch führen können:

  1. Der Client hat die Verbindung nicht ordnungsgemäß geschlossen und die Funktion nicht aufgerufen mysql_close().
  2. Wenn die Leerlaufzeit des Clients wait_timeoutdie interactive_timeoutSekunden des Parameters oder überschreitet, trennt der Server automatisch die Verbindung.
  3. Die Größe des vom Client gesendeten oder empfangenen Pakets überschreitet max_allowed_packetden Wert des Parameters, was zu einer Unterbrechung der Verbindung führt.
  4. Der Client hat versucht, auf die Datenbank zuzugreifen, hatte aber keine Berechtigung, oder es wurde das falsche Passwort verwendet oder das Verbindungspaket enthielt nicht die richtigen Informationen.

Nach einer Untersuchung wurde jedoch festgestellt, dass keine der oben genannten Situationen auf das aktuelle Problem zutrifft. Da die Aufgaben vorher normal liefen und sich das Programm nicht verändert hat, kann die erste Situation ausgeschlossen werden. Ich habe die Timeout-Parameter von MySQL überprüft wait_timeoutund interactive_timeoutfestgestellt, dass beide 28800 sind, was 8 Stunden entspricht und die Ausführungszeit der Aufgabe bei weitem überschreitet, sodass die zweite Situation ausgeschlossen werden kann. Ich habe auch max_allowed_packetdie Parameter des Clients und des Servers überprüft und festgestellt, dass beide 64 MB groß sind und diese Grenze wahrscheinlich nicht überschreiten werden, sodass die dritte Situation ausgeschlossen werden kann. Wir haben außerdem bestätigt, dass die Datenbankzugriffsrechte, das Passwort, das Verbindungspaket und andere Informationen des Kunden korrekt sind, sodass die vierte Situation ausgeschlossen werden kann.

Zu diesem Zeitpunkt sind wir zunächst der Meinung, dass es auf MySQL-Ebene kein Problem geben sollte und das Problem woanders liegen könnte.

Um das Problem weiter zu lokalisieren, haben wir versucht, einige relevante Kernel-Parameter des Servers wie folgt zu ändern:

net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 120
net.core.rmem_default = 2097152
net.core.wmem_default = 2097152
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 16384

Diese Parameter dienen hauptsächlich dazu, die Leistung und Stabilität der Netzwerkverbindung zu optimieren und zu verhindern, dass die Verbindung unerwartet geschlossen wird oder eine Zeitüberschreitung auftritt. Die geänderten Ergebnisse haben sich jedoch nicht verbessert und die Verbindung wird weiterhin abnormal unterbrochen.

Schließlich haben wir eine Paketerfassungsanalyse mit dem Wireshark- Tool durchgeführt und dabei ein ungewöhnliches Phänomen entdeckt: Der Server sendete eine große Anzahl von ACK-Paketen an den Client. Wie nachfolgend dargestellt:

Diese ACK-Pakete sind Bestätigungspakete im TCP-Protokoll, die anzeigen, dass der Server das Datenpaket des Clients empfangen hat und den Client auffordert, mit dem Senden von Daten fortzufahren. Aber warum sendet der Server so viele ACK-Pakete? Wir spekulieren, dass möglicherweise eine Anomalie im Netzwerk vorliegt, die dazu führt, dass der Client das vom Server zurückgegebene ACK-Paket nicht empfängt, sodass der Server wiederholt ACK-Pakete sendet, bis eine Zeitüberschreitung auftritt oder eine Antwort vom Client erhält. Nach einer Untersuchung durch das Netzwerkpersonal wurden jedoch keine offensichtlichen Probleme festgestellt.

Als wir die Paketerfassung weiter analysierten, entdeckten wir ein weiteres ungewöhnliches Phänomen: Der Client sendet einige Fensterwarnungen an den sendenden Server. Wie nachfolgend dargestellt:

Bei diesen Fensterwarnungen handelt es sich um einen Flusskontrollmechanismus im TCP-Protokoll, der anzeigt, dass das Empfangsfenster des Servers oder Clients voll ist und keine weiteren Daten empfangen kann.

[TCP Window Full] ist eine vom Sender an den Empfänger gesendete Fensterwarnung, die darauf hinweist, dass das Limit des Datenempfängers erreicht wurde.

[TCP ZeroWindow] ist eine Fensterwarnung, die vom empfangenden Ende an das sendende Ende gesendet wird und dem Absender mitteilt, dass das Empfangsfenster des empfangenden Endes voll ist und das Senden vorübergehend stoppt.

Basierend auf den oben genannten Informationen vermuten wir, dass die Ursache des Problems folgende ist: Da die Daten, die MySQL senden muss, zu groß sind, ist der TCP-Cache des Clients voll und muss warten, bis der Client die Daten im TCP verdaut Cache, bevor er weiterhin Daten empfangen kann. Während dieser Zeit fordert MySQL den Client jedoch weiterhin auf, weiterhin Daten zu senden. Wenn der Client nicht innerhalb einer bestimmten Zeitspanne (Standard ist 60 Sekunden) antwortet, geht MySQL davon aus, dass das Senden von Daten abgelaufen ist, und unterbricht die Verbindung.

Um die Spekulation zu überprüfen, habe ich das langsame MySQL-Protokoll überprüft und viele Last_errno: 1161- Datensätze gefunden.

Diese Aufzeichnungen weisen darauf hin, dass MySQL beim Senden von Daten auf einen Timeout-Fehler gestoßen ist und die Anzahl der Vorkommnisse sehr nahe an der Anzahl der fehlgeschlagenen Anwendungsaufgaben liegt. Laut der offiziellen MySQL-Website hat dieser Fehler folgende Bedeutung:

Fehlernummer: 1161; Symbol: ER_NET_WRITE_INTERRUPTED; SQLSTATE: 08S01

Meldung: Zeitüberschreitung beim Schreiben von Kommunikationspaketen

Es ist ersichtlich, dass dies bedeutet, dass das Schreiben im Netzwerk unterbrochen wird, und es gibt einen Parameter auf MySQL-Ebene, um dies zu steuern. Versuchen Sie daher, den Parameter net_write_timeout auf 600 zu ändern, damit die Batch-Aufgabe normal ausgeführt wird.

Der Grund für die abnormale Unterbrechung der MySQL-Verbindung liegt darin, dass die vom Client erhaltene Datenbank zu groß ist und den TCP-Cache des Clients überschreitet. Während dieser Zeit muss MySQL weiterhin Daten anfordern Der Client sendete weiterhin Daten, reagierte jedoch nicht innerhalb von 60 Sekunden, was dazu führte, dass MySQL das Senden von Daten beendete und die Verbindung unterbrach.

abschließend

Durch die obige Analyse und Versuche sind wir zu folgenden Schlussfolgerungen gelangt:

  • In den Paketerfassungsinformationen gibt es viele ACK-Informationen, da der Cache des Clients voll ist und nicht rechtzeitig eine Rückmeldung an den Server senden kann. Daher sendet der Server wiederholt ACK-Informationen, bis mehr als 60 Sekunden vergangen sind ( net_write_timeoutder Standardwert ist 60), was zu Problemen führt MySQL soll die Verbindung unterbrechen.
  • Im langsamen Protokoll gibt es viele Last_errno: 1161- Datensätze, da SQL tatsächlich in MySQL ausgeführt wurde, aber beim Senden von Daten an den Client die Datenmenge den TCP-Cache des Clients übersteigt und der Client die Anwendung nicht verarbeitet hat Daten im Cache innerhalb von 60 Sekunden, was dazu führt, dass MySQL beim Senden von Daten an den Client eine Zeitüberschreitung erleidet.
  • Das Anpassen von net_write_timeoutParametern auf MySQL-Ebene kann dieses Phänomen nur lindern. Die Ursache liegt darin, dass die von einem einzelnen SQL erhaltene Datenmenge zu groß ist und die Cache-Größe des Clients überschreitet. Die Anwendung kann die Daten im Cache nicht in kurzer Zeit verarbeiten. Dies führt dazu, dass das nachfolgende Senden von Daten eine Zeitüberschreitung erfährt.

Optimierungsvorschläge

  • Die Daten werden auf Geschäftsebene stapelweise verarbeitet, um zu vermeiden, dass eine einzelne SQL-Abfrage eine große Datenmenge vom Server erhält, was zu einem unzureichenden TCP-Cache auf der Clientseite führt.
  • Das Erhöhen der Parameter in MySQL net_write_timeoutoder das Erhöhen des TCP-Cache des Clients kann diese Situation lindern, das Problem jedoch nicht vollständig lösen, da zu viele Daten immer noch die Leistung und Stabilität beeinträchtigen.
  • Optimieren Sie SQL-Anweisungen, um unnötige Datenrückgaben zu reduzieren, z. B. durch die Verwendung von LIMIT, WHERE und anderen Bedingungen oder durch die Verwendung von Aggregatfunktionen, Gruppierungsfunktionen usw., um die Datenmenge zu reduzieren und die Abfrageeffizienz zu verbessern.

Weitere technische Artikel finden Sie unter: https://opensource.actionsky.com/

Über SQLE

SQLE ist eine umfassende SQL-Qualitätsmanagementplattform, die die SQL-Prüfung und -Verwaltung von der Entwicklung bis zur Produktionsumgebung abdeckt. Es unterstützt gängige Open-Source-, kommerzielle und inländische Datenbanken, bietet Prozessautomatisierungsfunktionen für Entwicklung, Betrieb und Wartung, verbessert die Online-Effizienz und verbessert die Datenqualität.

SQLE erhalten

Typ Adresse
Repository https://github.com/actiontech/sqle
dokumentieren https://actiontech.github.io/sqle-docs/
Neuigkeiten veröffentlichen https://github.com/actiontech/sqle/releases
Entwicklungsdokumentation für das Datenaudit-Plug-in https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Linus nahm die Sache selbst in die Hand, um zu verhindern, dass Kernel-Entwickler Tabulatoren durch Leerzeichen ersetzen. Sein Vater ist einer der wenigen Führungskräfte, die Code schreiben können, sein zweiter Sohn ist Direktor der Open-Source-Technologieabteilung und sein jüngster Sohn ist ein Kern Mitwirkender bei Open Source: Es dauerte ein Jahr, 5.000 häufig verwendete mobile Anwendungen zu konvertieren. Java ist die Sprache, die am anfälligsten für Schwachstellen von Drittanbietern ist. Wang Chenglu, der Vater von Hongmeng: Open Source Hongmeng ist die einzige architektonische Innovation im Bereich der Basissoftware in China. Ma Huateng und Zhou Hongyi geben sich die Hand, um „den Groll zu beseitigen.“ Ehemaliger Microsoft-Entwickler: Die Leistung von Windows 11 ist „lächerlich schlecht“. sind sehr herzerwärmend . Meta Llama 3 wird offiziell veröffentlicht
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/actiontechoss/blog/11054532
Empfohlen
Rangfolge