Facebook
Twitter
Google+
Kommentare
4

Nimmer Ärger mit den Persistenten Verbindungen von MySQL? (Teil 2/2)

Was bislang geschah: Persistente Verbindungen sind ein berühmt-berüchtigtes Mittel zur Beschleunigung von Datenbankverbindungen. In PHP 5.3 führt MySQL Persistente Verbindungen in ext/mysqli ein. ext/mysql und PDO unterstützen sie bereits lange, doch mysqli zieht erst jetzt nach. Der Nachzügler verwendet eine andere Strategie beim Pooling und behauptet sicherer zu sein.

Der Rausch der Geschwindigkeit zu Lasten der Sicherheit?

Persistente Verbindung bergen nicht nur das Risiko einer Überlastung des Webservers durch eine Fehlkonfiguration. Es gibt weitere Nebenwirkungen, weil eine Persistente Verbindung von verschiedenen PHP-Anwendungen nacheinander benutzt.
Harry denkt an seine letzte Zugfahrt. “Bitte verlassen Sie diesen Raum so, wie Sie ihn vorfinden möchten”. Besteht keine Übereinkunft zwischen den Benutzern einer gemeinsamen Ressource über die Nutzung und Pflege derselben, sind Überraschungen vorprogrammiert. Negative Erfahrungen sind nicht immer dem Vorbenutzer anzulasten. Wie könnte ein verstorbener Vorbenutzer, ein ungewollt beendetes PHP-Skript, die geteilte Ressource aufräumen?
Die Kritik am Fehlen einer automatischen Bereinigung einer Persistenten Verbindung der PHP-Erweiterung ext/mysql hat dazu geführt, daß der Nachfolger, die PHP-Erweiterung ext/mysqli (“i” für “improved”), zunächst keine Persistenten Verbindungen erlaubte. Zu viele PHP-Anwender waren sich der Nebenwirkungen nicht bewusst. Persistente Verbindungen erhielten einen negativen Ruf. Entsprechend bot ext/mysqli bis zur PHP Version 5.3 keine Persistenten Verbindungen an.
Die neuerliche Umsetzung in ext/mysqli unterscheidet sich von derjenigen in ext/mysql. Die neue Implementierung legt mehr Wert auf Komfort und Sicherheit. Persistente Verbindungen von ext/mysqli werden automatisch bereinigt, bevor sie wiederverwendet werden.
Der “Reinigungsplan” für Persistente Verbindungen fällt je nach Datenbanksystem unterschiedlich lang aus. Im Falle von MySQL schreibt der Plan folgende Arbeiten vor:

  • ROLLBACK aller offenen Transaktionen
  • Freigabe alle temporären Tabellen
  • Freigabe aller Tabellensperren
  • Freigabe aller Sperren, die mit GET_LOCK() eingerichtet wurden
  • Rücksetzung aller Session-Variablen auf die globalen Standardwerte
  • Freigabe aller Prepared Statements
  • Schließen aller HANDLER

Bei Verwendung der Persistenten Verbindungen von ext/mysql wird keine der aufgelisteten Aktionen automatisch ausgeführt. Erhält ein PHP-Skript eine wiederverwendete Verbindung, so muß es damit rechnen, daß eine offene Transaktion vorliegt. Dies ist leicht innerhalb der Applikation zu lösen. Weitaus schwieriger ist es Tabellensperren zu erkennen, die nicht freigegeben wurden, bevor eine persistente Verbindung wiederverwendet wird.
Mit PHP 5.3 sind diese Probleme Vergangenheit, sofern ext/mysqli eingesetzt wird. Das “Flaggschiff” der PHP-MySQL-Erweiterungen für das Kommando COM_CHANGE_USER aus dem MySQL Client-Server Protokoll aus, bevor eine wiederverwendete Persistente Verbindung an eine PHP-Anwendung übergeben wird. COM_CHANGE_USER führt alle obigen “Reinigungsarbeiten” durch. Es versetzt die Verbindung in einen Zustand als sei sie neu eröffnet worden.
Alle Nebenwirkungen sind behoben. Wirklich alle, da COM_CHANGE_USER den Datenbankbenutzer neu authentifiziert und seine Autorisierung überprüft. Rechteänderungen werden von der Persistenten Verbindung erkannt.

Sicherheit drückt aufs Tempo

Soviel Komfort und Sicherheit haben ihren Preis. Aufräumen kostet ist. COM_CHANGE_USER, mysqli_change_user(), ist ein vergleichsweise langsames Kommando. Die zu Beginn des Artikels präsentierten Benchmark-Skripte werden um den Faktor 2-3 verlangsamt. Das “SELECT 1”-Beispiel erreicht ohne Persistente Verbindung 1522 Schleifendurchläufe. Mit Persistenten Verbindungen im Stile von ext/mysql steigt der Wert auf 11056. Beim Einsatz von sicheren Persistenten Verbindungen im Stile von ext/mysqli sinkt er jedoch auf 3584 Schleifendurchläufe. Wie groß die Auswirkungen auf reale Applikationen sind, muss die Praxis zeigen.
bild1
Wer seit Jahren erfolgreich die Persistenten Verbindungen von ext/mysql verwendet und diese mit all ihren Nebenwirkungen auch in ext/mysqli nutzen möchte, der sollte PHP mit -DMYSQLI_NO_CHANGE_USER_ON_PCONNECT kompilieren.
bild2

