linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/kb/Vacuum, freeze, wraparound/autovacuum

kb/vacuum ── Vacuum, freeze, wraparound ── intermediate

Autovacuum: пороги и bloat

Autovacuum чистит таблицу, когда мёртвых версий накопится больше порога threshold + scale_factor × reltuples (50 и 0.2 по умолчанию). scale_factor 0.2 плохо масштабируется на большие таблицы, поэтому горячим задают индивидуальные пороги. autovacuum=off ведёт к bloat и wraparound.

view as markdownaka: auto-vacuum, autovacuum-tuning, bloat

Формула срабатывания

порог = autovacuum_vacuum_threshold
      + autovacuum_vacuum_scale_factor × reltuples

По умолчанию threshold = 50, scale_factor = 0.2: уборка запускается, когда n_dead_tup превысит 50 + 20% от числа живых строк. Для миллиона строк это больше 200 тысяч мёртвых версий.

sql
SELECT relname, n_live_tup, n_dead_tup,
       50 + 0.2 * n_live_tup AS av_threshold
FROM pg_stat_all_tables WHERE relname = 'bloat_demo';

Почему 0.2 плох для больших таблиц

Порог пропорционален размеру. 20% от 100 млн строк - это 20 млн мёртвых версий, которые лежат раздутым грузом между уборками. Поэтому крупным и горячим таблицам задают индивидуальный, меньший порог:

sql
ALTER TABLE big_events SET (
  autovacuum_vacuum_scale_factor = 0.02,
  autovacuum_vacuum_threshold = 1000
);

Настройка таблицы переопределяет глобальную. Один общий scale_factor почти никогда не оптимален.

Порог по вставкам (PG13+)

Append-only таблицы не создают мёртвых версий, и раньше autovacuum их не трогал - страдали index-only сканы и заморозка. С PostgreSQL 13 есть отдельный порог autovacuum_vacuum_insert_threshold (1000) + autovacuum_vacuum_insert_scale_factor (0.2), и такие таблицы тоже регулярно проходят VACUUM.

Bloat и его измерение

Раздувание - место под мёртвыми версиями и пустотами; симптом того, что VACUUM не поспевает. Измеряют через pgstattuple (dead_tuple_percent, free_percent); на больших таблицах берут pgstattuple_approx из-за полного скана. Вернуть место ОС умеет только VACUUM FULL или pg_repack (см. vacuum).

Поймать за работой

sql
SELECT relname, last_autovacuum, autovacuum_count
FROM pg_stat_all_tables WHERE relname = 'bloat_demo';
SELECT relid::regclass, phase, heap_blks_scanned, heap_blks_total
FROM pg_stat_progress_vacuum;

autovacuum=off — дорогая ошибка

Отключение останавливает уборку (растёт bloat) и заморозку (возраст ползёт к 200 млн, см. wraparound). Анти-wraparound autovacuum всё равно сработает, но как аврал на пике. Правильная реакция на «autovacuum мешает»

  • сделать его агрессивнее (больше воркеров, меньше cost_delay, индивидуальные пороги), а не выключать.

§ команды

bash
ALTER TABLE big_events SET (autovacuum_vacuum_scale_factor = 0.02);

Чистить горячую таблицу при 2% мусора вместо 20%

bash
SELECT * FROM pg_stat_progress_vacuum;

Что делает текущий проход VACUUM прямо сейчас

bash
SELECT relname, last_autovacuum FROM pg_stat_all_tables ORDER BY last_autovacuum;

Когда таблицы чистились в последний раз

§ см. также

  • vacuumVACUUM и removable cutoffVACUUM удаляет мёртвые версии из таблицы и индексов, обновляет Free Space Map и Visibility Map, продвигает горизонт заморозки. Удаляет только версии старше removable cutoff. Обычный VACUUM не уменьшает файл - это делает VACUUM FULL под эксклюзивной блокировкой.
  • transaction-horizonГоризонт транзакцииГоризонт - минимум backend_xmin по всем активным транзакциям. Версию строки можно убрать, только если она стала мёртвой раньше горизонта. Одна долгая или idle-in-transaction транзакция отодвигает горизонт назад и запрещает уборку мусора во всей базе.
  • wraparoundWraparound и колесо XIDxid - 32-битное число, счётчик переполняется примерно через 4 млрд транзакций. Сравнения видимости идут по кругу: версия старше текущего на ~2 млрд «переворачивается» в будущее и молча исчезает. Защита - заморозка и лестница из autovacuum, failsafe, WARNING и single-user.
  • hot-updatesHOT-обновления и fillfactorHOT (Heap-Only Tuple) - обновление, которое не пишет в индексы: оно возможно, если ни одна индексируемая колонка не изменилась и новая версия помещается в ту же страницу. fillfactor оставляет в странице резерв, чтобы обновления оставались HOT.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки