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

Ответ

AutoVacuum — это фоновый демонический процесс в PostgreSQL, который автоматически выполняет операции VACUUM и ANALYZE для поддержания здоровья и производительности базы данных.

Зачем это нужно? В PostgreSQL механизм MVCC (Multiversion Concurrency Control) при UPDATE или DELETE не удаляет старые версии строк физически, а помечает их как «мертвые». Со временем эти «мертвые» кортежи (dead tuples) накапливаются, приводя к:

  1. Разбуханию таблиц (Bloat): Таблицы и индексы занимают больше места на диске, чем нужно.
  2. Снижению производительности: Запросы начинают сканировать много неактуальных данных, замедляясь.
  3. Риску остановки транзакций: Если долгоживущая транзакция мешает очистке очень старых версий строк, может возникнуть ошибка "прерывание из-за заморозки" (wraparound).

Как работает AutoVacuum? Он периодически проверяет таблицы. Если количество «мертвых» кортежей в таблице превышает порог, рассчитываемый по формуле: autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * число_кортежей — процесс запускает VACUUM для этой таблицы, чтобы:

  • Освободить место, помеченное «мертвыми» кортежами, для повторного использования (хотя не всегда возвращает его ОС).
  • Обновить статистику, используемую планировщиком запросов (при срабатывании ANALYZE).
  • Защитить от wraparound, «замораживая» старые идентификаторы транзакций.

Базовая настройка (postgresql.conf):

autovacuum = on  # Включено по умолчанию в современных версиях
track_counts = on # Необходимо для сбора статистики

# Настройки для конкретной таблицы можно переопределить
# ALTER TABLE my_table SET (autovacuum_vacuum_scale_factor = 0.05);

Когда может потребоваться ручное управление или тонкая настройка?

  • На таблицах с очень интенсивной нагрузкой на запись, где AutoVacuum не успевает.
  • Для больших пакетных операций (например, массовое удаление) — стоит запустить VACUUM сразу после них.
  • Для критически важных таблиц, где нужно уменьшить масштабный фактор (autovacuum_vacuum_scale_factor), чтобы очистка запускалась чаще.

Ответ 18+ 🔞

А, слушай, про эту автоуборку в постгресе! Это ж такая тема, которую все игнорят, пока всё не начнёт тормозить и дисковое пространство не кончится, а потом орут "почему у меня база ебёт мозг?".

Ну, короче, есть у них там такой фоновый дворник, AutoVacuum. Он тихонечко работает и пытается прибраться в твоих таблицах. А убирать там есть чего, потому что постгрес — он хитрожопый. Когда ты что-то обновляешь или удаляешь, он старую версию строки не стирает нахуй, а просто помечает её как труп. Эти трупы строк (dead tuples) так и валяются, мусором.

И что получается? А получается пиздец, если их не убирать:

  1. Жирные таблицы (Bloat). Таблица вроде на 10 гигов данных, а весит все 50, потому что 40 гигов — это трупняк, который уже не нужен. Индексы тоже жиреют, как свиньи перед забоем.
  2. Всё ползёт, как улитка по стеклу. Запрос начинает читать не только живые данные, но и кучу мёртвого дерьма, которое лежит рядом. Представь, ищешь иголку в стоге сена, а там ещё и дохлых крыс дохуя накидали.
  3. Самая жёсткая хуйня — wraparound. Это когда база может просто встать колом и сказать "всё, пизда, я больше не могу". Такое бывает, если очень-очень давно не чистили и есть какая-то древняя транзакция, которая всё держит. К счастью, автоуборка и от этого защищает, "замораживая" старые версии.

Как этот дворник решает, когда подметать? У него есть простая, но тупая формула. Он смотрит на таблицу и думает: "Опа, тут уже autovacuum_vacuum_threshold трупов (по умолчанию 50 штук) плюс autovacuum_vacuum_scale_factor (по умолчанию 0.2, то есть 20%) от всех строк в таблице. Всё, пора выносить мусор".

Например, в таблице 1 000 000 строк. Порог = 50 + (0.2 * 1 000 000) = 200 050 мёртвых строк. Только когда их накопится больше двухсот тысяч — он проснётся и начнёт работу. Для мелких таблиц норм, а для огромных — это пиздец как много, можно ждать долго.

Включить-то его как? Да он вроде как сам включён в нормальных версиях. Но проверить в postgresql.conf надо:

autovacuum = on  # Должно быть on, иначе ты конченый
track_counts = on # Это тоже должно быть on, чтобы он статистику видел

Когда его настройки — говно и надо лезть руками?

  • Таблицы-шахидки. Где каждую секунду тысячи UPDATE/DELETE. Автоуборка может просто не успевать, мусор копится быстрее, чем его выносят. Тут надо либо чаще его будить (уменьшать scale_factor), либо ручками скрипты писать.
  • После массового удаления. Залил скрипт, который стёр полмиллиона записей? Сразу же, блядь, сделай VACUUM ANALYZE table_name; руками. Не жди, пока дворник соизволит.
  • Для особо важных таблиц. Можно подкрутить прямо на таблице, чтобы убирался чаще:
    ALTER TABLE my_important_table SET (autovacuum_vacuum_scale_factor = 0.05);

    Теперь он будет реагировать уже на 5% мусора, а не на 20%.

Короче, суть в том, что эта штука в 95% случаев работает сама и это охуенно. Но в оставшихся 5% — на твоей совести следить, чтобы твой автоматический дворник не проёбывался и не захлёбывался в твоём же мусоре. Иначе потом будешь разгребать последствия с лопатой и матерными криками.