Bereinigung der überfüllten Tabelle „wp_postmeta“

WordPress 5 Min. Lesezeit

Die Tabelle „wp_postmeta“ speichert Zusatzdaten zu Beiträgen, Seiten, Produkten und Bestellungen: Jedes einzelne Feld und jede Plugin-Einstellung entspricht einer eigenen Zeile. Sie verfügt über keine eigene Bereinigungsfunktion. Wenn Sie ein Plugin deinstallieren, bleiben dessen Zeilen meist erhalten, da nur wenige Plugins ihre Daten beim Entfernen löschen und nach einem größeren Versionswechsel auch alte Schlüsselnamen dort zurückbleiben können.

Bei einem Online-Shop wächst die Tabelle im Laufe der Jahre auf Millionen von Einträgen an. Dies macht sich an drei Stellen bemerkbar: Abfragen mit Filtern (beispielsweise Produktfilter) werden langsamer, das Sichern und Wiederherstellen dauert länger, und der Speicherplatz wird knapp.

1. Wie groß ist die Tabelle und was enthält sie?

Die Größe der Tabellen können Sie in phpMyAdmin (cPanel-Gruppe „Datenbanken“) auf der Registerkarte „Struktur“ der Datenbank einsehen. Die Aufteilung der Zeilen erfolgt nach Schlüsselnamen:

SELECT meta_key, COUNT(*) AS db
FROM 1vL7334_postmeta
GROUP BY meta_key
ORDER BY db DESC
LIMIT 40;

Das Tabellenpräfix (im Beispiel „1vL7334_“) ist bei mit dem WP Toolkit installierten Websites zufällig; Ihr eigenes Präfix wird durch den Befehl „wp db prefix“ ausgegeben und ist auch in der Liste auf der linken Seite von phpMyAdmin zu sehen. Über die Befehlszeile können Sie die Abfrage mit dem Befehl „mysql“ ausführen; auf den cPanel-Servern von aWh funktioniert „wp db query“ nicht (da „proc_open“ deaktiviert ist). Die Konfiguration der Datei „~/.my.cnf“, die das Passwort enthält, wird im Artikel zur Verwendung von WP-CLI beschrieben.

cd ~/public_html
P=$(wp db prefix); DB=$(wp config get DB_NAME)
mysql "$DB" -e "SELECT meta_key, COUNT(*) AS db FROM ${P}postmeta GROUP BY meta_key ORDER BY db DESC LIMIT 40"

2. Was ist überflüssig?

Schlüssel von deinstallierten Plugins. Die Präfixe der Schlüsselnamen beziehen sich meist auf das jeweilige Plugin (_yoast_, _elementor_, _wc_, _aioseo_). Vergleichen Sie die Liste mit Ihren installierten Plugins:

wp plugin list --fields=name,status

Wenn eine Schlüsselgruppe umfangreich ist und das Plugin nicht mehr in der Liste aufgeführt ist, kann es mit großer Wahrscheinlichkeit gelöscht werden. Falls Sie sich nicht sicher sind, suchen Sie nach dem Namen des Schlüssels: In der Dokumentation oder im Forum des jeweiligen Plugins wird meist angegeben, um welches Plugin es sich handelt.

Verwaiste Zeilen, deren Eintrag nicht mehr existiert (beispielsweise nach gelöschten Bestellungen oder nach Einträgen, die endgültig aus dem Papierkorb gelöscht wurden):

SELECT COUNT(*)
FROM 1vL7334_postmeta pm
LEFT JOIN 1vL7334_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;

Bei einer einwandfrei funktionierenden Website ist dieser Wert null oder sehr gering.

WooCommerce-Bestellungen. Die neuere Version von WooCommerce speichert Bestellungen in eigenen Tabellen (HPOS). Wenn Ihre Website umgestellt wurde und die Synchronisierung deaktiviert ist, können die alten Bestelldaten möglicherweise noch in der Tabelle „wp_postmeta“ vorhanden sein. Löschen Sie diese nicht manuell, sondern verwenden Sie dazu das eigene Tool von WooCommerce (WooCommerce › Einstellungen › Erweitert › Funktionen), und zwar erst, nachdem Sie sich vergewissert haben, dass die Bestellungen in den neuen Tabellen vollständig vorhanden sind.

