Что такое vacuum в базах данных и для чего он нужен
Что проверяют
Понимаете ли вы, что происходит в PostgreSQL после UPDATE и DELETE, и почему база растёт, хотя строк не прибавилось. Для бэкендера на Python это вопрос про собственный код: именно приложение плодит мёртвые версии строк пачками и держит долгие транзакции, из-за которых автовакуум не может их убрать.
Как отвечать
В MVCC обновление не правит строку на месте, а пишет новую версию; старая остаётся видимой для транзакций со старым снапшотом. VACUUM помечает такие мёртвые версии как место, пригодное для повторной записи в этой же таблице.
Три его задачи: вернуть место под новые строки, обновить карту видимости (без неё не работает index-only scan) и заморозить идентификаторы транзакций, чтобы счётчик не пошёл на второй круг. Последнее и есть главная причина существования вакуума.
Обычно всё делает автовакуум, настраиваемый по таблице через autovacuum_vacuum_scale_factor и autovacuum_vacuum_threshold. Наблюдать стоит за pg_stat_user_tables.
select relname, n_live_tup, n_dead_tup, last_autovacuum
from pg_stat_user_tables order by n_dead_tup desc limit 10;Отдельно упомяните ANALYZE: это другая операция, статистика для планировщика. И VACUUM FULL, который переписывает таблицу целиком под эксклюзивной блокировкой.
Где спотыкаются
Говорят, что вакуум возвращает место операционной системе. Обычный VACUUM этого не делает, файл не уменьшается; место отдают VACUUM FULL или pg_repack, причём первый блокирует таблицу и требует свободного места под копию.
Ищут причину распухания в базе, а она в коде. Забытая открытая транзакция в ORM, курсор фонового скрипта, неиспользуемый слот репликации держат горизонт видимости, и автовакуум честно работает, только удалять ему нечего.
Отключают автовакуум на нагруженной таблице, чтобы «не мешал». Через какое-то время приходит принудительная заморозка, которую уже не отменить, и накладывается она на таблицу, успевшую вырасти в разы.