Принцип работы автоочистки
Описание
Операция VACUUM:
- производит очистку таблиц и индексов от неактуальных версий строк (модель MVCC) для оптимизации хранения данных и доступа к ним;
- собирает статистику об использовании таблицы, что позволяет составить более точный план запросов;
- защищает от переполнения счетчика транзакций.
Подробное описание представлено в разделе «Регулярная очистка» документа «Справочная информация по PostgreSQL».
Команда VACUUM над каждой таблицей с блокировкой ShareUpdateExclusiveLock (защищена от параллельных изменений) производит следующие действия:
- Сканирование страниц на «мертвые» (невидимые после
DELETEилиUPDATE) строки, их заморозку при необходимости, и удаление ссылок из индексов. - Удаление «мертвых» строк и перемещение «живых» в каждом блоке, обновление карт видимости и свободного пространства (VM, FSM).
- Очистку индексов после удаления, обрезку таблицы по возможности, обновление статистики и системных каталогов таблицы. По завершению происходит очистка clog.
Статусы транзакций хранятся в commit log (clog) файлах, расположенных в папках pg_xact, по два бита на xid. Возможны четыре варианта: транзакция в процессе, подтверждена, отменена или является субтранзакцией (статус субтранзакции определяется статусом основной транзакции). При периодическом выполнении VACUUM будут постепенно замораживаться строки, страницы и таблицы БД. Обычные строки имеют свой отрезок видимости в транзакциях от времени создания xmin до времени удаления xmax, а замороженные строки считаются всегда видимыми, и xid текущей транзакции не влияет на их видимость. Для каждой таблицы имеется xid, до которого все строки заморожены, это relfrozenxid. После обработки всех таблиц обновляется такой же xid для всей БД - datfrozenxid. Горизонт транзакций — это все транзакции, начиная с datfrozenxid до xid текущей транзакции. Хранение статусов в commit log имеет смысл только для горизонта транзакций, так как замороженные строки видны для любой транзакции, и VACUUM удаляет все файлы за горизонтом.
Аналогично хранятся статусы мультитранзакций со своей структурой хранения pg_multixact.
Очистка (VACUUM) может работать в двух режимах – «ленивом» и «жадном»:
-
«Ленивый» пропускает страницы, в которых нет «мертвых» строк, поэтому он не может заморозить все строки и обновить
relfrozenxid. Замораживает строки старше, чемvacuum_freeze_min_age. -
«Жадный» режим проходит по всем страницам (кроме полностью замороженных), если при работе очистки возраст таблицы (
relfrozenxid) превышает параметрvacuum_freeze_table_age.Таким образом, при срабатывании автоочистки по 3 условиям (описаны далее),
vacuum_freeze_table_ageвлияет на агрессивность заморозки.
VACUUM необходим для стабильной и быстрой работы таблицы, поэтому его может запускать фоновый процесс, называемый autovacuum. В силу различной нагрузки на БД выполнять VACUUM по расписанию может быть или избыточно, или накладно, поэтому автоочистка (autovacuum) запускается в зависимости от интенсивности использования таблицы:
- Если количество «мертвых» строк таблицы превышает
autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * reltuples(общее количество строк в таблице). - Если количество новых строк таблицы превышает
autovacuum_vacuum_insert_threshold + autovacuum_vacuum_insert_scale_factor * reltuples. - При превышении возраста таблицы
relfozenxidпараметраautovacuum_freeze_max_age.
Обычно автоочистка срабатывает в «ленивом» режиме, замораживая строки старше vacuum_freeze_min_age.
В агрессивном режиме запускается, если возраст таблицы больше vacuum_freeze_table_age или autovacuum_freeze_max_age. При работе в агрессивном режиме выставляется флаг «to prevent wraparound», при котором выводятся соответствующие предупреждения и запрещается прерывание процесса автоочистки, если таблица заблокирована.
Настройка
Параметры
Общие параметры настройки автоочистки:
Параметр | Описание | Значение по умолчанию | Специальные значения параметров |
|---|---|---|---|
| Включает процесс автоочистки |
| |
| Интервал в секундах между запусками автоочистки |
| |
| Максимальное количество одновременно запущенных процессов автоочистки |
| |
| Максимальное количество используемой памяти в килобайтах для каждого процесса автоочистки |
|
|
| Минимальное время исполнения автоочистки в миллисекундах для вывода логов автоочистки |
|
|
Если при запуске Pangolin значение autovacuum_max_workers меньше autovacuum_worker_slots, может произойти переполнение слотов.
Параметры условий запуска автоочистки:
Параметр | Описание | Значение по умолчанию | Специальные значения параметров |
|---|---|---|---|
| Минимальное количество измененных строк ( |
| |
| Множитель к количеству строк в таблице применительно к |
| |
| Минимальное количество добавленных строк ( |
|
|
| Множитель к количеству строк в таблице применительно к |
| |
| Минимальное количество операций со строками ( |
| |
| Множитель к количеству строк в таблице применительно к |
|
Параметры заморозки строк и таблиц:
Параметр | Описание | Значение по умолчанию |
|---|---|---|
| Возраст строк для заморозки при автоочистке |
|
| Возраст строк для заморозки MultiXactId |
|
| Возраст таблицы для сканирования всей таблицы и заморозки всех строк (агрессивная автоочистка) |
|
| Возраст мультитранзакций для агрессивной автоочистки |
|
| Возраст для агрессивной автоочистки от переполнения |
|
| Возраст мультитранзакций для агрессивной автоочистки от переполнения MultiXact («to prevent wraparound») |
|
| При включении параметра кластер игнорирует пороги для агрессивной автоочистки, предназначенной для защиты от переполнения счетчика транзакций ( |
|
Параметры для 32-битных счетчиков:
Параметр | Описание | Значение по умолчанию |
|---|---|---|
| Возраст мультитранзакций для аварийной агрессивной автоочистки от переполнения MultiXact («to prevent wraparound») |
|
| Возраст для аварийной агрессивной автоочистки от переполнения |
|
Параметры аварийной автоочистки: vacuum_failsafe_age и vacuum_multixact_failsafe_age, не используются для 64-битного счетчика (XID).
Управление
Проверка установки параметров
Текущие значения параметров можно получить командой:
SELECT * FROM pg_settings WHERE name LIKE '%vacuum%'
Проверка работоспособности
Выполнение автоочистки возможно проверить в логах сервера. При чтении сообщений лог-файла обратите внимание на конфигурационный параметр log_autovacuum_min_duration, ограничивающий вывод логов. Информация о работе представлена в таблице статистики:
SELECT R.relname, R.relfrozenxid, S.autovacuum_count, S.last_autovacuum FROM pg_class R
LEFT JOIN pg_stat_all_tables S ON S.relname = R.relname WHERE R.relname = 'tablename';
Также есть возможность проверить:
- появляются ли замороженные строки в страницах таблиц – это будет свидетельствовать о работе автоочистки по
freeze_min_age; - поднимается ли
relfrozenxidиdatfrozenxidв течение работы сервера – это информирует о корректной работе агрессивной заморозки без неорганиченного увеличения горизонта транзакций и увеличения файлов clog.
Cценарии использования
Автоочистка с параметрами по умолчанию подойдет для большинства случаев. Периодичность запуска обслуживания обеспечивает своевременное удаление неиспользуемых данных, очистку индексов и обновление статистики. Заморозка периодически блокирует таблицы, ненадолго мешая производить изменения в них. Тонкая настройка может понадобиться для определенных профилей нагрузки на БД.
Например, есть понимание, что в некоторых таблицах очень часто обновляются или удаляются данные, в таком случае для ускорения работы желательно почаще их чистить для оптимизации хранения и поиска – нужно уменьшить autovacuum_vacuum_threshold и autovacuum_vacuum_scale_factor.
При постоянно добавляющихся данных типа логов (без удалений и редактирований) имеет смысл использовать autovacuum_vacuum_insert_threshold = -1, так как очистка не потребуется, и нужна будет только заморозка.
При наличии огромной, постоянно и быстро пополняемой таблицы избавиться от долгих блокировок на агрессивной автоочистке можно настройками autovacuum_disable_freeze_max_age, но существуют дополнительные детали (описание приведено в подразделе «Доработки Pangolin») раздела «Регулярная очистка» документа «Программирование и администрирование сервера PostgreSQL».
Рекомендации
Замечено, что использование низкого значения autovacuum_naptime при резкой накрутке счетчика транзакций, приводит к тому, что агрессивная очистка не успевает отрабатывать за отведенное время, и автоочистка циклично обрабатывает одну и ту же таблицу одной БД («to prevent wraparound», ждет блокировок с предыдущих запусков), пропуская другие БД и таблицы.