PostgreSQL VACUUM FREEZE: защитить от wraparound
VACUUM FREEZE помечает старые версии строк как замороженные, чтобы PostgreSQL не хранил для них полноценный идентификатор транзакции. Это защищает базу от исчерпания 32-битных XID и wraparound. Обычный autovacuum делает то же самое автоматически, но ручной запуск нужен при обслуживании, миграции или подготовке к долгому простою.
Посмотреть возраст заморозки
SELECT
relname,
age(relfrozenxid) AS xid_age
FROM pg_class
WHERE relkind = 'r'
ORDER BY xid_age DESC
LIMIT 10;age(relfrozenxid) показывает, сколько транзакций прошло с последней заморозки таблицы. Чем больше значение, тем ближе база к пределу около двух миллиардов. Порог autovacuum_freeze_max_age по умолчанию — 200 миллионов; когда он достигнут, autovacuum запускает агрессивную заморозку даже при отключённом autovacuum для таблицы.
Заморозить таблицу вручную
VACUUM (FREEZE, VERBOSE) events;VERBOSE показывает, какие страницы обработаны и сколько строк заморожено. VACUUM без FULL не блокирует таблицу на всё время работы: читать и писать можно, хотя нагрузка на I/O и WAL возрастает. Не запускайте операцию в час пик и следите за репликацией: большой объём изменений может отставать на репликах.
VACUUM FREEZE не устраняет раздувание таблицы. Для возврата места на диске нужен VACUUM FULL (блокирует таблицу и переписывает её) или pg_repack. Не путайте эти задачи: freeze борется с wraparound, а не с размером файлов.
VACUUM нельзя выполнять внутри транзакции: запускайте его отдельной командой или через psql. Для всего кластера проверяйте pg_database.datfrozenxid и настройки vacuum_freeze_min_age, vacuum_freeze_table_age. Если база уже близка к пределу, не ждите окна обслуживания: сначала проверьте, не блокирует ли заморозку долгая транзакция или подготовленный XID.
Документация: VACUUM, routine vacuuming.