Fazit

Die mit PHP 5.3 in ext/mysqli eingeführten Persistenten Verbindungen sind komfortabler und sicherer als ihre Pendants in ext/mysql. Einfache Benchmarks lassen Performanzverluste erwarten. Die im Artikel gezeigten Benchmarks nähern sich dem “Worst-Case” an. Aufgrund der extrem einfachen Anfrage übt der Verbindungsoverhead einen großen Einfluss auf die Gesamtlaufzeit aus. Unter diesen wenig praxisrelevanten Vorraussetzungen zeigen sich Persistente Verbindungen von ext/mysqli etwa doppelt so schnell wie normale Verbindungen, wenngleich gegenüber ext/mysql ein Performanzeinbruch um den Faktor drei zu verzeichnen ist.
Da keine realitätsnahen Benchmarks vorliegen sind alle Werte mit größter Vorsicht zu interpretieren. Rückmeldung aus der Praxis ist notwendig, um zu entscheiden ob die in der Beta-Version von PHP 5.3 gewählte Implementierung auf ein positives Echo trifft. Nichts ist in Stein gemeißelt. Schon dar nicht ein -DMYSQLI_NO_CHANGE_USER_ON_PCONNECT für den Compiler.

PS: Auch Neu in PHP 5.3 – mysqlnd

Die PHP-Erweiterung ext/mysqli ist das “Flaggschiff” der kleinen Flotte von PHP-MySQL-Erweiterungen zu der weiterhin ext/mysql und PDO_MYSQL gehören. Das Flaggschiff beherrscht alle Manöver der kleineren Schwesterschiffe und kann als einziges den vollen Funktionsumfang der MySQL Datenbank ansprechen.

Alle drei Erweiterungen können in PHP 5.3 entweder den MySQL native driver for PHP (mysqlnd) oder die MySQL Client Library (libmysql) verwenden, um mit der MySQL Datenbank zu kommunizieren. Die Verwendung der einen oder anderen C-Blibliothek ist transparent für den PHP-Programmierer. Egal welche C-Bibliothek zum Einsatz kommt, bestehende PHP-MySQL-Anwendungen funktionieren wie gewohnt. Die einzige Einschränkung ist, daß mysqlnd einen MySQL Server der Version 5.0 oder neuer voraussetzt, da MySQL ältere Versionen nicht mehr unterstützt. Wer sich trotzdem für mysqlnd entscheidet, darf auf eine mindestens gleichwertige Performanz und potentielle Speichereinsparungen hoffen. Bestes Beispiel sind die obigen Benchmarks.

Mehr hierzu in der Präsentation und im PHP-Handbuch.

Dort finden sich auch ein paar Hinweise auf die neuen mysqlnd-Statistiken, mit vielversprechenden Feldern wie “connect_success”, “connect_failure”, “connection_reused ”, “reconnect “, “pconnect_success “ und, und, und. Johannes testet auf seiner Website eine PHP-Erweiterung, welche die Daten über mehrere PHP-Aufrufe hinweg aggregiert: http://schlueters.de/~johannes/mysqlnd_stat.php

Über den Autor

Ulf Wendel

Ulf Wendel arbeitet als Senior Software Engineer im Connectors-Team bei MySQL/Sun. Er verdiente sich von 1997-2004 seine Brötchen als Entwickler von PHP und MySQL basierten Webanwendungen. In dieser Zeit arbeitete er für NetUSE (phpLib), stellte auf dem ersten deutschen PHP-Kongress im Jahr 2000 ein Dokumentationsskript vor (phpdoc.de) vor und genoß die Zeit als MySQL-Consultant zusammen mit Mayflower/thinkPHP für die Hypovereinsbank arbeiten zu dürfen. Von 2004-2006 kümmerte er sich als MaxDB Support Manager bei MySQL, um Support, Training und Consulting von MaxDB. Im Jahr 2006 wechselter er in das Connectors-Team Das Team betreut und entwickelt die MySQL-Treiber (JDBC, ODBC, C-API, PHP, ...), die es einem Client ermöglichen auf einen MySQL-Server zuzugreifen. Derzeit arbeitet Ulf an der PHP-MySQL Anbindung, so wie den Neuentwicklungen MySQL Connector/C++ und dem nativen MySQL Treiber für OpenOffice.org. Wenn es ihm die Zeit erlaubt, schreibt er gerne einmal einen Artikel. Zuletzt erschien der Artikel “Fünf Fragen zu MySQL” von ihm im Buch “Linux Technical Review 09: Datenbanken: Praxistipps von Entwurf bis Tuning”.
Kommentare

4 Comments

  1. Klingt ja echt nicht verkehrt, aber wann wird denn PHP 5.3 endlich kommen? So viele schöne Neuerungen, aber „kein“ Release in Sicht.

    Reply
  2. Also dass ich ausgerechnet in einem Programmier-Blog das schlimme (Amateur-Journalisten-)Wort „vorprogrammiert“ lesen muss! *staun*

    Ansonsten schau ich absolut gern hier rein, wenn ich auch manchem nicht ganz folgen kann. Naja, in einem Jahr vielleicht.. Ich lerne..

    Gruß
    Annie

    PS. Warum wird meine echte E-Mail-Adresse „vorname.nachname@web.de“ hier nicht akzeptiert?

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen