WP-CLI-Löschbefehle: Welche Tabellen jeder Befehl anfasst und was er zurücklässt

Inhalt
Datenbankpflege in WordPress ist eine Handvoll Befehle, die alle gleich aussehen und sich überhaupt nicht gleich verhalten. Einer geht durch die Anwendung und räumt hinter sich auf; der nächste fasst eine einzige Tabelle an und lässt vier weitere mit Zeilen zurück, die auf nichts mehr zeigen.
Wichtig wird der Unterschied dadurch, dass WP-CLI von wenigen Ausnahmen abgesehen kein Probelaufen kennt. Einen Löschbefehl zu fragen, was er täte, ist nicht vorgesehen. Es gibt nur die Übung, vorher einen anderen Befehl zu fragen.

Das Zweischrittmuster, das den Probelauf ersetzt
Zu jedem zerstörenden Befehl gibt es ein harmloses Geschwister, das denselben Filter annimmt. Zu wp post delete gehört wp post list, zu wp comment delete gehört wp comment list. Die Liste zuerst mit --format=count zu fahren, beantwortet die einzige Frage, die ein Probelauf beantwortet hätte: um wie viele Zeilen es gleich geht.
# 0. eine Sicherung, außerhalb des Web-Verzeichnisses
wp db export /home/pi/sicherung-$(date +%F).sql
# 1. zählen, mit genau dem Filter, der gleich verwendet wird
wp post list --post_type=revision --format=count
# 2. löschen, mit genau demselben Filter
wp post list --post_type=revision --format=ids | xargs -n 100 wp post delete --force
Das xargs in der letzten Zeile ist keine Zierde. Mehrere tausend Nummern unmittelbar in die Befehlszeile einzusetzen, läuft in die Längenbegrenzung der Argumente, und der Fehler kommt, nachdem ein Teil der Arbeit erledigt ist, statt bevor irgendetwas geschehen ist – also genau in der Lage, die das ganze Vorgehen vermeiden sollte.
Die Sicherungszeile enthält eine Feinheit, die im Gedächtnis bleiben sollte: Ohne Pfad schreibt wp db export den Abzug in das aktuelle Verzeichnis, und das ist bei einem WordPress-Befehl meist das Web-Verzeichnis. Ein vollständiger Datenbankabzug mit erratbarem Namen, über HTTP ausgeliefert, ist ein schlimmeres Ergebnis als alles, was das Aufräumen beheben sollte.
Zwei Wege, dieselbe Zeile zu entfernen
wp post delete ruft dieselbe Funktion auf wie der Editor. Der Befehl entfernt die Metadaten, die Kommentare, die Kommentarmeta und die Begriffsverknüpfungen, und er löst die Haken aus, über die Erweiterungen entfernen können, was sie anderswo angelegt haben – einen Sucheintrag, einen Zwischenspeicher, eine Zeile in ihrer eigenen Tabelle.
Ein unmittelbares DELETE FROM wp_posts entfernt eine Zeile. Alles, was auf sie verwies, bleibt liegen, unerreichbar und unsichtbar: Keine Abfrage verbindet sich mit einem Beitrag, den es nicht gibt, also tauchen die Zeilen schlicht nie wieder auf. Das ist tragbar, bis eine Nummer erneut vergeben wird – und Beitragsnummern werden nach einem Datenbankeinspielen erneut vergeben. Dann erbt der neue Beitrag lautlos die eigenen Felder und die Kommentare des alten.
Was jeder Befehl tatsächlich anfasst
| Befehl | Entfernt | Lässt stehen |
|---|---|---|
wp post delete <Nr> --force |
Beitrag, Metadaten, Kommentare, Begriffe | die angehängten Dateien und ihre Anhangszeilen |
wp post delete <Anhang> --force |
die Zeile und die Dateien auf der Platte, alle Größen | Verweise auf die Adresse in anderen Beiträgen |
wp post delete <Revisionen> |
die Revisionen und deren eigene Metazeilen | den Beitrag selbst, unangetastet |
wp comment delete --status=spam |
Kommentare und Kommentarmeta | die Kommentarzähler je Beitrag, bis zum Nachzählen |
wp transient delete --expired |
nur Transienten, deren Frist verstrichen ist | jeden Transienten, der ohne Frist gespeichert wurde |
wp db optimize |
nichts | eine Tabellensperre für die Dauer des Neuaufbaus |
Die erste Zeile überrascht am häufigsten. Einen Beitrag zu löschen, löscht die Bilder darin nicht – Anhänge sind eigene Beiträge mit eigenen Nummern und überleben ihren Erzeuger. Eine um tausend alte Beiträge erleichterte Seite trägt also weiterhin tausend Beiträge an Medien mit sich, und dort ist der Plattenplatz auch geblieben.
Die Zeile mit den Kommentarzählern ist am billigsten zu beheben und am leichtesten zu vergessen: Nach jedem größeren Kommentarlöschen bringt wp comment recount die Zahlen wieder mit den Zeilen in Übereinstimmung. Ohne das geht nichts kaputt; die Zähler sind bloß falsch, überall und lautlos.
Der Papierkorb ist keine Sicherung
Ohne --force verschiebt das Löschen einen Beitrag in den Papierkorb, und das ist eine Statusänderung und sonst nichts. Die Zeile bleibt, die Metadaten bleiben, die Medien bleiben, und Platz wird nicht frei – ein einmal im Monat geleerter Papierkorb ist eine Pflegegewohnheit und kein Sicherheitsnetz.
Mit --force überspringt der Beitrag den Papierkorb vollständig, und innerhalb von WordPress gibt es überhaupt kein Zurück. Zwischen einem vertippten Filter und einem verlorenen Monat steht allein der Abzug aus Schritt null – deshalb ist es Schritt null.
Abgelaufen ist nicht dasselbe wie alle
Transienten sind ein Zwischenspeicher mit einer neben dem Wert abgelegten Frist. wp transient delete --expired entfernt die, deren Zeit verstrichen ist, und ist von der Anlage her ungefährlich: Was gelöscht wird, war ohnehin ungültig.
--all ist ein anderer Befehl im selben Gewand. Er entfernt auch Transienten ohne Frist, und manche Erweiterungen verwenden genau die als einzigen Ablageort für etwas, dessen Berechnung teuer war – eine Lizenzprüfung, einen Bestand, ein fertig gebautes Menü. Sichtbar geht nichts kaputt; die Seite verbringt bloß die nächste Stunde damit, Dinge neu zu bauen, um die sie niemand gebeten hat, und ein oder zwei Erweiterungen benehmen sich, als wären sie gerade installiert worden.
Optimieren ist ein Neuaufbau, kein Aufräumen
wp db optimize führt OPTIMIZE TABLE aus, und bei InnoDB ist das keine Optimierung, sondern ein vollständiger Neuaufbau der Tabelle samt ihrer Indizes. Für die Dauer ist die Tabelle für Schreibzugriffe gesperrt, was bei einem kleinen Blog eine Sekunde dauert und bei einer großen wp_postmeta lange genug, dass Besucher es merken.
Es ist zugleich der Schritt, der am verlässlichsten nichts zurückgewinnt. Platz aus gelöschten Zeilen wird von InnoDB bereits für neue Zeilen wiederverwendet; die Datei auf der Platte schrumpft nur, wenn sehr viel gelöscht wurde und seitdem nichts geschrieben. Einmal nach einem großen Aufräumen zu einer ruhigen Stunde lohnt sich – in einem nächtlichen Cron aufgehoben zu sein lohnt sich nicht, und genau dort landet der Befehl für gewöhnlich.