06 Занятие 06: Многоверсионность / Автоочистка
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: dba2_06_mvcc_autovacuum.html Archive: DBA2-handouts-16.zip Страниц PDF: 20
Page 1: Многоверсионность / Автоочистка
Авторские права
© Postgres Professional, 2016–2025 Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Игорь Гнатюк Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Автоматическая очистка (autovacuum)
- Автоанализ
- Настройка процесса автоочистки
Page 3: Автоматическая очистка
Работает аналогично обычной очистке
- Выполняется периодически
- для таблиц с определенным количеством изменений
- в том числе для toast-таблиц
- Процесс autovacuum launcher
- постоянно запущен
- планирует запуск рабочих процессов
- Процессы autovacuum worker
- запускаются процессом postmaster по просьбе autovacuum launcher
- подключаются к заданной БД, перебирают и очищают таблицы
Комментарии преподавателя
Автоматическая очистка — механизм, позволяющий запускать обычную очистку в определенные моменты времени, в зависимости от количества изменений в таблицах. Это удобнее и правильнее, чем запуск по расписанию (cron), поскольку учитывает динамику системы.
При включенной автоочистке в системе всегда присутствует процесс autovacuum launcher, который занимается планированием работы. Реальную очистку выполняют процессы autovacuum worker, несколько экземпляров которых могут работать параллельно.
Процессы autovacuum worker запускаются процессом postmaster по просьбе autovacuum launcher (поскольку именно postmaster отвечает за порождение всех новых процессов).
https://postgrespro.ru/docs/postgresql/16/routine-vacuuming#AUTOVACUU M
Page 4: Autovacuum launcher
Периодически запускает рабочий процесс в каждую активную базу данных
- раз в autovacuum_naptime
- над одной базой могут работать несколько процессов
- общее количество рабочих процессов ≤ autovacuum_max_workers
- Настройки
- autovacuum = on
- track_counts = on
- autovacuum_naptime = 60 s
- autovacuum_max_workers = 3
- должны быть включены оба
- ?
Комментарии преподавателя
Процесс autovacuum launcher составляет список баз данных, в которых есть какая-либо активность (точнее, для которых собирается статистика использования).
Новый рабочий процесс запускается раз в autovacuum_naptime для каждой базы данных из списка (то есть при наличии N баз процессы будут порождаться в N раз чаще). Если за время autovacuum_naptime рабочий процесс не успел очистить всю базу данных, в ту же базу будет направлен другой рабочий процесс, и они будут работать вместе. Общее количество рабочих процессов ограничено параметром autovacuum_max_workers.
Чтобы автоматическая очистка в принципе работала, должны быть установлены параметры autovacuum и track_counts. Последний включает сбор статистики использования.
Page 5: Autovacuum worker
Составляет список объектов базы данных для очистки
- число ненужных версий строк превышает
- autovacuum_vacuum_threshold +
- autovacuum_vacuum_scale_factor × число строк в таблице
- число строк, вставленных с момента последней очистки, превышает
- autovacuum_vacuum_insert_threshold +
- autovacuum_vacuum_insert_scale_factor × число строк в таблице
- включаются обычные таблицы и toast-таблицы,
- материализованные представления
- не включаются временные таблицы
Комментарии преподавателя
Рабочий процесс подключается к указанной базе данных и строит список всех таблиц, материализованных представлений и toast-таблиц, требующих очистки.
Очистки требуют объекты, в которых накопилось значительное количество ненужных («мертвых») версий строк.
Очищаются также объекты, в которые с момента прошлой очистки было вставлено значительное количество новых строк. Это важно для таблиц, в которые данные только вставляются: их тоже необходимо очищать, чтобы обновить карту видимости и заморозить старые версии (рассматривается в теме «Заморозка»).
Точные формулы приведены на слайде. Каждая из них использует два параметра, один из которых (*_threshold) определяет абсолютное значение, а другой (*_scale_factor) — относительную долю строк.
Число строк определяется приблизительно, по статистике:
● общее число — pg_class.reltuples,
● число ненужных — pg_stat_all_tables.n_dead_tup,
● число вставленных — pg_stat_all_tables.n_ins_since_vacuum.
Page 6: Autovacuum worker
Составляет список объектов базы данных для анализа
- число изменившихся версий строк превышает
- autovacuum_analyze_threshold +
- autovacuum_analyze_scale_factor × число строк в таблице
- включаются обычные таблицы и материализованные представления
- не включаются toast-таблицы и временные таблицы
- По очереди очищает и/или анализирует выбранные объекты
- в одной базе может одновременно работать несколько процессов
- на уровне одной таблицы параллелизма нет
Комментарии преподавателя
Также строится список всех таблиц и материализованных представлений, требующих анализа. Toast-таблицы не анализируются.
Анализа требуют объекты, в которых с момента предыдущего анализа изменилось значительное число строк. Оно определяется по статистике: pg_stat_all_tables.n_mod_since_analyze.
Построив два списка, рабочий процесс по очереди очищает и/или анализирует отобранные объекты и по окончании очистки завершается.
В одной БД может одновременно работать несколько процессов, параллельно обрабатывая разные таблицы. На уровне одной таблицы параллелизма нет.
Page 7: Autovacuum worker
Настройки автоочистки
- autovacuum_vacuum_threshold = 50
- autovacuum_vacuum_scale_factor = 0.2
- ↓
- autovacuum_vacuum_insert_threshold = 1000
- autovacuum_vacuum_insert_scale_factor = 0.2
- ↓?
- Параметры хранения таблиц
- autovacuum_enabled
- toast.autovacuum_enabled
- и одноименные настроечные параметры
Комментарии преподавателя
Настройки по умолчанию предполагают вызов автоочистки при изменении таблицы на 20% или вставке 20% новых строк. Это достаточно высокое значение: автоочистка будет вызываться редко, но работать будет долго, особенно для больших таблиц. В большинстве случаев эти проценты следует уменьшить.
В случае необходимости можно настроить эти параметры на уровне отдельных таблиц с помощью параметров хранения:
CREATE TABLE … WITH (параметр=значение)
Причем параметры можно отдельно настраивать для toast-таблиц.
Кроме того, на уровне отдельных таблиц автоочистку можно отключить.
https://postgrespro.ru/docs/postgresql/16/runtime-config-autovacuum
https://postgrespro.ru/docs/postgresql/16/sql-createtable#SQL-CREATETAB LE-STORAGE-PARAMETERS
Page 8: Autovacuum worker
Настройки автоанализа
- autovacuum_analyze_threshold = 50
- autovacuum_analyze_scale_factor = 0.1
- ?
- Параметры хранения таблиц
- autovacuum_analyze_threshold
- autovacuum_analyze_scale_factor
- для toast-таблиц анализ не выполняется
Комментарии преподавателя
Настройки по умолчанию предполагают вызов автоанализа при изменении таблицы на 10%.
В случае необходимости, можно настроить эти параметры на уровне отдельных таблиц с помощью параметров хранения.
Toast-таблицы не анализируются, поэтому соответствующих параметров для них нет.
Page 9: Autovacuum worker
Настройки для регулирования нагрузки
- общий предел
- для всех рабочих
- autovacuum_vacuum_cost_limit = −1
- (при −1 используется vacuum_cost_limit = 200)
- ↑
- процессов
- autovacuum_vacuum_cost_delay = 2ms
- (при −1 используется vacuum_cost_delay = 0)
- vacuum_cost_page_hit, vacuum_cost_page_miss, vacuum_cost_page_dirty
- Параметры хранения таблиц
- autovacuum_vacuum_cost_limit
- toast.autovacuum_vacuum_cost_limit
- autovacuum_vacuum_cost_delay
- toast.autovacuum_vacuum_cost_delay
Комментарии преподавателя
Регулирование нагрузки при автоматической очистке работает так же, как и при обычной. Однако существуют дополнительные параметры autovacuum_vacuum_cost_limit и autovacuum_vacuum_cost_delay, которые, если не равны −1, перекрывают параметры vacuum_cost_limit и vacuum_cost_delay.
Для ускорения работы автоочистки можно увеличить значение autovacuum_vacuum_cost_limit, но при этом следует учитывать, что предел, устанавливаемый этим параметром, общий для всех рабочих процессов. Поэтому при увеличении autovacuum_max_workers следует увеличивать и autovacuum_vacuum_cost_limit.
Также эти параметры могут указываться и на уровне отдельных таблиц.
https://postgrespro.ru/docs/postgresql/16/runtime-config-resource#RUNTIM E-CONFIG-RESOURCE-VACUUM-COST
Page 10: Autovacuum worker
Настройки памяти
- autovacuum_work_mem = −1
- (при –1 используется maintenance_work_mem = 64MB)
- настройки действуют для каждого рабочего процесса,
- память выделяется сразу в полном объеме
- больший объем памяти уменьшает избыточную обработку
- индексных страниц
- Мониторинг
- log_autovacuum_min_duration = 10min
- pg_stat_progress_vacuum
Комментарии преподавателя
Кроме настроек, влияющих на то, когда и как работать процессу автоочистки, есть возможность отрегулировать выделяемую память для рабочих процессов (autovacuum worker).
По умолчанию размер памяти ограничен параметром maintenance_work_mem, который действует не только на автоочистку, но и на другие служебные операции. Обычно этот параметр можно установить в достаточно большое значение, поскольку фоновых процессов не так много. Однако число рабочих процессов автоочистки (регулируемое параметром autovacuum_max_workers) может быть большим, и память выделяется сразу полностью (а не по необходимости). Поэтому для процессов автоочистки можно настроить отдельное ограничение с помощью параметра autovacuum_work_mem.
Как говорилось в теме «Очистка», процесс очистки может работать и с минимальным объемом памяти. Но если на таблице созданы индексы, то небольшое значение может привести к повторным сканированиям одних и тех же индексных страниц — автоочистка будет работать медленнее. В идеале следует подобрать такое минимальное значение, при котором нет повторных сканирований.
Для мониторинга есть параметр log_autovacuum_min_duration, задающий время выполнения автоочистки, при превышении которого информация будет записываться в журнал сообщений сервера, и представление pg_stat_progress_vacuum, показывающее информацию в реальном времени.
Напомним, что зачастую следует не увеличивать размер памяти, а уменьшать порог срабатывания очистки, чтобы за один раз обрабатывалось меньше данных.
Page 11: Автоочистка
Создадим таблицу с 1000 строками:
Выставим настройки автоочистки. Небольшое время ожидания, чтобы сразу видеть результат:
Один процент строк:
Нулевой порог:
Выставим настройки автоанализа. Два процента строк:
Нулевой порог:
Перечитаем настройки:
И подождем немного, чтобы сработал автоанализ. Создадим представление, показывающее, нуждается ли наша таблица в очистке. Здесь мы учитываем только мертвые версии, но аналогично можно добавить и условие для вставленных строк.
Page 12: Page 12
Сейчас таблица не требует очистки (в ней нет ненужных версий) и она ни разу не очищалась:
Можно создать аналогичное представление и для анализа:
Представление показывает, что таблица не требует анализа; автоанализ уже был выполнен:
Отключим автоочистку на уровне таблицы и изменим 11 строк (больше 1%):
Проверим представления:
Page 13: Page 13
Как видно, таблице требуется автоочистка. Включим автоочистку для таблицы и подождем несколько секунд…
Автоочистка пришла и обработала таблицу. Число ненужных версий снова равно нулю. При этом автоанализ не выполнялся. Изменим еще 11 строк:
Теперь должна отработать и автоочистка, и автоанализ. Проверим это.
Несколько секунд ожидания…
Page 14: Page 14
Все правильно, отработали оба процесса. Показанные представления можно использовать для мониторинга очереди таблиц, ожидающих очистку и анализ, убрав условие на имя таблицы. Для полноты картины в них требуется учесть параметры хранения на уровне отдельных таблиц.
Page 15: Подход к настройке
Баланс между разрастанием и накладными расходами
- итеративный процесс
- Основные параметры
- autovacuum_vacuum_scale_factor
- частота обработки
- autovacuum_max_workers
- параллелизм
- autovacuum_vacuum_cost_limit
- скорость работы
- индивидуальная настройка важных таблиц параметрами хранения
- Мониторинг
- разрастание таблиц
- очередь таблиц, ожидающих очистки
- нагрузка на ввод-вывод при работе очистки
Комментарии преподавателя
Автоочистка управляется довольно большим числом взаимосвязанных параметров. В хорошо настроенной системе автоочистка не дает таблицам неадекватно разрастаться и при этом не создает лишних накладных расходов.
Поиск баланса — итеративный процесс. Нужно выставить разумные начальные значения исходя из размера и характера использования таблиц, проводить постоянный мониторинг и вносить коррективы.
Увеличение threshold/scale_factor приводит к большему разрастанию таблиц, но очистка выполняется реже и большими порциями (возможны пиковые нагрузки), суммарные накладные расходы ниже. Уменьшение параметров приводит к более частой обработке небольшими порциями, общие накладные расходы увеличиваются, но таблицы разрастаются меньше. Пиковые нагрузки можно пытаться сгладить параметрами cost_limit/cost_delay, уменьшающими скорость работы очистки.
Значение, заданное параметрами threshold/scale_factor, определяет лишь желаемый момент срабатывания очистки. При большом числе сильно измененных таблиц процесс очистки может долго выполнять проход и приступит к обработке очередной таблицы далеко не сразу. В этом случае надо либо увеличивать скорость работы очистки (если она была уменьшена параметрами cost_limit/cost_delay), либо увеличивать число параллельно работающих процессов параметром max_workers (что приведет к увеличению накладных расходов).
Начиная с 16-ой версии процессы автоочистки применяют изменения параметров прямо во время обработки очередного отношения. Поэтому можно «на лету» ускорить уже начавшуюся очистку большой таблицы.
Page 16: Итоги
Автоматическая очистка запускает очистку и анализ таблиц, динамически реагируя на изменения данных
- Автоочистка допускает тонкую настройку как на уровне системы, так и отдельных таблиц
- Настройка автоочистки — итеративный поиск баланса
Page 17: Практика
- Настройте автоочистку на запуск при изменении 10% строк, время «сна» — одна секунда.
- Создайте таблицу с большим количеством строк.
- Двадцать раз с интервалом в несколько секунд изменяйте по 5–6% случайных строк. Каждое изменение выполняйте в отдельной транзакции.
- Сколько раз отработала автоочистка? Насколько разрослась таблица? Совпадают ли результаты с ожидаемыми и как их объяснить?
Page 18: 1. Настройка автоочистки
Настраиваем автоочистку на 10% строк.
Устанавливаем запуск рабочих процессов на один раз в секунду:
2. Таблица
3. Изменение данных
Начальный размер таблицы:
Выполняем обновление таблицы с задержками в несколько секунд между командами.
Page 19: Page 19
4. Оценка разрастания
Статистика по таблице (autovacuum_count — сколько раз выполнялась автоочистка):
Page 20: Page 20
Вот как увеличилась таблица:
Суммарно изменилось порядка 110000 строк, что составляет 110% от размера таблицы. Можно было бы предположить, что автоочистка сработает 10–11 раз. Однако автоочистка выполнялась примерно в два раза реже, поскольку существенная часть обновлений была оптимизирована самоочисткой (в нашем случае, HOT-очисткой: поле n_tup_hot_upd). Таблица увеличилась не в два раза, а меньше — примерно на треть. В идеале достаточно было бы 5–6%, но: карта свободного пространства не обновляется при самоочистке, а автоочистка срабатывает только на второй раз; в результате HOT-обновлений на страницах появляются «лишние» redirect-указатели — при небольшой длине строк, как в нашем примере, этот эффект становится заметен; карта свободного пространства хранит не точную, а округленную информацию.