Что такое VACUUM в PostgreSQL
Что проверяют
Знаете ли вы, почему в PostgreSQL обновление строки порождает новую версию, и связываете ли распухание таблиц с поведением своего приложения. Это не вопрос для администратора: мёртвые версии строк создаёт как раз код, который вы пишете.
Как отвечать
Начните с многоверсионности: каждая версия строки помечена номерами транзакций, UPDATE записывает новую версию и помечает старую, DELETE только помечает. Старые версии живут, пока их может увидеть хоть одна открытая транзакция. Очистка проходит по таблице и делает три вещи: помечает место мёртвых версий как свободное к переиспользованию, обновляет карту видимости, без которой не работает сканирование только по индексу, и замораживает номера транзакций у давних строк.
Дальше главное различие. Обычный VACUUM не отдаёт место операционной системе: файл не уменьшается, освободившееся место занимают новые строки. Уменьшает файл VACUUM FULL, но он переписывает таблицу целиком под блокировкой, при которой её нельзя даже читать, поэтому на работающей системе берут расширение, переписывающее таблицу без долгой блокировки. Статистику для планировщика собирает ANALYZE, это отдельная работа. Штатно всё делает автоочистка по порогам от размера таблицы, и на больших таблицах пороги по умолчанию срабатывают поздно, их задают на уровне таблицы.
Со стороны приложения: долгая открытая транзакция, забытый режим ручного подтверждения, соединение, вернувшееся в пул с незакрытой транзакцией, удерживают горизонт очистки и не дают убрать мёртвые версии во всей базе.
Где спотыкаются
Уверены, что очистка возвращает место на диск. Размер файла после обычного прогона не изменится, и человек решает, что команда не сработала, хотя она отработала как задумано.
Второе: советуют VACUUM FULL как лекарство и ставят его в шаг развёртывания. На большой таблице это блокировка на десятки минут, а рядом нужно место под вторую копию таблицы, которого может не быть.
Третье: не связывают проблему со своим кодом. Ищут виноватого в настройках, пока приложение держит открытый снимок данных или переписывает таблицу одним запросом. Заодно путают распухание таблицы и индексов: индексы лечит перестроение, а не очистка.