Autovacuum launcher
Autovacuum launcher — это фоновый процесс PostgreSQL, который не выполняет очистку напрямую, а запускает рабочие процессы autovacuum worker, когда базе данных требуется автоматическая очистка (vacuum) или анализ (analyze).
Он — «диспетчер» автоматической очистки, а не исполнитель
Autovacuum launcher — это фоновый процесс PostgreSQL, который не выполняет очистку напрямую, а запускает рабочие процессы autovacuum worker, когда базе данных требуется автоматическая очистка (vacuum) или анализ (analyze).
Autovacuum launcher — это «надзиратель» MVCC, который:
- Следит за состоянием таблиц,
- Запускает уборку (VACUUM) и анализ (ANALYZE) по мере необходимости,
- Предотвращает раздувание данных и деградацию планов запросов.
MVCC, Vacuum - Механизм пометки строк как удаленные
Без него PostgreSQL со временем остановился бы из-за:
- Переполнения диска (bloat),
- Невозможности найти свободное место на страницах,
- Плохих планов из-за устаревшей статистики.
Формула запуска VACUUM:
мёртвые_строки ≥ autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor × общее_число_строк
Главная задача Autovacuum launcher
Мониторить состояние таблиц в фоне и запускать
autovacuum workerдля тех из них, где накопилось достаточно «мёртвых» строк или изменилась статистика.
«мёртвыe» строки - В PostgreSQL при выполнении Delete строка не удаляется сразу а помечается как удаленная, в ней меняются некоторые поля метаданных. Это ускоряет работу, не приходится в текущий момент совершать множество дополнительных операций:
- Строка остаётся на диске, в том же 8 КБ-блоке
- Не требуется сдвигать другие строки, чтобы «заткнуть дыру».
- Не нужно обновлять указатели в индексах, ведущие к этой строке.
Без MVCC: удаление → фрагментация → необходимость
VACUUM FULLилиREINDEX.
- Страница не перезаписывается, не вызывается
fsync().- Нет необходимости обновлять free space map (FSM) сразу.
Без него MVCC в PostgreSQL привёл бы к неограниченному раздуванию (bloat) и устаревшей статистике, что убивает производительность.
Как это работает (по шагам)
- При старте кластера
postmasterзапускает один процессautovacuum launcher. - Launcher периодически (раз в
autovacuum_naptime, по умолчанию — 1 минута) сканирует все таблицы во всех базах данных. - Для каждой таблицы он проверяет:
- Сколько мёртвых строк накопилось (по данным из
pg_stat_user_tables.n_dead_tup), - Насколько устарела статистика (по числу изменений и
pg_statistic).
- Сколько мёртвых строк накопилось (по данным из
- Если таблица превысила пороги (на основе
autovacuum_vacuum_threshold,autovacuum_vacuum_scale_factorи аналогов дляANALYZE) →
→ запускаетautovacuum workerдля этой таблицы. - Worker выполняет:
VACUUM— удаляет мёртвые строки, обновляет visibility map,- и/или
ANALYZE— собирает статистику для планировщика.
Ключевые параметры
| Параметр | По умолчанию | Роль |
|---|---|---|
autovacuum | on | Включена ли автоматическая очистка |
autovacuum_naptime | 1min | Как часто launcher проверяет таблицы |
autovacuum_vacuum_threshold | 50 | Минимум «мёртвых» строк для запуска VACUUM |
autovacuum_vacuum_scale_factor | 0.2 | Доля от общего числа строк (например, 20%) |
autovacuum_max_workers | 3 | Макс. число одновременных worker’ов |
autovacuum_vacuum_cost_delay | 20ms | Задержка для ограничения I/O (на worker’а) |
Важные нюансы
- Один launcher — на весь кластер, но он обслуживает все базы данных.
- Несколько worker’ов могут работать одновременно (до
autovacuum_max_workers). - Launcher не запускает worker для таблиц, где
autovacuum_enabled = false. - Если все worker’ы заняты — launcher ожидает, пока один освободится.
- При очень высокой нагрузке на запись launcher может не успевать → bloat растёт → нужно настраивать пороги или увеличивать число worker’ов.
Мониторинг
-- Текущие autovacuum-процессы
SELECT pid, query FROM pg_stat_activity
WHERE query LIKE 'autovacuum%';
-- Статистика по таблицам
SELECT schemaname, tablename,
n_tup_ins, n_tup_upd, n_tup_del,
n_dead_tup,
last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
WHERE n_dead_tup > 0;Autovacuum worker ^psql-autovacuum-worker
Autovacuum worker — это фоновый процесс PostgreSQL, который выполняет реальную работу по очистке (VACUUM) и анализу (ANALYZE) таблиц, когда это необходимо для поддержания производительности и целостности MVCC.
Он запускается Autovacuum launcher’ом и работает непосредственно с данными, в отличие от launcher’а, который только принимает решения.
- Это отдельный ОС-процесс, запускаемый
postmasterпо запросу Autovacuum launcher’а. - В
ps auxвы увидите:
postgres: autovacuum: VACUUM public.orders
postgres: autovacuum: ANALYZE public.usersМожет быть до autovacuum_max_workers одновременных worker’ов (по умолчанию — 3).
Главные задачи Autovacuum worker
1. Очистка мёртвых строк (VACUUM)
- В PostgreSQL при
UPDATE/DELETEстарые версии строк не удаляются сразу (MVCC). - Со временем это приводит к bloat — таблица раздувается, замедляется сканирование.
- Worker находит мёртвые строки, которые больше не нужны ни одной активной транзакции, и:
- Помечает их пространство как свободное для повторного использования,
- Обновляет Visibility Map (файл
_vm) — чтобы при последующих сканированиях можно было пропускать целые страницы.
Это не уменьшает физический размер файла таблицы (только
VACUUM FULLэто делает), но освобождает место внутри файла.
2. Сбор статистики (ANALYZE)
- Планировщик PostgreSQL строит планы запросов на основе статистики (
pg_statistic). - Если статистика устарела — планы становятся неоптимальными.
- Worker:
- Сканирует часть таблицы,
- Собирает данные о распределении значений,
- Обновляет
pg_statistic.
Это критично для сложных условий (
WHERE,JOIN,GROUP BY).
3. Предотвращение wraparound транзакций
- XID в PostgreSQL — 32-битный, циклический (от 0 до ~4 млрд).
- Если не обновлять frozen XID, старые транзакции могут «завернуться» и стать будущими → катастрофа.
- Worker «замораживает» очень старые строки (устанавливает
xmin = FrozenTransactionId), чтобы они были видны всегда. - Это обязательная операция, иначе PostgreSQL останавливает все записи, чтобы избежать потери данных.
При приближении к autovacuum_freeze_max_age (по умолчанию 200 млн XID) autovacuum усиливается принудительно.
Как выбирается таблица для обработки?
Worker получает от launcher’а конкретную таблицу и тип операции (VACUUM, ANALYZE или оба).
Решение принимается на основе:
| Условие | Действие |
|---|---|
n_dead_tup ≥ threshold | Запуск VACUUM |
n_mod_since_analyze ≥ threshold | Запуск ANALYZE |
age(datfrozenxid) ≥ autovacuum_freeze_max_age | Принудительный VACUUM с freeze |
Пороги:
threshold = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * n_tup
блокировки берёт Autovacuum worker?
ShareUpdateExclusiveLockна таблицу:- ✅ Совместима с
SELECT,INSERT,UPDATE,DELETE, - ❌ Конфликтует с
ALTER,DROP,VACUUM FULL,CREATE INDEX.
- ✅ Совместима с
Важные нюансы
- Worker работает «вежливо»:
Использует cost-based throttling (autovacuum_vacuum_cost_delay), чтобы не нагружать диск. - Не блокирует DML, но может замедляться из-за активности пользователей (например, при долгих транзакциях).
- Не может очистить строку, если есть долгая транзакция, для которой она ещё видима → bloat растёт.
- При работе с очень большими таблицами может выполняться часами.
Мониторинг
-- Текущие autovacuum-процессы
SELECT pid, datname, relname, phase, heap_blks_scanned, heap_blks_total
FROM pg_stat_progress_vacuum;
-- История очистки
SELECT schemaname, tablename,
last_autovacuum, last_autoanalyze,
n_dead_tup, n_tup_upd, n_tup_del
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;