wie Sie feststellen können, welche PHP-Code öffnet MySQL-Verbindungen, die nicht immer geschlossen sind
-
10-07-2019 - |
Frage
Wir haben eine Anwendung, die von ein paar aus dem Regal PHP-Anwendungen (Expression und XCart) sowie unseren eigenen benutzerdefinierten Code besteht.
Ich habe nicht die eigentliche Analyse tun, damit ich weiß nicht genau, wie es bestimmt war, aber ich bin nicht überrascht zu hören, dass zu viele MySQL-Verbindungen sind nicht geschlossene gelassen wird (ich bin nicht überrascht, weil ich erhebliche Speicherlecks zu sehen war auf unserem dev-Server, wo ich im Laufe eines Tages oder zwei, von 100MB auf anfängliches Boot startet, wird der gesamte Gig rAM verbraucht, und nur sehr wenig davon ist gecached).
Also, wie gehen wir über genau, welche PHP-Code zu bestimmen ist der Schuldige? Ich habe Erfahrung mit XDebug bekam, und haben vorgeschlagen, dass, wenn wir getrennte, Staging-Umgebung einigermaßen stabil bekommen haben, dass wir XDebug auf dev nachrüsten und verwenden, die eine Analyse zu tun. Ist dies sinnvoll und / oder hat jemand anderes haben spezifischere und / oder zusätzliche Anregungen?
Lösung
Sie können mit der
SHOW PROCESSLIST
SQL-Befehl, um zu sehen, welche Prozesse ausgeführt werden. Das wird Ihnen sagen, den Benutzernamen, Host, Datenbank, etc., die von jedem Prozess verwendet werden. Das sollte Ihnen eine Idee geben, was los ist, vor allem, wenn Sie eine Reihe von Datenbanken zugegriffen wird.
Mehr hier: http://codeinthehole.com/archives/2- Monitoring-MySQL-processes.html
Andere Tipps
Dies sollte nicht durch einen PHP-Code verursacht werden, weil mysql-Verbindungen automatisch geschlossen werden sollen.
cf: http://www.php.net/manual/function .mysql-connect.php :
Die Verbindung zum Server wird geschlossen sobald die Ausführung des Skripts früher endet, es sei denn, es geschlossen ist durch expliziter Aufruf mysql_close ().
Einige Vorschläge:
- hat Ihr developper technisch einen direkten Zugriff auf Ihre Produktion MySQL-Server hat? wenn ja, dann wohl sie nur verlassen ihre Mysql-Manager offen:)
- Sie haben einig täglichen Batch-Prozess? wenn ja, vielleicht, dass es einige zombi Prozesse im Speicher
PHP schließt automatisch alle mysql-Verbindungen, wenn die Seite endet. der einzige Grund, dass eine PHP-Web-Anwendung viele unclosed mysql-Verbindungen haben würde auch entweder 1) Sie verwenden Connection Pooling, oder 2) gibt es einen Fehler in dem MySQL-Server oder den Anschluss an.
aber wenn Sie wirklich auf den Code aussehen wollen zu finden, wo es verbindet, finden Sie unter http: // xdebug. org / docs / Profiler
Wie bereits gesagt, PHP beendet MySQL Verbindungen durch mysql_connect
erstellt oder die msqli / PDO-Äquivalente.
Sie können jedoch persistente Verbindungen mit mysql_pconnect
erstellen. Es sieht für Verbindungen offen und nutzen diejenigen vorhandenen; wenn sie nicht finden kann, wird es ein neues öffnen. Wenn Sie auf einmal viele Anfragen haben, haben sie viele Verbindungen verursacht könnten öffnen und offen bleiben.
Sie können die maximale Anzahl der Verbindungen senken, oder das Timeout für persistente Verbindungen senken. Siehe die Kommentare am unteren Rand des Mann rel="nofollow Details.
Ich habe ein Skript auszuführen, das SHOW STATUS Zahl für Gewinde abgefragt und ich bemerkte, dass die Verwendung von mysql_pconnect immer eine hohe Anzahl von Threads gefördert. Ich fand, dass es sehr beunruhigend, denn dann konnte ich nicht sagen, dass meine Verbindungsrate tatsächlich tropfte. So stellte ich sicher, alle Orte zu zentralisieren, wo mysql_connect () aufgerufen wurde und beseitigen mysql_pconnect ().
Das nächste, was ich tat, war Blick auf die Verbindungs-Timeouts und stellen Sie sie mehr wie 30 Sekunden, da. So stellte ich meine my.cnf mit
connect-timeout = 30
so konnte ich die Anzahl der Verbindungen tatsächlich sehen abfallen. Um die Anzahl der Verbindungen zu bestimmen müssen Sie offen ist davon abhängig, wie viele Apache-Arbeiter sind Sie mal die Anzahl der Datenbankverbindungen laufen sie jeweils geöffnet.
dabei wurde das Hinzufügen einer Notiz auf meine Fragen, um zu erkennen, sie in SHOW PROCESS oder mytopDas andere, was ich begann, würde ich eine Notiz Spalte zu meinen Ergebnissen hinzufügen wie:
$q = "SELECT '".__FILE__.'.'.__LINE__."' as _info, * FROM table ...";
Dies würde zeigen mir die Datei die Abfrage ausgibt, wenn ich an mytop sah, und es hat nicht vereiteln die MySQL-Query-Cache wie mit
/* __FILE__.'.'.__LINE__ */
zu Beginn meiner Abfrage würde.
Ich nehme noch ein paar Dinge, die ich tun kann, im Hinblick auf das allgemeine Speicherproblem, wie speziell auf MySQL dagegen, und insbesondere im Rahmen unseres eigenen benutzerdefinierten Code, wäre unseren Code wickeln mit Aufrufen an denen einen oder andere der folgenden PHP integrierten Funktionen:
Insbesondere da ich gerade arbeite auf der Protokollierung von einem benutzerdefinierten Code, kann ich die Speichernutzung anmelden, während ich es bin