it-swarm.com.de

Werden transiente Abfälle gesammelt?

Diese Frage brachte mich zum Nachdenken Transiente RSS-Feeds in wp_options werden nicht automatisch entfernt?

Transienten sollen ablaufen und gelöscht werden. Die einzige Möglichkeit, wie ich dies sehe, besteht darin, dass ein Transient abgelaufen und angefordert ist und dann während der Anforderung gelöscht wird.

Was ist, wenn der Transient abgelaufen ist, danach aber nie mehr angefordert wurde? Aufgrund der Beschreibung im Codex dachte ich, dass eine Art Müllabfuhr impliziert ist. Jetzt bin ich mir nicht so sicher und kann keinen Code finden, der so etwas ausführt.

Wird es also für immer in der Datenbank bleiben?

61
Rarst

Sie sind es jetzt

Ab WordPress 3.7 werden abgelaufene Transienten bei Datenbank-Upgrades gelöscht, siehe # 20316


Alte Antwort

Wenn mir jemand nichts anderes zeigen kann, scheinen Transienten doch kein Müll zu sein. Was es noch schlimmer macht, ist, dass im Gegensatz zu Optionen nicht garantiert wird, dass sie in der Datenbank gespeichert werden. Es gibt also keine zuverlässige Möglichkeit, eine Liste aller Transienten abzurufen, um sie auf Ablauf zu überprüfen.

Behelfsmäßiger Code für die Speicherbereinigung, wenn die Datenbank für die Speicherung verwendet wird:

add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace('_transient_timeout_', '', $transient);
        delete_transient($key);
    }
}
44
Rarst

Verschieben einiger Kommentare aus der Diskussion in eine Antwort mit Neuformulierung und Neuformatierung.

Grundsätzlich kommt es darauf an, dass sie nicht wirklich "Müll gesammelt" werden müssen, es sei denn, Sie haben einen Super-Extremfall. Wenn Sie sie nie abholen, spielt es keine Rolle, ob sie dort sind oder nicht.

Siehe, Transienten werden standardmäßig in der Optionstabelle gespeichert. In einer Basisinstallation enthält die Optionstabelle möglicherweise 100 Einträge. Jeder Übergang fügt zwei weitere Einträge hinzu. Auch wenn Sie Tausende Einträge haben, wirken sich diese nicht auf die Site-Geschwindigkeit aus, da sie nicht automatisch geladen werden.

Beim Start lädt WordPress die Optionen in den Speicher, aber es lädt nur Optionen, deren Autoload-Flag aktiviert ist. Transienten erhalten dies nicht und werden daher nicht in den Speicher geladen. Nur Transienten, die später tatsächlich verwendet werden, verursachen Kosten.

Aus Sicht der Datenbank enthält die Optionstabelle Indizes sowohl zur Options-ID als auch zum Optionsnamen. Transienten werden immer basierend auf dem Namen (Schlüssel) geladen, und die Suche nach ihnen ist daher immer eine einfache Auswahl für einen einzelnen eindeutigen Schlüsselwert. Die Suche lautet also O(log(n)) und ist superschnell. Mit einem Big-O von log (n) müssten Sie in die Millionen und Abermillionen von Zeilen vordringen, bevor es auffällt. Ehrlich gesagt ist der Aufwand für das Einrichten und Herunterfahren der Abfrage sowie für die eigentliche Datenübertragung viel länger. Die Abfrage selbst wird im Vergleich im Wesentlichen null-mal ausgeführt. Wenn Sie also einfachzusätzliche nicht verwendete Zeilen haben, hat dies nur Auswirkungen auf die Verwendung von zusätzlichem Speicherplatz.

Das Indizieren in Datenbanken ist eine dieser tief gelesenen Ideen, die für Leute, die nicht wirklich verstanden haben, was sich hinter den Kulissen abspielt, keinen Sinn ergibt. Datenbanken sind für den schnellen Abruf von Daten von Grund auf ausgelegt und können solche Aufgaben problemlos ausführen. Dies ist eine ziemlich gute Lektüre: http://en.wikipedia.org/wiki/Index_(database )

