I rifiuti transitori vengono raccolti?


61

Questa domanda mi ha fatto pensare che i feed RSS transitori in wp_options non siano stati rimossi automaticamente?

I transitori dovrebbero scadere ed essere eliminati. Tuttavia, l'unico modo per vedere questo gestito è quando il transitorio è scaduto e richiesto, quindi viene eliminato durante la richiesta.

Cosa succede se il transitorio è scaduto ma non è mai stato richiesto dopo? Dalla descrizione nel Codice ho pensato che fosse implicito un qualche tipo di raccolta dei rifiuti. Ora non sono così sicuro e non riesco a trovare alcun codice che esegua tale.

Quindi sarà bloccato nel database per sempre?


teoricamente dovrebbero essere rimossi quando cron viene eseguito (se sono scaduti)
onetrickpony

1
@Ambiziosa Amoeba sì, l'ho già detto in questione. Il punto è che la creazione temporanea non presuppone né garantisce che verrà mai richiesta. Sottolineando la domanda originale: quando e se il transitorio scaduto viene eliminato se non lo capisco mai ?
Rarst

1
suppone che tu pulisca i dati scaduti, ma sì, hai ragione, ci sono situazioni in cui non verrebbero mai cancellati. Come rimuovere un widget che utilizza i transitori. Per questo devi inviare un biglietto sul trac :)
onetrickpony,

1
@Rarst - Sembra una cosa perfetta per cui scrivere una patch e inviarla a trac?
MikeSchinkel,

Risposte:


45

Lo sono adesso

A partire da WordPress 3.7 i transitori scaduti vengono eliminati con gli aggiornamenti del database, vedere # 20316


Vecchia risposta

Se qualcuno non può mostrarmi il contrario, sembra che i transitori non siano spazzatura raccolti dopo tutto. Ciò che rende peggio è che a differenza delle opzioni non è garantito che siano archiviate nel database. Quindi non esiste un modo affidabile per recuperare l'elenco di tutti i transitori per verificarne la scadenza.

Alcuni codici improvvisati per eseguire la garbage collection se il database viene utilizzato per l'archiviazione:

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']; e quindi facendo uso di $ time nella query SQL, non farlo. Trattare con più attenzione con variabili / valori $ _SERVER per prevenire iniezioni di SQL.
Hakre,

