Формула срабатывания
порог = autovacuum_vacuum_threshold
+ autovacuum_vacuum_scale_factor × reltuples
По умолчанию threshold = 50, scale_factor = 0.2: уборка запускается,
когда n_dead_tup превысит 50 + 20% от числа живых строк. Для миллиона
строк это больше 200 тысяч мёртвых версий.
SELECT relname, n_live_tup, n_dead_tup,
50 + 0.2 * n_live_tup AS av_threshold
FROM pg_stat_all_tables WHERE relname = 'bloat_demo';
Почему 0.2 плох для больших таблиц
Порог пропорционален размеру. 20% от 100 млн строк - это 20 млн мёртвых версий, которые лежат раздутым грузом между уборками. Поэтому крупным и горячим таблицам задают индивидуальный, меньший порог:
ALTER TABLE big_events SET (
autovacuum_vacuum_scale_factor = 0.02,
autovacuum_vacuum_threshold = 1000
);
Настройка таблицы переопределяет глобальную. Один общий scale_factor
почти никогда не оптимален.
Порог по вставкам (PG13+)
Append-only таблицы не создают мёртвых версий, и раньше autovacuum их не
трогал - страдали index-only сканы и заморозка. С PostgreSQL 13 есть
отдельный порог autovacuum_vacuum_insert_threshold (1000) +
autovacuum_vacuum_insert_scale_factor (0.2), и такие таблицы тоже
регулярно проходят VACUUM.
Bloat и его измерение
Раздувание - место под мёртвыми версиями и пустотами; симптом того, что
VACUUM не поспевает. Измеряют через pgstattuple (dead_tuple_percent,
free_percent); на больших таблицах берут pgstattuple_approx из-за
полного скана. Вернуть место ОС умеет только VACUUM FULL или pg_repack
(см. vacuum).
Поймать за работой
SELECT relname, last_autovacuum, autovacuum_count
FROM pg_stat_all_tables WHERE relname = 'bloat_demo';
SELECT relid::regclass, phase, heap_blks_scanned, heap_blks_total
FROM pg_stat_progress_vacuum;
autovacuum=off — дорогая ошибка
Отключение останавливает уборку (растёт bloat) и заморозку (возраст ползёт к 200 млн, см. wraparound). Анти-wraparound autovacuum всё равно сработает, но как аврал на пике. Правильная реакция на «autovacuum мешает»
- сделать его агрессивнее (больше воркеров, меньше
cost_delay, индивидуальные пороги), а не выключать.