EMZETT.
Увійти

PostgreSQL VACUUM: autovacuum і роздуті таблиці

Коротко: PostgreSQL не видаляє рядки одразу, а позначає їх; VACUUM очищує, звільняє місце для повторного використання та підтримує статистику актуальною, зазвичай автоматично через autovacuum.

Докладніше: Через MVCC (кілька версій рядка для паралельних транзакцій) UPDATE і DELETE породжують мертві кортежі. Вони лишаються, доки жоден виконуваний доступ їх більше не потребує. VACUUM прибирає їх з погляду повторного використання.

Подробиці

Що робить VACUUM

  • Позначає місце мертвих рядків як доступне для повторного використання.
  • Оновлює мапу видимості (прискорює index-only-сканування).
  • Захищає від переповнення ідентифікатора транзакції (wraparound) (заморожує старі рядки).
  • VACUUM FULL перезаписує таблицю й повертає місце операційній системі, але блокує монопольно; потрібен рідко (альтернатива: pg_repack).
  • ANALYZE збирає статистику для планувальника запитів.

Autovacuum

Фоновий процес запускає VACUUM/ANALYZE, коли накопичилося достатньо змін (за замовчуванням: 20 % таблиці + 50 рядків). Налаштування: autovacuum_vacuum_scale_factor, autovacuum_naptime, для окремої таблиці ALTER TABLE … SET (autovacuum_vacuum_scale_factor = 0.02). Ніколи не вимикайте. Для великих, сильно змінюваних таблиць налаштовуйте агресивніше.

Виявлення роздування (bloat)

Симптоми: таблиця/індекс росте за того самого обсягу даних, запити сповільнюються. Перевірка: pg_stat_user_tables (n_dead_tup, last_autovacuum), розмір через pg_total_relation_size, розширення pgstattuple. Причини: довгі транзакції або забуті відкриті з’єднання (заважають очищенню), надто рідкісний autovacuum, часті масові оновлення. Рішення: тримати транзакції короткими, тонше налаштувати autovacuum, вручну VACUUM (VERBOSE, ANALYZE) table;.

Практика та керовані сервіси

У Neon, Supabase, RDS autovacuum здебільшого працює автоматично; все ж спостерігайте за шаблонами (таблиці з безліччю оновлень на кшталт сеансів, лічильників, черг: краще вставка + видалення старих рядків або партиції). Видаляйте великі обсяги пакетами. Робіть резервну копію перед VACUUM FULL. Читайте pg_stat_progress_vacuum. З’єднання, що застрягли в idle in transaction, — ворог будь-якого vacuum: обмежуйте через idle_in_transaction_session_timeout.

Див. також: PostgreSQL, MVCC і рівні ізоляції, Індекси PostgreSQL, Пулінг з’єднань