Ne vale la pena eseguire VACUUM su una tabella che riceve solo INSERT?


19

In un discorso del 2015 su: Invent, AWS ha affermato che il vuoto dovrebbe essere eseguito non solo dopo gli aggiornamenti o le eliminazioni, ma anche dopo gli inserimenti. Ecco la parte rilevante del discorso:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Presumibilmente, è necessario eseguire alcuni cleanup sui blocchi anche se hanno ricevuto solo inserti e questo cleanup può essere eseguito sia la prima volta che si seleziona un blocco (rallentamento delle letture) sia durante il vuoto. È vero e, in tal caso, esattamente quale pulizia deve essere eseguita?

Risposte:


15

tl; dr: il primo processo che legge i dati dopo il commit imposta bit di suggerimento. Ciò sporcherà la pagina, creando attività di scrittura. L'altra cosa VACUUM(ma non altri comandi) è contrassegnare la pagina come tutto visibile, se appropriato. VACUUMalla fine dovrà colpire il tavolo per congelare le tuple.

Il lavoro che deve essere fatto dopo un inserto non è realmente pulito, almeno non nel senso dell'altro lavoro VACUUMnormalmente. Prima di entrare nei dettagli, nota che questa risposta si basa sul codice 9.6 (inedito) corrente e sto ignorando gli effetti della replica in streaming, anche se può influire sulla visibilità.

A causa di MVCC , ogni volta che Postgres valuta se una tupla deve essere visibile a una query, deve considerare se la transazione che ha creato la tupla (registrata nel campo nascosto xmin) ha eseguito il commit, insieme ad alcuni altri criteri. Tale controllo è costoso, quindi non appena è noto che una transazione è visibile a tutte le transazioni attualmente aperte, nell'intestazione della tupla viene impostato un "bit di suggerimento". L'impostazione di quel bit sporca la pagina, il che significa che dovrà essere scritta su disco. Questo può essere molto confuso se il prossimo comando per leggere i dati è un SELECTche sta improvvisamente creando molto traffico di scrittura. Eseguire un VACUUMdopo l'inserimento dell'inserimento lo eviterà. Un'altra importante distinzione è quellaVACUUMsuggerirà SEMPRE le tuple su una pagina (purché abbia il blocco di pulizia sulla pagina), ma la maggior parte degli altri comandi suggerirà solo se la transazione di inserimento è stata impegnata prima dell'avvio del comando.

Un punto importante sulla scrittura di tutti questi bit di suggerimento è che VACUUMpuò essere limitato (e l'autovacuum è limitato per impostazione predefinita). Altri comandi non sono limitati e genereranno dati sporchi il più rapidamente possibile.

VACUUMè l'unico metodo per contrassegnare le pagine come completamente visibili, che è una considerazione importante delle prestazioni per alcune operazioni (in particolare, le scansioni solo dell'indice). Se si esegue un inserto di grandi dimensioni, è molto probabile che ci siano molte pagine con nient'altro che tuple appena inserite. VACUUMpuò potenzialmente contrassegnare quelle pagine come completamente visibili, ma solo se la transazione in esecuzione più vecchia all'avvio VACUUMera più recente della transazione che ha inserito i dati .

A causa del funzionamento di MVCC, le tuple inserite più di ~ 2 miliardi di transazioni fa devono essere contrassegnate come " congelate ". Per impostazione predefinita, l'autovacuum prenderà il via per farlo ogni 200 milioni di transazioni. L'esecuzione di un vuoto manuale con vacuum_freeze_min_age impostato su 0 dopo un inserimento in blocco può contribuire a ridurne l'impatto. Più aggressivamente, potresti eseguire VACUUM FREEZEsul tavolo dopo l'inserimento. Ciò "reimposterebbe l'orologio" quando si verifica la successiva scansione congelata.

Se vuoi conoscere i dettagli specifici, dai un'occhiata al HEAPTUPLE_LIVEcaso dopo la chiamata HeapTupleSatisfiesVacuum()all'interno lazy_scan_heap(). Vedi anche HeapTupleSatisfiesVacuum()se stesso e confrontalo con HeapTupleSatisfiesMVCC().

Ci sono altre due mie presentazioni che potrebbero essere interessanti. Il primo video è disponibile da http://www.pgcon.org/2015/schedule/events/829.en.html , mentre il secondo (che penso fosse un po 'meglio) su https://www.youtube. com / watch? v = L8nErzxPJjQ


Questo è molto interessante, e spiega anche alcune pagine sporche in alcuni EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least * COMMITTED` e *INVALID) può (potrebbe) essere già impostato dal COMMITo ROLLBACK, giusto?
dezso

3
COMMIT e ROLLBACK in realtà non toccano le pagine di dati, quindi no, quei comandi in particolare non potrebbero mai suggerire. Un comando DML potrebbe comunque impostare gli stati dei suggerimenti xmin e xmax, sia per le tuple contrassegnate da altre transazioni sia per le potenzialmente tuple contrassegnate dalla transazione corrente.
Jim Nasby,
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.