@hakre hm ... L'ho preso dalla presentazione sulle prestazioni di PHP che lo ha raccomandato sull'uso time()che può causare bug (l'esecuzione non è istantanea per natura). Il tempo di richiesta viene impostato dallo stesso PHP, non proviene da alcun tipo di dati forniti dall'utente. Perché questa vulnerabilità?
Rarst

@Rarst: non ho detto che non dovresti usarlo, devi solo assicurarti che sia codificato in modo sicuro per essere utilizzato all'interno della query SQL. Dovresti farlo con ogni variabile da una fonte esterna. Le variabili $ _SERVER potrebbero non essere impostate come previsto e, al contrario, impostate dall'utente richiedente anche. Volevo solo propagare alcune buone pratiche di programmazione. Come sempre, per conoscere il reale stato di disponibilità, consultare i documenti. Per PHP 4, ad esempio, tale variabile non esiste e potrebbe essere sovrascritto da un header personalizzato o variabile di ambiente - php.net/manual/en/reserved.variables.server.php
hakre

@hakre risolto (penso), grazie per il promemoria PHP4 a proposito (non vedo l'ora che WordPress ne
rilasci il

Ai miei occhi sembra molto meglio;). Speriamo che non ci siano problemi con time () e numeri interi negativi che potrebbero cancellare tutti o nessun transiente che per caso. Non fidarti mai di un sistema in esecuzione: P
hakre,

20

Spostando alcuni dei commenti della discussione in una risposta, con riformattazione e riformattazione.

Fondamentalmente, ciò che si riduce è che a meno che tu non abbia un caso super-estremo, non hanno davvero bisogno di essere "spazzatura". Se non li prendi mai, non importa se sono lì o no.

Vedi, i transitori sono memorizzati nella tabella delle opzioni di default. In un'installazione di base, la tabella delle opzioni avrà forse 100 voci al suo interno. Ogni transitorio aggiunge altre due voci, ma anche se ne hai migliaia, non influiscono sulla velocità del sito, poiché non sono caricate automaticamente.

All'avvio, WordPress carica le opzioni in memoria, ma carica solo le opzioni che hanno il loro flag di caricamento automatico attivato. I transitori non ottengono questo e quindi non vengono caricati in memoria. Solo i transitori che verranno effettivamente utilizzati in seguito comportano un costo.

Dal punto di vista del database, la tabella delle opzioni ha indici sia sull'ID opzione sia sul nome dell'opzione. I transitori vengono sempre caricati in base al nome (chiave), quindi le ricerche per essi sono sempre semplici selezioni su un singolo valore chiave univoco. Quindi la ricerca è O (log (n)) ed è super veloce. Con un Big-O di log (n), dovresti entrare in milioni e milioni di righe prima che diventasse evidente. Francamente, il sovraccarico nell'installazione e nello smontaggio della query, insieme al trasferimento effettivo dei dati, è molto più lungo. La query stessa viene eseguita essenzialmente a tempo zero in confronto. Quindi il semplice fatto di avere righe inutilizzate in più non ha alcun effetto se non l'utilizzo di spazio su disco aggiuntivo.

L'indicizzazione nei database è uno di quei tipi di idee approfondite che non hanno senso per le persone che non hanno davvero capito cosa sta succedendo dietro le quinte. I database sono progettati per il recupero rapido dei dati, da zero, e possono gestire questo tipo di cose senza problemi. Questa è una lettura abbastanza buona: http://en.wikipedia.org/wiki/Index_(database )

Ora, la pulizia nel modo più ovvio (chiamando SQL DELETE su di essi) in realtà non li elimina dal database. Li rimuove semplicemente dall'indice e contrassegna la riga come "eliminata". Ancora una volta, è così che funzionano i database. Per liberare effettivamente lo spazio su disco, è necessario continuare e fare una TABELLA OTTIMALE in seguito, e questa non è un'operazione veloce. Richiede tempo. Probabilmente più tempo di quanto valga la pena. Probabilmente non è abbastanza per darti un risparmio nel tempo della CPU, in totale.

Se hai qualche caso che causa un inserimento continuo di nuovi transitori che non vengono utilizzati, devi invece trovare il problema sottostante. Cosa sta inserendo questi transitori? Stanno usando una chiave mutevole o mutante? In tal caso, il plug-in o il codice che causa questo problema dovrebbe essere risolto, in pratica, per non farlo. Ciò sarà più utile, perché è probabile che anche il codice che non li sta creando correttamente non li stia recuperando, e quindi facendo più lavoro di quello che deve fare.

D'altra parte, potrebbe esserci un caso in cui vengono creati transitori per qualcosa come ogni post. Questo può davvero essere perfettamente accettabile. Lo faccio anch'io in SFC, per memorizzare i commenti in arrivo da Facebook. Ogni post ha un potenziale transitorio associato, il che significa due righe extra per post. Se hai post da 10k, avrai 20k righe nella tabella delle opzioni (eventualmente). Questo non è male o lento, perché, di nuovo, c'è ben poca differenza tra 100 e 20.000 righe per quanto riguarda i database. È tutto indicizzato. È veloce come diamine. Sub-sub-millisecondi.

Quando inizi a entrare in milioni di file, allora sarei preoccupato. Quando la dimensione della tabella delle opzioni aumenta oltre le centinaia di megabyte, allora sarei abbastanza preoccupato da dare un'occhiata più da vicino. Ma in generale, questo non è un problema tranne che per casi estremi. Non è certamente un problema per qualcosa di più piccolo di qualcosa come un grande sito di notizie, con centinaia di migliaia di post. E per qualsiasi sito abbastanza grande da essere un problema, dovresti utilizzare una cache di oggetti esterna di qualche tipo e, in tal caso, i transitori vengono archiviati automagicamente lì invece che nel database.


1
NB: transitori senza scadenza non ottenere autloaded, e nessuna scadenza è il valore predefinito , in modo in cui una domanda / plugin sta creando un sacco di transitori e che non stabilisce una scadenza useranno blocchi di memoria su ogni caricamento della pagina / post.
webaware,

Non vi è alcun motivo per utilizzare un "transitorio senza scadenza", perché sostanzialmente identico a una normale "opzione".
Otto

1
Certo, ma è l'impostazione predefinita . Pertanto, molti autori di plugin stanno aggiungendo transitori non in scadenza.
webaware,

1
Bene, la soluzione qui è semplice: non usare questi plugin. Lo stanno facendo male. I transitori non devono essere utilizzati come sessioni, non è necessario utilizzarli senza una scadenza significativa e non devono avere chiavi mutanti o modificanti.
Otto

2
Dì, 7 giorni. Se un autore di plugin / temi desidera qualcosa di più grande o più piccolo, lo specificherà. Se vogliono il caricamento automatico, non dovrebbero specificare 0 per scadenza (= infinito), ma è quello che hanno attualmente con il parametro di scadenza che fa doppio dovere come parametro di caricamento automatico sì / no. In entrambi i casi, la scadenza predefinita non dovrebbe comportare anche il caricamento automatico = yes come predefinito; questo è solo chiedere guai.
webaware

18

Otto - Non potrei essere più in disaccordo con te. Il problema è che alla fine con tutti quei transitori, la dimensione del tavolo diventa ridicola. Non ci vogliono milioni di file per impantanarsi. Attualmente ho a che fare con una tabella di opzioni che ha oltre 130k righe e si blocca regolarmente. Poiché il campo del valore è un tipo di testo di grandi dimensioni, anche la ricerca solo delle righe di "caricamento automatico" diventa un incubo di prestazioni. Tali campi valore sono memorizzati separatamente dal resto dei dati della riga. Anche se fa logicamente parte della stessa tabella, i join devono avvenire per estrarre le righe desiderate. Join che ora impiegano un'eternità perché i dati necessari sono sparsi ovunque sul disco. La profilazione (utilizzando Jet Profiler per mysql) lo ha dimostrato.

L'aggiunta del caricamento automatico alla chiave cluster può aiutare a risolvere questo problema. Il clustering su Autoload Desc, ad esempio ID ASC, consentirebbe a tutte le righe di caricamento automatico di raggrupparsi prima sul disco. Anche ancora penso che tu stia osservando un'enorme tensione dal punto di vista del DB.

Personalmente penso che il design di questo sistema sia stravagante. La tabella delle opzioni sembra essersi trasformata in un accorgimento generale per molte cose. Va bene se il campo del valore è abbastanza piccolo da essere incluso nella stessa pagina del resto dei dati della riga e può essere indicizzato in modo efficace. Sfortunatamente non è così. Chiunque abbia progettato questo deve tornare alla classe DB101.


5
vero, ma considera che quando iniziò lo sviluppo di WordPress, nessuno pensava che sarebbe stato possibile avere migliaia di plug-in che utilizzavano la tabella delle opzioni come archivio dati :)
onetrickpony,

@onetrickpony è per questo che è importante prenderti sempre il tuo tempo e fare le cose nel modo giusto, che tu ti aspetti che sia un giorno enorme o no :)
Mahmoud Al-Qudsi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.