3. Speichern

Bevor Sie irgendetwas löschen, sichern Sie bitte die Datenbank:

mysqldump --single-transaction --no-tablespaces "$DB" > ~/postmeta-elott-$(date +%F).sql
tail -1 ~/postmeta-elott-$(date +%F).sql

Die letzte Zeile sollte lauten: „-- Dump completed on …“. Die Registerkarte „Exportieren“ in phpMyAdmin sowie die tägliche JetBackup-Sicherung sind ebenfalls geeignet (Wiederherstellung aus der Sicherung).

4. Löschen in kleinen Schritten

Ein einziger großer DELETE-Befehl über mehrere hunderttausend Zeilen sperrt die Tabelle für längere Zeit. Da jede Speicherung von Einträgen und Bestellungen in diese Tabelle erfolgt, wird die Website während dieser Zeit langsamer, der Bezahlvorgang kann ins Stocken geraten, und der Vorgang kann zudem an die Ressourcengrenzen des Webhostings stoßen. Löschen Sie stattdessen in Portionen von jeweils 5.000 Zeilen mit kurzen Pausen:

KULCS='_regibovitmeny_adat'
while :; do
  N=$(mysql "$DB" -N -e "DELETE FROM ${P}postmeta WHERE meta_key = '${KULCS}' LIMIT 5000; SELECT ROW_COUNT();")
  echo "törölve: $N"
  [ "$N" -eq 0 ] && break
  sleep 1
done

Es durchläuft alle Schleifen und hält an, sobald nichts mehr zu löschen ist. Für die verbleibenden Zeilen gilt dasselbe Muster, die Abfrage lautet:

DELETE pm FROM 1vL7334_postmeta pm
LEFT JOIN 1vL7334_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;

Dieses Format wird von MySQL mit LIMIT-tel nicht zugelassen; wenn die Anzahl der Treffer groß ist, löschen Sie bitte nach ID-Bereichen (beispielsweise AND pm.meta_id < 100000-tel und anschließend < 200000) oder verwenden Sie ein Bereinigungs-Plugin wie WP-Optimize, das ebenfalls in Teilmengen arbeitet.

Ohne SSH können Sie dieselben Abfragen auf der Registerkarte „SQL“ von phpMyAdmin ausführen; wiederholen Sie die Variante „LIMIT 5000“, bis die Anzahl der betroffenen Zeilen auf null sinkt.

5. Komprimierung der Tabelle

Der Platz der gelöschten Zeilen innerhalb der Tabelle wird freigegeben, doch die Datei auf der Festplatte wird nicht kleiner, und auch die Speicherung wird nicht schneller, solange die Tabelle nicht neu aufgebaut wird:

mysql "$DB" -e "OPTIMIZE TABLE ${P}postmeta"

Die Meldung „Table does not support optimize, doing recreate + analyze instead“ in der Antwort ist normal (bei InnoDB-Tabellen baut MySQL die Tabelle auf diese Weise neu auf); entscheidend ist der Status „OK“ in der letzten Zeile. Der Vorgang sperrt die Tabelle für einige Sekunden; führen Sie ihn daher in Zeiten mit geringem Datenverkehr durch. In phpMyAdmin: Markieren Sie die Tabelle und wählen Sie die Funktion „Tabelle optimieren“ aus.

Überprüfung

Führen Sie die erste Abfrage erneut durch und vergleichen Sie die Anzahl der Zeilen mit der Größe der Tabelle. Überprüfen Sie die wichtigen Bereiche der Website (Produktseiten, Filter, Kasse, Vorlagen des Seitenerstellers): Falls etwas fehlt, haben Sie möglicherweise einen noch verwendeten Schlüssel gelöscht; diesen können Sie aus der Sicherung wiederherstellen.

Sollte neben der Tabelle „wp_postmeta“ auch die Admin-Oberfläche langsam sein, hilft Ihnen der Artikel über die automatisch geladenen Daten der Tabelle „wp_options“ weiter; sollte die Datenbank aufgrund von Hintergrundaufgaben an Größe zunehmen, lesen Sie bitte den Artikel zum Action Scheduler.

Zurück: WordPress-Artikel (43)