7 Stimmen

Aufspüren von MySQL-Verbindungslecks

Ich habe einen Anwendungsserver (Jetty 6 auf einem Linux-Rechner), auf dem 15 einzelne Anwendungen (einzelne War's) laufen. Alle 3 oder 4 Tage erhalte ich von Nagios eine Meldung über die Anzahl der offenen TCP-Verbindungen. Bei der Überprüfung stelle ich fest, dass die überwiegende Mehrheit dieser Verbindungen zum MySQL-Server geht.

netstat -ntu | grep TIME_WAIT

Zeigt mehr als 10.000 Verbindungen auf dem MySQL-Server vom Anwendungsserver aus an (der Status ist TIME_WAIT). Wenn ich Jetty neu starte, sinken die Verbindungen auf fast Null.

Einige interessante Werte aus einem Show-Status:

mysql> show status;
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| Aborted_clients          | 244       |
| Aborted_connects         | 695853860 |
| Connections              | 697203154 |
| Max_used_connections     | 77        |
+--------------------------+-----------+

Ein "show processlist" zeigt nichts Ungewöhnliches an (was ich auch erwarten würde, da die meisten Verbindungen im Leerlauf sind - denken Sie an den TIME_WAIT-Status von oben).

Ich habe eine TEST-Umgebung für diesen Server, aber es gibt nie irgendwelche Probleme. Es bekommt offensichtlich nicht viel Verkehr und der Anwendungsserver wird ständig neu gestartet, so dass die Fehlersuche dort nicht viel Hilfe ist. Ich schätze, ich könnte in jeder einzelnen Anwendung graben und einen Lasttest schreiben, der den Datenbankcode treffen würde, aber dies würde eine Menge Zeit / Ärger nehmen.

Haben Sie eine Idee, wie ich die Anwendung ausfindig machen kann, die all diese Verbindungen aufnimmt und nicht mehr loslässt?

5voto

jckdnk111 Punkte 2110

Die Antwort scheint zu sein, die folgenden Einträge in my.cnf unter [mysqld] hinzuzufügen :

wait_timeout=60
interactive_timeout=60

Ich habe sie hier gefunden (ganz unten): http://community.livejournal.com/mysql/82879.html

Die Standardwartezeit zum Beenden einer veralteten Verbindung beträgt 22800 Sekunden. Zum Überprüfen:

mysql> show variables like 'wait_%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 60    |
+---------------+-------+

EDIT: Ich vergaß zu erwähnen, dass ich auch das Folgende zu meiner /etc/sysctl.conf hinzugefügt habe:

net.ipv4.tcp_fin_timeout = 15

Dies soll dazu beitragen, den Schwellenwert zu senken, den das Betriebssystem abwartet, bevor es Verbindungsressourcen wiederverwendet.

EDIT 2: /etc/init.d/mysql reload wird die my.cnf nicht wirklich neu laden (siehe den Link unten)

3voto

Steve B. Punkte 52372

Möglicherweise sind die Verbindungspools falsch konfiguriert, um zu viele Verbindungen zu halten, und sie halten zu viele untätige Prozesse.

Abgesehen davon kann ich mir nur vorstellen, dass ein Teil des Codes eine Ergebnismenge festhält, aber das scheint weniger wahrscheinlich. Um herauszufinden, ob es sich um eine langsame Abfrage handelt, können Sie MySQL auch so einstellen, dass er in ein Slow-Query-Log in der Conf-Datei schreibt, und er schreibt dann alle Abfragen auf, die länger als X Sekunden dauern, Standard ist 10 Sekunden.

0voto

Noufal Ibrahim Punkte 68934

Nun, eine Sache, die mir in den Sinn kommt (obwohl ich kein Experte auf diesem Gebiet bin), ist, die Protokollierung von mySQL zu erhöhen und alle Verbindungs-/Schließungsmeldungen aufzuspüren. Wenn das nicht funktioniert, können Sie einen winzigen Proxy schreiben, der zwischen dem eigentlichen mySQL-Server und Ihrer Anwendungssuite sitzt und die zusätzliche Protokollierung vornimmt, so dass Sie wissen, wer sich verbindet/verlässt.

0voto

Phil Wallach Punkte 3308

SHOW PROCESSLIST zeigt den Benutzer, den Host und die Datenbank für jeden Thread an. Sofern nicht alle Ihre 15 Anwendungen die gleiche Kombination verwenden, sollten Sie anhand dieser Informationen eine Unterscheidung treffen können.

0voto

lepix Punkte 4912

Ich hatte das gleiche Problem mit +30.000 TIME_WAIT auf meinem Client-Server. Ich habe das Problem behoben, indem ich in /etc/sysctl.conf :

net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_tw_recycle = 1 
net.ipv4.tcp_fin_timeout = 30 

Dann :

/sbin/sysctl -p

Nach 2 oder 3 Minuten gingen die TIME_WAIT-Verbindungen von 30 000 auf 7 000 zurück.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X