Werden vorübergehende Abfälle gesammelt?
-
-
theoretisch sollten sieentfernt werden,wenn cron ausgeführt wird (wenn sie abgelaufen sind)theoretically they should be removed when cron is run (if they are expired)
- 0
- 2011-01-09
- onetrickpony
-
@ Ambitious Amoeba Ich sehenichtsmit dieser Funktionalität,die an Crongebundenist.Deshalbfrageich -es scheinteine Annahme zu sein,von derichnicht sicherbin,ob siegültigist.@Ambitious Amoeba I do not see anything with that functionality hooked to cron. That is why I am asking - it seems to be an assumption I am not sure is valid.
- 0
- 2011-01-09
- Rarst
-
Ich verstehe,dass Transienten keineechten Cron-Prozesse sind. Zumindestmussjemandeine Seite anfordern,damit sieerstellt/entfernt werden können (aberesist dasnächstbeste zueinem echten Cron-Prozess).Ich habemeine Transientennicht überwacht. Sehen Sie,dass Transientennach Ablauf häufig herumhängen?It's my understanding that transients are not really real cron processes, they at least require someone to request a page in order for them to be created/removed(but it's the next best thing to a real cron process). I've not monitored my transients, are you seeing transients hang around often after expiry?
- 0
- 2011-01-09
- t31os
-
@t31os Ja,ich sehe sie hängen,aberich habe keine Informationen darüber,wie lange sie hängen können,bevor definitivgesagt werden kann,dass sie kein Müll sind@t31os yes I do see them hanging, but I have no information on how long they can hang before it can be said definitively that they are not garbage collected
- 0
- 2011-01-09
- Rarst
-
@Rarst - Ichbin mir auchnicht sicher,wie die Bereinigungbestimmt wird. Sehen Sie dieses Problembei bestimmten oder unterschiedlichen Transienten?@Rarst - I'm not sure how cleanup is determined either, are you seeing this problem with any particular transients or differing ones?
- 0
- 2011-01-09
- t31os
-
@t31os Ich werde keine Zeit damit verschwenden,Transienten zuprotokollieren,die Geräteprotokollieren,bevorich weiß,obes sich überhaupt um Müll handelt.:) :)@t31os I am not going to waste time on coding transients logging contraption before I know if they are supposed to be garbage collected at all. :)
- 0
- 2011-01-09
- Rarst
-
@Rarst - Schlägtmich Kumpel,wolltenurein paar Gedankenteilen .. :)@Rarst - Beats me mate, just wanted to share a few thoughts.. :)
- 0
- 2011-01-09
- t31os
-
Es scheint,dass abgelaufene Transientengelöscht werden,wenn "get_transient" ausgelöst wird - http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/functions.php#L721it seems that expired transients are deleted when `get_transient` fires off - http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/functions.php#L721
- 0
- 2011-01-09
- onetrickpony
-
Sie sollten also keine abgelaufenen Transientenin der Datenbank sehen,es sei denn,mit delete_option ()istein Fehler aufgetreten.So you shouldn't see any expired transients in the db, unless something went wrong with delete_option()
- 0
- 2011-01-09
- onetrickpony
-
@ Ambitious Amoebaja,das habeichirgendwieerwähnt.Mein Punktist -transientes Erstellen setztnicht voraus odergarantiertnicht,dassesjemals angefordert wird.Hervorheben der ursprünglichen Frage - ** wann und ob abgelaufene Transientengelöscht werden,wennich sienie _get_ habe? **@Ambitious Amoeba yeah, I kinda mentioned that in question. My point is - transient being created doesn't assume or guarantee that it is ever going to be requested. Stressing the original question - **when and if expired transient gets deleted if I never _get_ it?**
- 1
- 2011-01-09
- Rarst
-
aber wasbringtes dann,Transienten zu verwenden?but what's the point of using transients then?
- 0
- 2011-01-09
- onetrickpony
-
@Ambitious Amoeba der Punktist,dass Transienten Caching-Mechanismus sind.Das Cache-Konzept setzt ablaufende Daten voraus und keinegarantierten Treffer.Wenn der Cache abgelaufene Datennichtbereinigt,gehen Ressourcen verloren.@Ambitious Amoeba the point is that transients are caching mechanism. Cache concept assumes expiring data and doesn't assume guaranteed hits. If cache doesn't cleanup expired data then it is leaking resources.
- 0
- 2011-01-09
- Rarst
-
Es wird davon ausgegangen,dass Sie die abgelaufenen Datenbereinigen,aberja,Sie haben Recht,esgibt Situationen,in denen sieniemalsgelöscht werden.Wie das Entferneneines Widgets,das Transienten verwendet.Sie sollten dafürein Ticket auf dem Traceinreichen :)it asssumes you clean up the expired data, but yes, you're right, there are situations in which it would never get deleted. Like removing a widget which uses transients. You should submit a ticket on the trac for this :)
- 1
- 2011-01-09
- onetrickpony
-
@Rarst - Klingtnacheinerperfekten Sache,umeinen Patchfür zu schreiben und antrac zu senden?@Rarst - Sounds like a perfect thing to write a patch for and submit to trac?
- 1
- 2011-01-09
- MikeSchinkel
-
@ MikeSchinkel yeaaaah ...nachdemjemandendlichendgültiggeantwortet hat,ob verdammte Transienten Müllgesammelt haben (oder sein sollen) :)@MikeSchinkel yeaaaah... after someone answers definitively at last if damn transients are (or are supposed to be supposed to be) garbage collected :)
- 0
- 2011-01-09
- Rarst
-
@Rarst - Dereinzige Weg,um sicher zu sagen,dasses den Code verfolgt ...@Rarst - The only way to tell for sure it to trace through the code...
- 0
- 2011-01-10
- MikeSchinkel
-
Siemüssennicht "Müllgesammelt" werden.Wenn Sie sienie holen,spieltes keine Rolle,ob sie da sind odernicht.They don't need to be "garbage collected". If you never fetch them, then it doesn't matter if they're there or not.
- 0
- 2011-09-12
- Otto
-
@Otto,wenn Sie anfangen,** Zehntausende ** solcher Mülleinträgein der Optionstabelle zu haben (wasin der Praxispassieren kann undpassiert,siehe verknüpfte Frage) Ich denke,esist ziemlich wichtig,nein?@Otto if you start to have **tens of thousands** of such garbage entries in options table (which can and does happen in practice, see linked question) I think it quite matters, no?
- 0
- 2011-09-12
- Rarst
-
Nein,dastutes wirklichnicht.Datenbanken können Millionen und Abermillionen von Zeilenenthalten,ohne dasses zueinermerklichen Verlangsamung kommt.Es heißt "Indizierung" undbleibt auchbei vielen,vielen Zeilen verdammt schnell: http://en.wikipedia.org/wiki/Index_(database). Wenn Sie SQL DELETE aufrufen,werden sienicht aus der Datenbankgelöscht.Sie werdennur aus dem Indexentfernt,bis Sie aucheine OPTIMIERUNGSTABELLEfür die Tabelle ausführen. Diesisteine langwierige Operation.Im Allgemeinenmüssen Datensätzein einer Datenbanknicht "bereinigt" werden.Lassen Sie die Datenbankihren Jobmachen.Esistbesser als du.No, it really doesn't. Databases can have millions and millions of rows in them without appreciable slowdown. It's called "indexing", and it stays fast as heck even with lots and lots of rows: http://en.wikipedia.org/wiki/Index_(database). What's more, calling the SQL DELETE on them doesn't actually delete them from the database. It just removes them from the index, until you do an OPTIMIZE TABLE on the table as well, which is a long running operation. There is generally no need to "clean up" records in a database. Let the database do its job. It's better at it than you are.
- 0
- 2011-09-12
- Otto
-
Umgenauer zu sein,stellen Siemöglicherweisefest,dassbei Transientenin der Datenbank das Autoload-Flag auf "Nein"gesetztist,wasbedeutet,dass siebeim Startnichtgeladen werden.Dieprimäre Verlangsamungbei jeder Datenbankabfrageist dietatsächliche Datenübertragung von der Datenbank zum Programm.Abfragen selbstnehmen,wenn sie richtiggeschrieben und richtigindiziert sind (wasbedeutet,dass die Abfrage keinen Tabellenscan verursacht),im Vergleichpraktisch keine Zeitin Anspruch.Es spielt keine Rolle,ob Sie 100 Datensätze oder 100.000 haben,daein einfaches SELECTfürein indiziertes Feldeine O-Operation (log (n))ist.Dies ändert sichnicht wirklich,bis Sie 1M + Datensätze oder soerhalten.To be more specific about it, you may notice that transients in the database have their autoload flag set to "no" which means they don't get loaded on startup. The primary slowdown from any database query is the actual data transfer from the database to the program. Queries themselves, if written correctly and properly indexed (meaning the query doesn't cause a table scan), take virtually no time by comparison. Doesn't matter if you have 100 records or 100,000, as doing a simple SELECT on an indexed field is an O(log(n)) operation. This doesn't really change until you get 1M+ records or so.
- 0
- 2011-09-12
- Otto
-
@Otto Könnten Sie diesbitte ineine Antwort verschieben,damit die Informationenbesser sichtbar sind?Ichbehauptenicht,dasseseine Menge Mülleinträgebraucht,um Dinge zu vermasseln ... Aber wennirgendetwas Ressourcen verliert (wasbei Transienten leichtpassieren kann,weil sieeine Schlüssellängenbegrenzung haben,dienicht überprüft wird,isteseinfach,eine Menge vonihnen und zugenerierenNie wieder anfassen,weil der Schlüsselgebrochenist),dann wirdesfrüher oder später alles vermasseln.Ich schreienicht "Fixthisin Core",aberich sehe Bereinigung auchnicht alsnutzlos an.@Otto Could you please move this to an answer so information is more visible? I do not argue that it will take a lot of garbage entries to screw things up... But if anything is leaking resources (which easily happen with transients because they have key length limit that is not checked, easy to generate crapload of them and never touch again because key is broken) then sooner or later it will screw things up. I am not screaming "fix this in core", but I don't see cleanup as useless either.
- 0
- 2011-09-12
- Rarst
-
"Screwthings up"isteine vage Aussage.Das Beste,wasich sehen kann,ist,dass die Datenbankfüreinen begrenzten Kontobereich zugroß wird.Es wirdeigentlichnichts kaputtmachen,bises wirklich sehr,sehrgroß wird.Ich arbeitemit Tabellen,die 20 Millionen Datensätzeenthalten.Das Durchsuchenistetwas langsam,abernicht unangemessen.Sie haben Rechtmit der Schlüssellängenbeschränkung,aber 45 Zeichen reichenfürjeden realistischen Fall,denichmir vorstellen kann.Okay,sicher,esistmöglich,etwas Verrücktes zutun,aberpassiert das oft?Es scheint,als sollte der Autor des Plugins anstelleeiner Problemumgehungbenachrichtigt werden ..."Screw things up" is a bit of a vague statement. The most that I can see happening is that the database gets too large for a limited account space. It's not going to actually break anything until it gets very, very large indeed. I work with tables that have 20 million records in them. Searching them is a bit slow, but not unreasonably so. You're correct about the key length limit, but 45 chars is plenty for every realistic case I can think of. Okay, sure, it's possible to do something crazy, but does that happen often? Seems like plugin author should be notified instead of a workaround...
- 0
- 2011-09-12
- Otto
-
@Otto "nicht oft" und "nie" sind verschiedene Dinge.Wennich darausein Pluginmachenmöchte,möchteich aucheine Warnungfür die Schlüssellänge hinzufügen.Ich sehejedoch keinen Sinn darin,Mülldatenin der Datenbank zu halten,nur weil vorübergehend sofunktioniert.Esist vielleicht kein Fehler,aberesist kaumeine Funktion.@Otto "not often" and "never" are different things. If I get to making plugin out of this I plan to add warning for key length as well. However I do not see a point in keeping garbage data in database just because transient work that way. It may not be a bug, but it is hardly a feature.
- 0
- 2011-09-12
- Rarst
-
Esgehtmirnicht darum,siein der Datenbank zubehalten,nur weil sie sofunktionieren.Mein Punktist,dass der Versuch,sie "zu sammeln",in praktisch allen Fällenmehr kostet alses spart.Esisteigentlich kontraproduktiv.My point isn't to keep them in the database just because they work that way. My point is that trying to "garbage collect" them costs more than it saves, in virtually all cases. It's actually counterproductive.
- 0
- 2011-09-12
- Otto
-
Zugehöriges Trac-Ticket: http://core.trac.wordpress.org/ticket/20316Related trac ticket: http://core.trac.wordpress.org/ticket/20316
- 1
- 2013-09-29
- Stephen Harris
-
3 Antworten
- Stimmen
-
- 2011-01-10
Sie sindjetzt
Ab WordPress 3.7 werden abgelaufene Transientenbei Datenbank-Upgradesgelöscht,siehe # 20316
Alte Antwort
Wennmirjemandnichts anderes zeigen kann,scheintes,dass Transienten doch kein Müll sind. Wasesnoch schlimmermacht,ist,dass sieim Gegensatz zu Optionennichtgarantiertin der Datenbankgespeichert werden. Esgibt also keine zuverlässige Möglichkeit,eine Liste aller Transienten abzurufen,um sie auf Ablauf zu überprüfen.
Behelfsmäßiger Codefür die Speicherbereinigung,wenn die Datenbankfü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); } }
They now are
Starting with WordPress 3.7 expired transients are deleted on database upgrades, see #20316
Old answer
If someone can't show me otherwise it seems that transients are not garbage collected after all. What makes it worse is that unlike options they are not guaranteed to be stored in database. So there is no reliable way to fetch list of all transients to check them for expiration.
Some makeshift code to do garbage collection if database is used for storage:
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); } }
-
$time=$ _SERVER ['REQUEST_TIME'];und dann $time in der SQL-Abfrage verwenden -tun Sie dasnicht.Gehen Sie sorgfältigermit $ _SERVER-Variablen/-Werten um,um SQL-Injektionen zu verhindern.$time = $_SERVER['REQUEST_TIME']; and then making use of $time in the SQL query - don't do that. Deal more carefully with $_SERVER variables / values to prevent SQL injections.
- 0
- 2011-01-10
- hakre
-
@hakre hm ... Ich habe das aus der Präsentation zur PHP-Leistung ausgewählt,dieesempfohlen hat,"time ()" zu verwenden,was zu Fehlernführen kann (die Ausführungerfolgt von Natur ausnicht sofort).Die Anforderungszeit wird von PHP selbstfestgelegt und stammtnicht aus vom Benutzerbereitgestellten Daten.Warumist diese Sicherheitsanfälligkeit?@hakre hm... I picked that from presentation on PHP performance that recommended it over using `time()` which can cause bugs (execution is not instant by nature). Request time is being set by PHP itself, doesn't come from any kind of user-supplied data. Why is this vulnerability?
- 0
- 2011-01-10
- Rarst
-
@Rarst: Ich habenichtgesagt,dass Sieesnicht verwenden sollten,Sie solltennur sicherstellen,dasses sicher codiertist,umin der SQL-Abfrage verwendet zu werden.Sie sollten diesmit jeder Variablen auseinerexternen Quelletun.$ _SERVER-Variablen werdenmöglicherweisenicht wieerwartetfestgelegt und stattdessen sogar vom anfordernden Benutzerfestgelegt.Ich wolltenureine gute Codierungspraxis verbreiten.Informationen zumtatsächlichen Verfügbarkeitsstatusfinden Sie wieimmerin den Dokumenten.Für PHP 4beispielsweiseexistierteine solche Variablenicht und wirdmöglicherweise durcheinen benutzerdefinierten Header odereine Umgebungsvariable überschrieben - http://php.net/manual/en/reserved.variables.server.php@Rarst: I didn't say that you should not use it, you should just ensure that it is safely encoded to be used inside the SQL query. You should do this with every variable from an external source. $_SERVER variables might not be set as expected, and instead, set by the requesting user even. I only wanted to propagate some good coding practice. As always, to learn about the real state of availability, see the docs. For PHP 4 for example, such a variable does not exists and might be overwritten by a custom header or environment variable - http://php.net/manual/en/reserved.variables.server.php
- 0
- 2011-01-10
- hakre
-
@hakrebehoben (glaubeich),dankefür die PHP4-Erinnerung übrigens (ich kannes kaumerwarten,dass WordPress die Unterstützung dafür aufgibt)@hakre fixed (I think), thanks for PHP4 reminder btw (I can't wait for WordPress to drop support of it)
- 0
- 2011-01-10
- Rarst
-
Das siehtin meinen Augen vielbesser aus;).Hoffen wir,dasses kein Problemmit time () undnegativen Ganzzahlengibt,die alle oder keine Transienten als versehentlich löschen könnten.Vertraueniemalseinem laufenden System: P.That looks much better in my eyes ;). Let's hope that there is no problem with time() and negative integers that might delete all or no transients than by accident. Never trust a running system :P
- 0
- 2011-01-10
- hakre
-
Falls Sie sichnichtbewusst waren,ist _ein einzelner Zeichen-Platzhalterfür LIKE-Anweisungen und sollteidealerweisemaskiert werden.:) :)In case you weren't aware, _ is a single char wildcard for LIKE statements, and should ideally be escaped. :)
- 0
- 2011-01-10
- Denis de Bernardy
-
@Denisja,ich weiß das ... Aber keinpraktischer Unterschiedin dieser Abfrage? .. Es sei denn,jemand schafftes,die Option XtransientXtimeoutX oder so zubenennen.@Denis yeah, I know that... But no practical difference in this query?.. Unless someone manages to name option XtransientXtimeoutX or something.
- 0
- 2011-01-10
- Rarst
-
Würden Sienicht $ wpdb->prepare () verwenden,um sich ordnungsgemäß vorfehlerhaften Daten zu schützen,wie z. B. dem,worüber @hakre sprach?Dies würde auch das Entkommen des '_' lösen.Ich würdeempfehlen,es als Best Practice zu verwenden.Wouldn't you use $wpdb->prepare() in order to properly protect yourself from tainted data such as what @hakre was talking about? This would also solve the escaping of the '_' as well. I'd recommend using it, as a best practice.
- 0
- 2012-06-22
- Tom Auger
-
@ Tom anders als "um wirklich wirklich sicher zu sein"muss diese spezielle Abfragenicht wirklich vorbereitet werden undich habemichnicht darumgekümmert,sie hinzuzufügen.@Tom other than "to be really really sure" this specific query doesn't really need prepare and I didn't bother to add it.
- 0
- 2012-06-22
- Rarst
-
Dubistgerade da,woichesmir ansehe.Das (int)ist wahrscheinlich dergesamte Schutz,den Siefür diese Servervariablebenötigen.You're right now that I look at it. The (int) probably is all the protection you need on that server variable.
- 0
- 2012-06-22
- Tom Auger
-
Sollteesnicht "_transient_timeout_%" sein?Nur um sicherzugehen,dasses wirklich dasist,was WP als Präfix verwendet?;)Shouldn't it be `_transient_timeout_%`? Just to make sure it really is what WP uses as prefix? ;)
- 0
- 2013-07-28
- kaiser
-
- 2011-09-12
Verschiebeneiniger Kommentare aus der Diskussionin eine Antwortmit Neuformulierung und Neuformatierung.
Grundsätzlich kommtes darauf an,dass sienicht wirklich "Müllgesammelt" werdenmüssen,es sei denn,Sie habeneinen extremen Fall. Wenn Sie sienie abrufen,spieltes keine Rolle,ob sie dort sind odernicht.
Siehe,Transienten werden standardmäßigin der Optionstabellegespeichert. Beieiner Basisinstallationenthält die Optionstabellemöglicherweise 100 Einträge. Jeder Übergangfügt zwei weitere Einträge hinzu,aber selbst wenn Sie Tausende haben,wirken sich diesenicht auf die Geschwindigkeit der Site aus,da sienicht automatischgeladen werden.
Beim Start lädt WordPress die Optionenin den Speicher,lädtjedochnur Optionen,deren Autoload-Flag aktiviertist. Transientenerhalten diesnicht und werden dahernichtin den Speichergeladen. Nur Transienten,die spätertatsächlich verwendet werden,verursachen Kosten.
Aus Sicht der Datenbankenthält die Optionstabelle Indizes sowohlfür die Options-ID als auchfür den Optionsnamen. Transienten werdenimmerbasierend auf dem Namen (Schlüssel)geladen,und daher sind die Suchvorgängefür sieimmereinfache Auswahlenfüreinen einzelneneindeutigen Schlüsselwert. Somitist die Suche O (log (n)) undist superschnell. Miteinem Big-O von log (n)müssten Siein die Millionen und Abermillionen von Zeilengelangen,bevores auffällt. Ehrlichgesagtist der Aufwandbeim Einrichten und Herunterfahren der Abfrage zusammenmit dereigentlichen Datenübertragung viel länger. Die Abfrage selbst wirdim Vergleich dazuim Wesentlichenin der Nullzeit ausgeführt. Daseinfache Vorhandensein zusätzlichernicht verwendeter Zeilen wirkt sich alsonur auf die Verwendung von zusätzlichem Speicherplatz aus.
Die Indizierungin Datenbankenisteine diesertief gelesenen Ideen,diefür Menschen,dienicht wirklich verstanden haben,was sich hinter den Kulissen abspielt,keinen Sinnergibt. Datenbanken sindfüreinen schnellen Datenabruf von Grund auf konzipiert und können solche Problemeproblemlosbewältigen. Diesisteine ziemlichgute Lektüre: http://en.wikipedia.org/wiki/Index_(database )
Wenn Sie siejetzt auf die offensichtlichste Weisebereinigen (indem Sie SQL DELETE aufrufen),werden sienicht wirklich aus der Datenbankgelöscht. Esentfernt sieeinfach aus dem Index undmarkiert die Zeile als "gelöscht". Auch diesistgenau so,wie Datenbankenfunktionieren. Um den Speicherplatztatsächlichfreizugeben,müssen Siefortfahren und anschließendeine OPTIMIERUNGSTABELLE ausführen. Diesist kein schneller Vorgang. Esbraucht Zeit. Wahrscheinlichmehr Zeit alses wertist. Es reicht wahrscheinlichnicht aus,uminsgesamt CPU-Zeit zu sparen.
Wennin einem Fall ständigneue Transienteneingefügt werden,dienicht verwendet werden,müssen Sie stattdessen das zugrunde liegende Problemfinden. Wasist das Einfügen dieser Transienten? Verwenden sieeinen sich ändernden odermutierenden Schlüssel? Wennja,dann sollte das Plugin oder der Code,der dies verursacht,behoben werden,um diesim Grundenicht zutun. Diesist hilfreicher,da der Code,der sienicht ordnungsgemäßerstellt,sie wahrscheinlich auchnicht abruft und somitmehr Arbeit leistet alsnötig.
Andererseits kannes vorkommen,dass Transientenfür soetwas wiejeden Beitragerstellt werden. Dies kannin der Tat durchaus akzeptabel sein. Ichmache das selbstin SFC,umeingehende Kommentare von Facebook zu speichern. Jedem Beitragistein potenzieller Übergang zugeordnet,dh zwei zusätzliche Zeilenpro Beitrag. Wenn Sie 10.000 Beiträge haben,haben Sie (eventuell) 20.000 Zeilenin der Optionstabelle. Diesistnicht schlecht oder langsam,daes wiederum kaumeinen Unterschied zwischen 100 und 20.000 Zeilengibt,soweites die Datenbanken wirklichinteressiert. Esist allesindiziert. Esist verdammt schnell. Sub-Sub-Millisekunden.
Wenn Sie anfangen,in Millionen Zeilen zugelangen,würdeichmir Sorgenmachen. Wenn die Größe der Optionstabelle über Hunderte von Megabyte steigt,wäreichbesorgtgenug,umgenauer hinzuschauen. Im Allgemeinenist diesjedoch kein Problem,außerin extremen Fällen. Esist sicherlich kein Problemfüretwas Kleineres alseine große Nachrichtenseitemit Hunderttausenden von Posts. Undfürjede Site,diegroßgenugist,umein Problem zu sein,sollten Sieeinen externen Objektcache verwenden. In diesem Fall werden die Transienten dort automatisch anstattin der Datenbankgespeichert.
Moving some of the comments from the discussion into an answer, with re-wording and re-formatting..
Basically, what it comes down to is that unless you have a super extreme case, they don't really need to be "garbage collected". If you never fetch them, then it doesn't matter if they're there or not.
See, transients are stored in the options table by default. In a base install, the options table will have maybe 100 entries in it. Each transient adds two more entries, but even if you have thousands, they don't affect the site speed, since they're not autoloaded.
On startup, WordPress loads the options into memory, but it only loads options that have their autoload flag turned on. Transients don't get this, and so don't get loaded into memory. Only transients that get actually used later will incur a cost.
From the database's perspective, the options table has indexes on both the option Id and the option name. Transients are always loaded based on the name (key), and so the lookups for them are always simple selects on a single unique key value. Thus the lookup is O(log(n)) and is super fast. With a Big-O of log(n), you'd have to get into the millions and millions of rows before it became noticable. Frankly, the overhead in the setup and teardown of the query, along with the actual data transfer, is way longer. The query itself runs in essentially zero-time by comparison. So simply having extra unused rows doesn't affect anything but using extra disk space.
Indexing in databases is one of those deep-read kind of ideas that doesn't make sense to people who haven't actually understood what's going on behind the scenes. Databases are designed for fast data retrieval, from the ground up, and can handle this sort of thing without issues. This is a pretty good read: http://en.wikipedia.org/wiki/Index_(database)
Now, cleanup in the most obvious way (calling SQL DELETE on them) doesn't actually delete them from the database. It just removes them from the index and marks the row as "deleted". Again, this is just how databases work. To actually clear up the disk space, you have to then continue on and do an OPTIMIZE TABLE afterwards, and this is not a fast operation. It takes time. Probably more time than it's worth. It's probably not enough to give you a savings in CPU time, in total.
If you have some case that is causing a continual insertion of new transients that are not being used, then you need to find the underlying problem instead. What is inserting these transients? Are they using a changing or mutating key? If so, then the plugin or code causing this should be fixed to, basically, not do that. That will be more helpful, because it's likely that the code that isn't creating them properly also isn't retrieving them, and thus doing more work than it has to do.
On the other hand, there may be a case where transients are being created for something like every post. This may indeed be perfectly acceptable. I do this myself in SFC, to store incoming comments from Facebook. Each post has a potential transient associated with it, which means two extra rows per post. If you have 10k posts, you'll have 20k rows in the options table (eventually). This isn't bad or slow, because again, there's very little difference between 100 rows and 20,000 rows as far as databases really care. It's all indexed. It's fast as heck. Sub-sub-milliseconds.
When you start getting into millions of rows, then I'd be worried. When the options table size increases above hundreds of megabytes, then I'd be concerned enough to take a closer look. But generally speaking, this isn't an issue except for extreme cases. It's certainly not an issue for anything smaller than something like a large news site, with hundreds of thousands of posts. And for any site large enough for it to be a problem, you should be using an external object cache of some sort, and in that case, the transients get automagically stored there instead of in the database.
-
NB: Transienten ohne Ablauf ** werden automatischgeladen,und kein Ablaufist die ** Standardeinstellung **. Wenn alsoeine Anwendung/ein Plugin viele Transientenerstellt und keinen Ablauffestlegt,werdenbei jedem Speicher Speicherblöcke verwendetSeite/Post laden.NB: transients with no expiration **do** get autloaded, and no expiration is the **default**, so where an application / plugin is creating lots of transients and not setting an expiration they will be using chunks of memory on every page/post load.
- 1
- 2013-07-29
- webaware
-
Esgibt keinen Grund,einen "Transienten ohne Ablauf" zu verwenden,da diesgrundsätzlichmit einernormalen "Option"identischist.There is no reason to use a "transient with no expiration", because that is basically identical to a normal "option".
- 0
- 2013-07-29
- Otto
-
Sicher,aber [esist die Standardeinstellung] (http://codex.wordpress.org/Function_Reference/set_transient).Daherfügen viele Plugin-Autorennicht ablaufende Transienten hinzu.Sure, but [it's the default](http://codex.wordpress.org/Function_Reference/set_transient). As such, many plugin authors are adding non-expiring transients.
- 1
- 2013-07-30
- webaware
-
Diesist auchnichtidentischmit einer Option,da siebei Verwendungeines Objektcachesgelöscht wird. Weitere Informationenfinden Sieim [neuesten Artikel zu WPEngine] (http://wpengine.com/2013/02/wordpress-transient-api/).Also, not identical to an option, as it will be purged when using an object cache -- see [recent article on WPEngine](http://wpengine.com/2013/02/wordpress-transient-api/) for details.
- 0
- 2013-07-30
- webaware
-
Die Lösung hieristeinfach: Verwenden Sie diese Pluginsnicht.Siemachenesfalsch.Transienten dürfennicht als Sitzungen verwendet werden,Sie sollten sienicht ohneeinen sinnvollen Ablauf verwenden und sie sollten keinemutierenden oder ändernden Schlüssel haben.Well, the solution here is simple: Don't use those plugins. They're doing it wrong. Transients are not to be used as sessions, you should not use them without a meaningful expiration, and they should not have mutating or changing keys.
- 1
- 2013-07-30
- Otto
-
:) (weilesnicht daran liegt,dass der WordPress-Standardfalschist,oder?):) (because it's not because the WordPress default is wrong, eh?)
- 0
- 2013-07-31
- webaware
-
Kommt darauf an.Was würden Sie dort stattdessen als sinnvollen Standardwertbetrachten?That depends. What would you consider a sensible default value there instead?
- 0
- 2013-07-31
- Otto
-
Sagen wir,7 Tage.Wennein Plugin/Theme-Autoretwas Größeres oder Kleineresmöchte,gibt eres an.Wenn sie das automatische Laden wünschen,sollten siefür den Ablauf (=unendlich) keine 0 angebenmüssen,abergenau das haben sie derzeit,wenn der Ablaufparameter als Ja/Nein-Autoload-Parameter die doppelte Aufgabeerfüllt.Inbeiden Fällen sollte der Standardablaufnicht auch zu Autoload=yes als Standardführen.dasbittet nur um Ärger.Say, 7 days. If a plugin / theme author wants something bigger or smaller, they'll specify it. If they want autoload, they shouldn't have to specify 0 for expiration (= infinity), but that's what they've currently got with the expiration parameter doing double duty as the yes/no autoload parameter. Either way, default expiration shouldn't also lead to autoload=yes as default; that's just asking for trouble.
- 2
- 2013-08-01
- webaware
-
Meiner Meinungnach sollte die Nichtangabeeines Ablaufseinen schwerwiegenden Fehler auslösen und die Websitebeschädigen.Aber dannbin ichnicht verantwortlich.Ein Übergang ohne Ablaufist dumm undbedeutungslos.Wenn Sie den Objektcache verwendenmöchten,verwenden Sie den Objektcacheeinfach direktmit den Funktionen wp_cache.Das heißt,esgibt Tickets,um zukünftige Versionen von WordPress alte Transientenbereinigen zu lassen,hauptsächlich weilesmehr als alles andere "unansehnlich"ist.In my considered opinion, not specifying an expiration should throw a fatal error and break the site. But then I'm not in charge. A transient with no expiration is stupid and meaningless. If you want to use the object cache, then just use the object cache directly with the wp_cache functions. That said, there are tickets to have future version of WordPress clean up old transients, mainly because it's "unsightly" more than anything else.
- 1
- 2014-03-19
- Otto
-
- 2011-12-02
Otto -ich könnte dirnichtmehr widersprechen. Das Problemist,dassmit all diesen Transienten die Größe der Tabelle schließlich lächerlich wird. Esbrauchtnicht Millionen von Reihen,umfestzumachen. Ich habees derzeitmit einer Optionstabelle zutun,die über 130.000 Zeilenenthält und regelmäßig hängt. Daes sichbei dem Wertefeld umeinen großen Texttyp handelt,wird das Suchennachnur den Zeilen zum automatischen Laden zueinem Albtraum der Leistung. Diese Wertefelder werdengetrennt von den übrigen Zeilendatengespeichert. Obwohles logisch Teil derselben Tabelleist,müssen Verknüpfungen stattfinden,um diegewünschten Zeilen aufzurufen. Joins,diejetztewig dauern,da diebenötigten Daten überall auf der Festplatte verteilt sind. Profiling (mit Jet Profilerfür MySQL) hat diesbewiesen.
Das Hinzufügen des automatischen Ladens zum Clustered Key kann zur Lösung dieses Problemsbeitragen. Durch Clustering auf Autoload Desc,z. B. ID ASC,können alle Autoload-Zeilen zuerst auf der Festplatte zusammengefasst werden. Trotzdem denkeich,dass Sie aus Sicht der DBeine enorme Belastung sehen.
Persönlich denkeich,dass das Design dieses Systems verrücktist. Die Optionstabelle scheintfür viele Dinge zueinem allgemeinen Sammelbegriffgeworden zu sein. Dasistin Ordnung,wenn das Wertefeld kleingenugist,um auf derselben Seite wie die übrigen Zeilendatenenthalten zu sein,undeffektivindiziert werden kann. Dasist leidernicht der Fall. Wer diesentworfen hat,muss zur DB101-Klasse zurückkehren.
Otto - I couldn't disagree with you more. The issue is that eventually with all those transients, the size of the table becomes ridiculous. It doesn't take millions of rows to bog down. I'm currently dealing with an options table that has over 130k rows, and hangs regularly. Because the value field is a large text type, even looking for only the "autoload" rows becomes a nightmare of performance. Those value fields are stored separately from the rest of the row data. Even though it's logically part of the same table, joins must happen in order to pull up the rows you want. Joins that now take forever because the data you need is spread all over the place on disk. Profiling (using jet profiler for mysql) has proven this.
Adding auto-load to the clustered key might help solve this problem. Clustering on Autoload Desc, ID ASC for example, would allow all the autoload rows to bunch together first on disk. Even still I think you're looking at a huge strain from a DB perspective.
Personally I think the design of this system is wack. The options table seems to have turned into a general catch-all for a lot of things. That's fine if the value field is small enough to be included on the same page as the rest of the rowdata, and can be indexed effectively. Unfortunately that's not the case. Whoever designed this needs to go back to DB101 class.
-
stimmt,aberbedenken Sie,dass zu Beginn der WordPress-Entwicklungniemand darangedacht hat,dass Tausende von Plugins die Optionstabelle als Datenspeicher verwenden werden :)true, but consider that when WordPress development started, nobody thought that it would reach to have thousands of plugins using options table as their data storage :)
- 5
- 2011-12-02
- onetrickpony
-
@onetrickpony Deshalbistes wichtig,sichimmer Zeit zunehmen und die Dinge richtig zumachen,ob Sieerwarten,dasseseines Tages riesig wird odernicht :)@onetrickpony that's why it's important to always take your time and do things right, whether you expect it to be huge someday or not :)
- 0
- 2017-12-11
- Mahmoud Al-Qudsi
Diese Fragebrachtemich zum Nachdenken Transiente RSS-Feedswp_optionsnicht automatischentfernt?
Transienten sollen ablaufen undgelöscht werden.Ich sehe diesjedochnur,wenn der Übergang abgelaufen und angefordertist under dann während der Anforderunggelöscht wird.
Wasist,wenn der Übergang abgelaufenist,danach abernie mehr angefordert wird?Aus der Beschreibungim Codexging hervor,dasseine Art Speicherbereinigungimpliziertist.Jetztbin ichmirnicht so sicher und kann keinen Codefinden,der dies ausführt.
Wirdes alsofürimmerin der Datenbank steckenbleiben?