Блог инженера

History is written by its contributors

PostgreSQL VACUM: что это и зачем нужно

2025-04-21 время чтения 4 мин Postgresql Ilya Brin

Что такое VACUUM в PostgreSQL?

VACUUM — это уборка в мире PostgreSQL. Разберёмся, когда пора действовать и почему спешка только навредит.

Почему нужен VACUUM?

PostgreSQL использует MVCC (Multiversion Concurrency Control) — механизм, который позволяет читать данные, даже если их кто-то изменяет. Побочный эффект: старые версии строк не удаляются мгновенно, а остаются в таблице как “мёртвые” (dead tuples).

Когда вы удаляете или обновляете строки в таблице, PostgreSQL не сразу освобождает место. Вместо этого он помечает эти строки как “мертвые” и продолжает использовать старые версии данных. Это позволяет откатить транзакции, но со временем “мертвые” строки накапливаются, занимая место и замедляя работу базы. VACUUM очищает эти “мертвые” строки, освобождая место и улучшая производительность. Он также обновляет статистику, что помогает оптимизатору запросов выбирать лучшие планы выполнения.

VACUUM делает две ключевые вещи:

  1. Освобождает место, помечая его доступным для новых данных (но не возвращает операционной системе).
  2. Обновляет статистику для планировщика запросов, чтобы тот не тупил на разросшихся таблицах.

Есть ещё VACUUM FULL — радикальная версия, которая переписывает таблицу заново, полностью освобождая место. Но это дорогая операция, блокирующая таблицу.

Когда запускать VACUUM?

VACUUM можно запускать вручную или настроить автоматическую уборку. Рекомендуется запускать VACUUM регулярно, особенно если в таблицах часто происходят обновления и удаления.

Когда начинать думать о VACUUM?

  • Если таблица стала медленно отвечать на запросы.
  • Если размер таблицы значительно увеличился, но вы не добавляли новых данных.
  • Если вы заметили, что количество “мертвых” строк (dead tuples) в таблице растёт.
  • Если вы видите предупреждения в логах PostgreSQL о необходимости VACUUM.
  • Если вы используете autovacuum, но он не справляется с нагрузкой.
  • Если вы часто выполняете операции DELETE или UPDATE на больших таблицах.
  • Если вы заметили, что индексы стали медленнее работать.
  • Если вы видите, что размер таблицы не уменьшается после удаления данных.
  • Если вы хотите оптимизировать производительность базы данных.

Почему не стоит запускать VACUUM сразу?

PostgreSQL уже автовакуумит таблицы по расписанию.

Если вмешаться раньше времени:

  • Нагрузка на диск — VACUUM может конкурировать с рабочими запросами.
  • Лишние затраты ресурсов — если dead tuples ещё не критичны, уборка будет пустой тратой IOPS.
  • Риск перестараться — VACUUM FULL блокирует таблицу и может ударить по производительности.

Как запустить VACUUM?

Чтобы запустить VACUUM, используйте команду:

VACUUM имя_таблицы;

Если хотите полностью освободить место, используйте:

VACUUM FULL имя_таблицы;

Если хотите очистить все таблицы в базе данных, просто выполните:

VACUUM;

Если хотите, чтобы PostgreSQL сам заботился о чистоте, включите autovacuum в настройках. Он будет автоматически запускать VACUUM в фоновом режиме, когда это нужно.

ALTER SYSTEM SET autovacuum = on;

Заключение

VACUUM — это важный инструмент для поддержания здоровья вашей базы данных PostgreSQL. Он помогает избежать накопления “мертвых” строк, освобождает место и улучшает производительность. Регулярно запускайте VACUUM или настройте autovacuum, чтобы ваша база данных оставалась быстрой и отзывчивой. Помните, что VACUUM — это не разовая операция, а часть регулярного обслуживания базы данных. Не забывайте следить за состоянием таблиц и запускать VACUUM по мере необходимости, чтобы избежать проблем с производительностью в будущем.

Избегайте VACUUM FULL — если можно обойтись обычным вакуумом или pg_repack.

Дополнительные советы

  • Регулярность: Запускайте VACUUM регулярно, особенно для таблиц с частыми обновлениями и удалениями. Это поможет избежать накопления “мертвых” строк.

  • Мониторинг: Используйте pg_stat_user_tables для отслеживания количества “мертвых” строк и других метрик. Это поможет понять, когда пора запускать VACUUM.

  • Настройка autovacuum: Проверьте настройки autovacuum в postgresql.conf. Вы можете настроить частоту и условия запуска, чтобы он лучше подходил под вашу нагрузку.

  • Планирование: Если у вас есть большие таблицы, подумайте о запуске VACUUM в нерабочее время, чтобы минимизировать влияние на пользователей.

  • Использование pg_repack: Если у вас есть большие таблицы с много “мертвыми” строками, рассмотрите использование утилиты pg_repack, которая может помочь с реорганизацией таблиц и индексов без блокировки.

  • Регулярное обслуживание: Включите VACUUM в регулярные задачи обслуживания базы данных, чтобы поддерживать её в хорошем состоянии. Это поможет избежать накопления “мертвых” строк и улучшит общую производительность.

  • Проверка индексов: После запуска VACUUM проверьте индексы на предмет необходимости их перестройки. Иногда после очистки таблиц индексы могут стать менее эффективными.

  • Использование pg_stat_activity: Следите за активностью в базе данных с помощью pg_stat_activity, чтобы понять, какие запросы могут блокировать VACUUM и как это влияет на производительность.

  • Планирование больших операций: Если вы планируете большие операции обновления или удаления, подумайте о запуске VACUUM сразу после них, чтобы освободить место и улучшить производительность для последующих запросов.

  • Использование pg_stat_progress_vacuum: Начиная с PostgreSQL 12, вы можете использовать представление pg_stat_progress_vacuum, чтобы отслеживать прогресс выполнения VACUUM. Это полезно для понимания, сколько времени займёт операция и какие таблицы обрабатываются.

  • Проверка настроек autovacuum: Убедитесь, что параметры autovacuum_vacuum_threshold и autovacuum_vacuum_scale_factor настроены правильно. Они определяют, когда будет запущен автоматический VACUUM. Если у вас много обновлений и удалений, возможно, стоит уменьшить эти значения.

  • Проверка блокировок: Если VACUUM не может запуститься из-за блокировок, используйте pg_locks, чтобы увидеть, какие транзакции блокируют его. Это поможет вам понять, как оптимизировать работу с таблицами.

  • Использование pg_stat_user_indexes: Это представление поможет вам увидеть статистику по индексам, включая количество “мертвых” строк в индексах. Если их много, возможно, стоит перестроить индексы после VACUUM.

  • Планирование больших операций: Если вы планируете большие операции обновления или удаления, подумайте о запуске VACUUM сразу после них, чтобы освободить место и улучшить производительность для последующих запросов.

comments powered by Disqus