SELECT rimuove le righe morte come fa VACUUM?


9

Stavo armeggiando VACUUMe ho notato alcuni comportamenti inaspettati in cui le SELECTrighe da una tabella sembrano ridurre il lavoro VACUUMda svolgere in seguito.

Dati di test

Nota: l'autovacuum è disabilitato

CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
  autovacuum_enabled = 'f',
  toast.autovacuum_enabled = 'f'
);

INSERT INTO numbers SELECT generate_series(1, 5000);

Prova 1

Ora eseguiamo un aggiornamento su tutte le righe,

UPDATE numbers SET num = 0;

E quando corriamo VACUUM (VERBOSE) numbers;otteniamo,

INFO:  vacuuming "public.numbers"
INFO:  "numbers": removed 5000 row versions in 23 pages
INFO:  "numbers": found 5000 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 6585
There were 0 unused item pointers.

Prova 2

Ora emettiamo un altro UPDATE, ma questa volta aggiungiamo un SELECTdopo,

UPDATE numbers SET num = 1;
SELECT * FROM numbers;

E quando corriamo VACUUM (VERBOSE) numbers;otteniamo,

INFO:  vacuuming "public.numbers"
INFO:  "numbers": removed 56 row versions in 22 pages
INFO:  "numbers": found 56 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 6586
There were 56 unused item pointers.

Cosa sta succedendo esattamente qui? Perché la seconda versione che eseguo, dopo aver SELECTrimosso le tuple morte dalle pagine che visita, è abbastanza simile VACUUM?

Sto eseguendo Postgres 11.3 su macOS 10.14.5.


2
Quale client usi per eseguire i tuoi comandi? Autocommit è abilitato in esso?
Mustaccio,

2
Ho intenzione di eliminare la domanda "La tabella VACUUM è praticamente SELEZIONA * DA tabella sotto il cofano?" (Non lo è) Penso che sia un buon follow-up, la risposta qui è semplicemente che SELECT può rimuovere le righe morte e lo condivide in comune con VACUUM. La differenza tra loro sarà una conversazione molto esaustiva sul rollover XID e una tonnellata di altre cose. Questa domanda è fondamentalmente "Quali altre cose fa il vuoto oltre a rimuovere le file morte". (Che sarebbe un po 'vago)
Evan Carroll,

@mustaccio Ho fatto questi test con uno script Ruby usando ActiveRecord, che usa la gemma PG sotto il cofano. Credo che autocommit sia abilitato di default in quanto non è necessario emettere COMMIT a meno che BEGIN non venga utilizzato in modo esplicito.
rafbm

Risposte:


5

Da questo post su / r / PostgreSQL a una risposta di Laurenz Albe sembra che gli aggiornamenti di Heap Only Tuples (HOT) possano essere responsabili. Dalla descrizione degli aggiornamenti CALDI insrc/backend/access/heap/README.HOT

In effetti, il recupero dello spazio avviene durante il recupero della tupla quando la pagina è quasi piena (<10% libero) e può essere acquisito un blocco di pulizia del buffer. Ciò significa che UPDATE, DELETEe SELECTpuò innescare il recupero dello spazio, ma spesso non durante INSERT ... VALUESperché non recupera una riga.

La citazione non è nella risposta originale, ma il resto è una citazione,

Per supportare o confutare questa teoria, eseguire la query seguente:

SELECT n_tup_upd, n_tup_hot_upd
FROM pg_stat_user_tables
WHERE schemaname = 'public' AND relname = 'TABLE_NAME';

Se n_tup_hot_updè maggiore di zero, abbiamo un caso.


Ora stiamo parlando. +1
mustaccio

CALDO sembra essere una buona spiegazione. Se I CREATE INDEX idx_numbers ON numbers USING btree (num), l'uscita VACUUM diventa INFO: "numbers": removed 5000 row versions in 45 pages. Si noti tuttavia che nello scenario senza indice, n_tup_hot_updè sempre 0, sia tra UPDATE e SELECT sia tra SELECT e VACUUM. Mi sono anche assicurato di passare SELECT pg_sleep(10)da una istruzione all'altra in modo che le statistiche siano aggiornate (vedo seq_scan: 2, una per l'UPDATE e una per il SELECT).
rafbm,

In questo caso, la selezione genera WAL? Ho avuto l'impressione che seleziona non generi affatto WAL. Se sì, ciò significherebbe che la rimozione di file morte viene propagata a tutti gli schiavi. In caso contrario, significa che l'aspirazione è ancora necessaria sullo slave. Significherebbe anche che i padroni e gli schiavi non sono un po 'identici. Forse dovrei fare qualche ricerca e pubblicare una domanda e / o una risposta o due.
Colin 't Hart,

1

Nel caso speciale di una tabella non indicizzata, sì, SELECT può fare lo stesso lavoro di VACUUM (per quanto riguarda la rimozione delle righe morte).


3
Potresti aggiungere una spiegazione?
Laurenz Albe,
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.