Что делает VACUUM, VACUUM FULL, ANALYZE? Чем они отличаются и какой когда применять?
VACUUM удаляет dead tuples без блокировки; VACUUM FULL переписывает таблицу с эксклюзивной блокировкой, освобождая место ОС; ANALYZE обновляет статистику для планировщика. В проде autovacuum обычно справляется, VACUUM FULL — крайняя мера.
VACUUM, VACUUM FULL, ANALYZE в PostgreSQL
VACUUM
Помечает пространство, занятое dead tuples, как повторно используемое. Не возвращает место операционной системе — оно остаётся в файле таблицы и будет переиспользовано при следующих INSERT/UPDATE.
- Работает без эксклюзивной блокировки — параллельные чтение/запись не блокируются.
- Дополнительно выполняет заморозку XID (freeze) для борьбы с wraparound.
- Обновляет visibility map — ускоряет index-only scans.
-- Ручной запуск
VACUUM orders;
-- С заморозкой (принудительно морозит все строки)
VACUUM FREEZE orders;
-- Посмотреть прогресс
SELECT * FROM pg_stat_progress_vacuum;
VACUUM FULL
Переписывает всю таблицу в новый файл, физически возвращая место ОС. Это эквивалент CLUSTER без сортировки.
- Требует ACCESS EXCLUSIVE lock — таблица полностью недоступна для чтения и записи.
- Создаёт новый файл и удаляет старый — нужно вдвое больше места на диске в процессе.
- Перестраивает все индексы таблицы.
-- Опасная операция! Блокирует таблицу
VACUUM FULL orders;
-- Альтернатива без блокировки — pg_repack
-- (расширение из pg_catalog.pg_extension)
pg_repack -h localhost -d mydb -t orders
ANALYZE
Собирает статистику о распределении данных в столбцах и сохраняет её в pg_statistic. Планировщик запросов использует эту статистику для выбора плана (seq scan vs index scan, порядок JOIN и т.д.).
-- Только статистика
ANALYZE orders;
-- Комбинация (autovacuum делает это автоматически)
VACUUM ANALYZE orders;
-- Посмотреть текущую статистику по колонке
SELECT * FROM pg_stats
WHERE tablename = 'orders' AND attname = 'status';
Autovacuum
PostgreSQL запускает autovacuum автоматически при превышении порогов. Ключевые параметры postgresql.conf:
-- Когда запускать VACUUM (20% мёртвых + 50 строк)
autovacuum_vacuum_scale_factor = 0.2
autovacuum_vacuum_threshold = 50
-- Когда запускать ANALYZE
autovacuum_analyze_scale_factor = 0.1
autovacuum_analyze_threshold = 50
-- Для высоконагруженных таблиц — индивидуальные настройки
ALTER TABLE orders SET (
autovacuum_vacuum_scale_factor = 0.01,
autovacuum_vacuum_threshold = 1000
);
Когда что применять
- Autovacuum: основной режим работы. Настройте пороги под нагрузку.
- VACUUM вручную: после массового DELETE/UPDATE (bulk load, очистка логов), чтобы не ждать autovacuum.
- VACUUM FREEZE: при приближении к wraparound (age > 1.5 млрд).
- VACUUM FULL: таблица раздута до неприемлемых размеров, нет подходящего окна — и только если нет
pg_repack. - ANALYZE: после значительного изменения данных (bulk insert), когда планировщик начинает выбирать плохие планы.
Подводные камни
- VACUUM FULL требует место на диске, вдвое превышающее размер таблицы — проверяйте свободное место заранее.
- VACUUM FULL пересоздаёт индексы — у вас будут все индексы с минимальным bloat, но и время выполнения пропорционально растёт.
- Долгая транзакция блокирует autovacuum — регулярно проверяйте
pg_stat_activityна idle in transaction сессии. - Параметр
autovacuum_vacuum_cost_delay= 2ms throttlит autovacuum — на SSD можно снизить до 0 или 1ms для ускорения очистки. - На секционированных таблицах autovacuum работает отдельно для каждой секции — мониторинг нужно строить по секциям, а не по родительской таблице.
- После
pg_repackнужно пересоздать logical replication slots — он несовместим с ними. - ANALYZE не запускается autovacuum сразу после VACUUM FULL — нужно запустить вручную или подождать следующего цикла.
- Таблицы без autovacuum_enabled = on и временные таблицы никогда не очищаются автоматически.
Common mistakes
- Путать VACUUM и ANALYZE.
- Запускать VACUUM FULL как безопасную уборку.
- Ожидать, что обычный VACUUM уменьшит файл на диске.
What the interviewer is testing
- Просит lock impact VACUUM FULL.
- Проверяет роль statistics.
- Уточняет autovacuum vs manual vacuum.