Тюнинг Autovacuum в PostgreSQL: scale factor, cost limit и борьба с bloat
- Разрастание объема таблиц и индексов (Bloat) при стабильном количестве строк.
- Предупреждения в логах
WARNING: database "db_name" must be vacuumed within 10000000 transactions(угроза Wraparound). - Фоновый autovacuum потребляет весь дисковый ввод-вывод или не успевает за потоком операций
UPDATE/DELETEв 1С.
1. Комплексная оптимизация autovacuum в postgresql.conf
# Включение и параллелизм
autovacuum = on
autovacuum_max_workers = 6 # Количество параллельных воркеров
autovacuum_naptime = 15s # Интервал пробуждения демона
# --- Пороги срабатывания (Снижение дефолтных 20% до 5-2% для крупных таблиц) ---
autovacuum_vacuum_threshold = 50
autovacuum_vacuum_scale_factor = 0.05 # Запуск очистки при изменении 5% строк
autovacuum_analyze_threshold = 50
autovacuum_analyze_scale_factor = 0.02 # Запуск сбора статистики при изменении 2% строк
# --- Квоты ввода-вывода (Снятие удушающих лимитов для NVMe дисков) ---
autovacuum_vacuum_cost_limit = 2000 # Увеличение общего пула затрат (дефолт 200 слишком мал)
autovacuum_vacuum_cost_delay = 2 # Задержка в мс при исчерпании лимита
# --- Предотвращение Transaction ID Wraparound ---
autovacuum_freeze_max_age = 2000000002. Индивидуальная настройка autovacuum для особо горячих таблиц 1С
-- Настройка агрессивной очистки для таблицы итогов регистров накопления (_AccumRgT)
ALTER TABLE _accumrgtn12345 SET (
autovacuum_vacuum_scale_factor = 0.01,
autovacuum_vacuum_cost_limit = 5000,
autovacuum_vacuum_cost_delay = 0
);3. Мониторинг возраста транзакций и работы воркеров
-- Поиск таблиц, наиболее близких к блокировке Transaction ID Wraparound
SELECT
c.oid::regclass AS TableName,
age(c.relfrozenxid) AS AgeInTransactions,
pg_size_pretty(pg_total_relation_size(c.oid)) AS TotalSize
FROM pg_class c
WHERE c.relkind IN ('r', 't')
ORDER BY age(c.relfrozenxid) DESC LIMIT 10; Частые вопросы (FAQ)
Что такое Transaction ID Wraparound и почему это опасно?
В PostgreSQL счетчик транзакций (XID) 32-битный (до 4 млрд). Когда возраст транзакций приближается к 2 млрд, база принудительно уходит в Read-Only для предотвращения перезаписи старых видимых данных новыми транзакциями.
Почему стандартный autovacuum_vacuum_cost_limit = 200 тормозит очистку на современных серверах?
Дефолтный лимит 200 рассчитан на старые HDD диски 20-летней давности. При стоимости чтения страницы из памяти в 1 единицу, а с диска в 20 единиц, воркер засыпает почти каждую секунду, не успевая очищать активные таблицы 1С.
В чем разница между VACUUM и VACUUM FULL?
Обычный VACUUM помечает мертвые строки как свободное место для повторной записи новыми данными внутри тех же страниц (без уменьшения размера файла на диске). VACUUM FULL физически перезаписывает таблицу в новый файл, возвращая место ОС, но намертво блокирует таблицу на запись и чтение (AccessExclusiveLock).
Как увидеть текущие работающие процессы Autovacuum?
Выполните: SELECT pid, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed FROM pg_stat_progress_vacuum;