Unser byteblog: Allgemeine Themen zur Netzkultur, die wir gerne teilen möchten.
WordPress, rewrite_rules und max_allowed_packet
Kürzlich hatten wir bei einer Kundeninstallation von WordPress das Phänomen, dass das Blog von der einen Sekunde auf die andere eine ungewöhnlich lange Zeit zur Auslieferung der Seite benötigte. Nach dem Aufruf einer Blogseite zeigte der Browser für variable Zeiten zwischen 10 bis 30 Sekunden nur “Warten auf ….” an, um dann aber die Seite mit normaler Geschwindigkeit auszuliefern. Hier kamen sofort Gedanken an ein Problem mit MySQL oder dem Server an sich in den Kopf – allerdings lief eine gleichzeitig installierte Version des Blogs in einer anderen Sprache einwandfrei und auch andere installierte Webseiten auf dem Server zeigten keine Probleme.
Das Debugging sollte sich also etwas aufwendiger gestalten. MySQL seitig war kein Problem zu finden. Also machten wir ein Backup der Seite und installierten es auf einem lokalen System – auch hier gab es kein Problem – die Seiten wurden normal ausgeliefert. Musste es also doch am Server liegen.
Wir haben dann die Skriptlaufzeit untersucht und an verschiedenen Stellen im WordPresscode Marker gesetzt um zu sehen, an welcher Stelle die ungewöhnlich hohe Skriptlaufzeit auftrat. Nach kurzer Zeit konnten wir die Funktion parse_request als den Schuldigen ausmachen, der das Skript so verlangsamte.
Betreibt man ein WordPress Blog mit Permalinks, so werden statische Rewrite Rules erzeugt, die in der Datenbank in der Tabelle wp_options als Option rewrite_rules abgelegt werden. Dies soll WordPress eine schnellere Übersetzung von URLs zu ihrer jeweilgen Post bzw. Pages-ID ermöglichen. Wie sich herausstellte, war in der englischen Version des Blogs diese Option nicht mehr vorhanden, in der deutschen hingegen schon.
Da die Option im Englischen nicht vorhanden war, erzeugte sich WordPress bei jedem Seitenaufruf die rewrite_rules on the fly – was bei den inzwischen ca. 500 vorhandenen Pages und 300 vorhandenen Posts eben gut 10 Sekunden dauerte.
Die Frage war nun, warum die rewrite_rules in der wp_options nicht mehr vorhanden war. Nachdem wir uns diese Option in der lokalen Version angesehen haben, zeigte sich recht schnell, dass diese rewrite_rules eine stattliche Größe von mehr als 1 MB hatte. Ein etwas längeres Googlen zu diesem Umstand brachte dann zu Tage, dass es hier zu Problemen kommt, wenn man WordPress mit MySQL in der Standard-Config betreibt. Als Default Wert hat MySQL in der Variablen max_allowed_packet eine Größe von 1 MB pro Query. Sobald also ein Query > 1 MB ist, wird es von MySQL verworfen.
WordPress versucht nun nach jedem Editieren oder Neuanlegen einer Page die rewrite_rules neu zu schreiben. Da das Query aber die magiche Größe von 1 MB überschritten hat, wurden die rewrite_rules nicht mehr geschrieben (dankenswerterweise hat WordPress die Option vor dem Neuschreiben aber gelöscht).
Somit blieb zur Lösung des Problems bei WordPress die max_allowed_packet Größe auf etwas wie 16 MB zu setzen und schon wurde rewrite_rules neu erzeugt bei Editieren einer Page und die WordPress-Installation lief wieder schnell wie eh und je.
Kommentare
Sven 24.08.2010 | 11:49:49
Versteh ich das richtig, dass WordPress bei jedem Seitenaufruf die ganze rewrite_rules Spalte sich mit einem Select SQL Befehl holt. Was macht man denn, wenn die Spalte mal über 5MB groß wird 1 MB hatte ihr ja schon in euerm Beispiel. Dauert dann das Laden einer Seite 10 Sekunden? Hmm sollte man vielleicht mal testen. Cooler Beitrag gut zu wissen.




