Autovacuum запускає вакуум для таблиці, коли кількість мертвих рядків перевищить поріг:
поріг = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor × кількість рядків
= 50 + 0.2 × кількість рядків
Тобто вакуум починається, коли змінено 20% таблиці. Для таблиці на 100 мільйонів рядків - це 20 мільйонів мертвих версій до першого вакууму: таблиця роздута, запити повільні.
Налаштування для конкретних таблиць:
ALTER TABLE orders SET (
autovacuum_vacuum_scale_factor = 0.01, -- 1% замість 20%
autovacuum_analyze_scale_factor = 0.005
);
-- таблиця-черга з постійними вставками й видаленнями
ALTER TABLE jobs SET (
autovacuum_vacuum_scale_factor = 0,
autovacuum_vacuum_threshold = 1000 -- кожні 1000 мертвих рядків
);
Швидкість роботи вакууму. Autovacuum навмисно сповільнений, щоб не заважати запитам (autovacuum_vacuum_cost_limit, autovacuum_vacuum_cost_delay). На сучасних SSD значення за замовчуванням часто занадто обережні - вакуум не встигає за змінами. Типове рішення - збільшити autovacuum_vacuum_cost_limit (глобально чи для таблиці).
Кількість воркерів: autovacuum_max_workers (за замовчуванням 3). Якщо великих таблиць багато, воркери зайняті на одній, а інші чекають.
Як зрозуміти, що вакуум не встигає:
SELECT relname, n_live_tup, n_dead_tup,
round(100.0 * n_dead_tup / nullif(n_live_tup + n_dead_tup, 0), 1) AS dead_percent,
last_autovacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
Високий відсоток мертвих рядків і давній last_autovacuum - сигнал.
Якщо вакуум працює, а мертві рядки не зникають - його блокує довга транзакція, забутий слот реплікації чи prepared transaction. Налаштування тут не допоможуть: потрібно прибрати те, що утримує горизонт.
Не вимикати autovacuum «бо він навантажує сервер» - без нього таблиці роздуваються, а лічильник транзакцій наближається до переповнення.