Jetzt werden sie bei einer Bereinigung auf die offensichtlichste Weise (durch Aufrufen von SQL DELETE) nicht wirklich aus der Datenbank gelöscht. Sie werden einfach aus dem Index entfernt und die Zeile als "gelöscht" markiert. Wiederum funktionieren Datenbanken genau so. Um den Speicherplatz tatsächlich freizugeben, müssen Sie fortfahren und anschließend eine OPTIMIZE TABLE ausführen. Dies ist keine schnelle Operation. Es braucht Zeit. Wahrscheinlich mehr Zeit als es wert ist. Es ist wahrscheinlich nicht genug, um insgesamt CPU-Zeit einzusparen.

Wenn in einem bestimmten Fall ständig neue Transienten eingefügt werden, die nicht verwendet werden, müssen Sie stattdessen das zugrunde liegende Problem suchen. Was ist das Einfügen dieser Transienten? Verwenden sie einen sich ändernden oder mutierenden Schlüssel? Wenn ja, dann sollte das Plugin oder der Code, der dies verursacht, im Grunde genommen nicht so sein. Das ist hilfreicher, da der Code, der sie nicht ordnungsgemäß erstellt, sie wahrscheinlich auch nicht abruft und damit mehr Arbeit leistet, als er tun muss.

Andererseits kann es vorkommen, dass für so etwas wie jeden Post Transienten erstellt werden. Dies kann in der Tat durchaus akzeptabel sein. Ich mache das selbst in SFC, um eingehende Kommentare von Facebook zu speichern. Mit jedem Post ist ein potenzieller Transient verbunden, dh zwei zusätzliche Zeilen pro Post. Wenn Sie 10.000 Posts haben, werden Sie (eventuell) 20.000 Zeilen in der Optionstabelle haben. Dies ist weder schlecht noch langsam, da es, soweit es die Datenbanken wirklich betrifft, kaum Unterschiede zwischen 100 Zeilen und 20.000 Zeilen gibt. Es ist alles indiziert. Es ist verdammt schnell. Sub-Sub-Millisekunden.

Wenn Sie anfangen, in Millionen Zeilen zu geraten, dann würde ich mir Sorgen machen. Wenn die Größe der Optionstabelle über Hunderte von Megabyte steigt, würde ich mir genug Sorgen machen, um genauer hinzuschauen. Im Allgemeinen ist dies jedoch kein Problem, mit Ausnahme von Extremfällen. Es ist mit Sicherheit kein Problem für etwas Kleineres als eine große Nachrichtenseite mit Hunderttausenden von Beiträgen. Und für jede Site, die groß genug ist, um ein Problem darzustellen, sollten Sie einen externen Objekt-Cache verwenden, und in dass werden die Transienten dort automatisch statt in der Datenbank gespeichert.

20
Otto

Otto - ich könnte dir nicht mehr widersprechen. Das Problem ist, dass mit all diesen Übergängen die Größe der Tabelle lächerlich wird. Es braucht nicht Millionen von Reihen, um festzumachen. Derzeit habe ich es mit einer Optionstabelle zu tun, die mehr als 130.000 Zeilen enthält und regelmäßig hängt. Da es sich bei dem Wertefeld um einen großen Texttyp handelt, wird selbst das Suchen nach "Autoload" -Zeilen zu einem Albtraum der Leistung. Diese Wertfelder werden getrennt von den übrigen Zeilendaten gespeichert. Obwohl es logischerweise Teil derselben Tabelle ist, müssen Verknüpfungen stattfinden, um die gewünschten Zeilen abzurufen. Beitritte, die jetzt für immer dauern, weil die Daten, die Sie benötigen, über den gesamten Speicherplatz auf der Festplatte verteilt sind. Das Profiling (mit Jet Profiler für MySQL) hat dies bewiesen.

Das Hinzufügen des automatischen Ladevorgangs zum Clustered Key kann zur Behebung dieses Problems beitragen. Durch Clustering in Autoload Desc, z. B. ID ASC, können alle Autoload-Zeilen zuerst auf der Festplatte zusammengefasst werden. Trotzdem denke ich, dass Sie eine enorme Belastung aus Sicht der DB sehen.

Persönlich denke ich, dass das Design dieses Systems verrückt ist. Die Optionstabelle scheint zu einem allgemeinen Sammelbegriff für viele Dinge geworden zu sein. Das ist in Ordnung, wenn das Wertefeld klein genug ist, um auf derselben Seite wie die übrigen Zeilendaten enthalten zu sein, und effektiv indiziert werden kann. Leider ist das nicht der Fall. Wer auch immer dies entworfen hat, muss in die Klasse DB101 zurückkehren.

18
myke