Manchmal läuft der Speicher in WordPress über, weil massenweise duplizierte Einträge von Custom Fields (Meta Keys) in den Beiträgen gespeichert werden. Wenn das passiert, hilft nur noch ein Eingriff in die Datenbank.
Ich hatte gestern den interessanten Fall, dass die Übersichtsseite der Beiträge nicht mehr zu laden war, weil der Speicher, trotz üppiger Ausstattung mit 256MB, übergelaufen ist.
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 4096 bytes) in /html/wp-includes/wp-db.php on line 1995
Die üblichen Tests auf problematische Plugins oder Themes waren ergebnislos. Blieben eigentlich nur noch die Beiträge selbst, die zu Problemen führen konnten. Das Löschen von ein paar Beiträgen hat das Speicherproblem Problem entschärft, aber nicht behoben. Somit war allerdings klar, dass irgendetwas mit den Beiträgen nicht stimmen konnte.
Auf die heiße Spur hat mich gebracht, dass ich manche Artikel quasi nicht mehr laden konnte, bzw. die Ladezeiten massiv gestiegen waren. Sichtbare Probleme gab es erstmal keine. Das Deaktivieren des Plugins „Advanced Custom Fields“ und des „Gutenberg Editor“ und dazu die Aktivierung der Anzeige der Custom Fields hat dann den Schlamassel zu Tage gebracht: Diese Artikel hatten extrem viele Instanzen von gleichen Custom Fields. Weitere Datenbank-Abfragen haben gezeigt, dass teilweise Beiträge mit über 150.000 Custom Fields die Datenbank zugemüllt haben.
Man konnte in einer Übersicht der Beiträge mit den meisten Custom Fields relativ schnell sehen, dass die Custom Fields quasi immer wieder verdoppelt wurden. Das hat darauf geschlossen, dass das Plugin „Duplicate Posts“ Probleme bereitet hat. Allerdings offenbar ausschließlich in der Kombination mit dem Plugin „Popup Builder“. Kurzerhand wurde das Plugin „Duplicate Posts“ gegen „Duplicate Page“ getauscht. Siehe da…keine Probleme mehr.
Kopien von Post Meta Entries per SQL bereinigen
Blieb nur noch die Bereinigung der Tabelle _postmeta. Wichtig war daran zu denken, dass man nicht einfach alles Meta Keys löschen durfte. Man musste die erste Instanz des Keys erhalten, damit der Post überhaupt noch funktioniert. Hier habe ich mich eines SQLs bedient, den ich bei tieferer Recherche im Netz gefunden habe:
DELETE FROM `wp_postmeta` WHERE `meta_id` NOT IN (SELECT * FROM (SELECT MAX(`pm`.`meta_id`) FROM `wp_postmeta` pm GROUP BY `pm`.`post_id`, `pm`.`meta_key`) x)
Mit diesem Befehl ließ sich schnell die Datenbank bereinigen und die Übersichtsseite der Posts war wieder erreichbar.