Stavo armeggiando VACUUM
e ho notato alcuni comportamenti inaspettati in cui le SELECT
righe da una tabella sembrano ridurre il lavoro VACUUM
da 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 SELECT
dopo,
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 SELECT
rimosso le tuple morte dalle pagine che visita, è abbastanza simile VACUUM
?
Sto eseguendo Postgres 11.3 su macOS 10.14.5.