Настраиваем автоочистку на 10 % строк.
=> ALTER SYSTEM SET autovacuum_vacuum_threshold = 0;
ALTER SYSTEM
=> ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.1;
ALTER SYSTEM
Устанавливаем частоту запуска процессов в 1 раз в секунду:
=> ALTER SYSTEM SET autovacuum_naptime = '1s';
ALTER SYSTEM
=> SELECT pg_reload_conf();
pg_reload_conf ---------------- t (1 row)
=> CREATE DATABASE mvcc_autovacuum;
CREATE DATABASE
=> \c mvcc_autovacuum
You are now connected to database "mvcc_autovacuum" as user "postgres".
=> CREATE TABLE t(n integer);
CREATE TABLE
=> INSERT INTO t(n) SELECT 1 FROM generate_series(1,100000);
INSERT 0 100000
Начальный размер таблицы:
=> SELECT pg_size_pretty(pg_table_size('t'));
pg_size_pretty ---------------- 3168 kB (1 row)
Выполняем обновление таблицы с задержками в несколько секунд между командами.
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5584
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5421
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5422
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5509
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5522
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5528
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5396
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5513
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5501
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5397
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5431
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5472
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5477
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5453
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5353
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5497
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5470
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5475
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5557
=> UPDATE t SET n = n + 1 WHERE random() < 0.055;
UPDATE 5548
Статистика по таблице (autovacuum_count - сколько раз выполнялась автоочистка):
=> SELECT * FROM pg_stat_all_tables WHERE relname='t' \gx
-[ RECORD 1 ]-------+------------------------------ relid | 25124 schemaname | public relname | t seq_scan | 20 seq_tup_read | 2000000 idx_scan | idx_tup_fetch | n_tup_ins | 100000 n_tup_upd | 109526 n_tup_del | 0 n_tup_hot_upd | 67610 n_live_tup | 100000 n_dead_tup | 5548 n_mod_since_analyze | 5548 last_vacuum | last_autovacuum | 2019-08-12 17:19:50.669151+03 last_analyze | last_autoanalyze | 2019-08-12 17:19:50.767039+03 vacuum_count | 0 autovacuum_count | 5 analyze_count | 0 autoanalyze_count | 9
Вот как увеличилась таблица:
=> SELECT pg_size_pretty(pg_table_size('t'));
pg_size_pretty ---------------- 4192 kB (1 row)
Суммарно изменилось порядка 110000 строк, что составляет 110% от размера таблицы. Можно было бы предположить, что автоочистка сработает 10-11 раз.
Однако автоочистка выполнялась примерно в два раза реже, поскольку существенная часть обновлений была оптимизирована внутристраничной очисткой (в нашем случае, HOT-очисткой: поле n_tup_hot_upd).
Таблица увеличилась не в два раза, а меньше - примерно на треть. В идеале достаточно было бы 5-6 %, но: