Перейти к основному содержимому

Принцип работы автоочистки

Описание

Операция VACUUM:

  • производит очистку таблиц и индексов от неактуальных версий строк (модель MVCC) для оптимизации хранения данных и доступа к ним;
  • собирает статистику об использовании таблицы, что позволяет составить более точный план запросов;
  • защищает от переполнения счетчика транзакций.

Подробное описание представлено в разделе «Регулярная очистка» документа «Справочная информация по PostgreSQL».

Команда VACUUM над каждой таблицей с блокировкой ShareUpdateExclusiveLock (защищена от параллельных изменений) производит следующие действия:

  1. Сканирование страниц на «мертвые» (невидимые после DELETE или UPDATE) строки, их заморозку при необходимости, и удаление ссылок из индексов.
  2. Удаление «мертвых» строк и перемещение «живых» в каждом блоке, обновление карт видимости и свободного пространства (VM, FSM).
  3. Очистку индексов после удаления, обрезку таблицы по возможности, обновление статистики и системных каталогов таблицы. По завершению происходит очистка 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) запускается в зависимости от интенсивности использования таблицы:

  1. Если количество «мертвых» строк таблицы превышает autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * reltuples (общее количество строк в таблице).
  2. Если количество новых строк таблицы превышает autovacuum_vacuum_insert_threshold + autovacuum_vacuum_insert_scale_factor * reltuples.
  3. При превышении возраста таблицы relfozenxid параметра autovacuum_freeze_max_age.

Обычно автоочистка срабатывает в «ленивом» режиме, замораживая строки старше vacuum_freeze_min_age.

В агрессивном режиме запускается, если возраст таблицы больше vacuum_freeze_table_age или autovacuum_freeze_max_age. При работе в агрессивном режиме выставляется флаг «to prevent wraparound», при котором выводятся соответствующие предупреждения и запрещается прерывание процесса автоочистки, если таблица заблокирована.

Настройка

Параметры

Общие параметры настройки автоочистки:

Параметр

Описание

Значение по умолчанию

Специальные значения параметров

autovacuum

Включает процесс автоочистки

on

autovacuum_naptime

Интервал в секундах между запусками автоочистки

60

autovacuum_max_workers

Максимальное количество одновременно запущенных процессов автоочистки

3

autovacuum_work_mem

Максимальное количество используемой памяти в килобайтах для каждого процесса автоочистки

-1

-1 - Использование значения maintenance_work_mem

log_autovacuum_min_duration

Минимальное время исполнения автоочистки в миллисекундах для вывода логов автоочистки

600000

0 - Выводить все; -1 - Логи отключены

Внимание!

Если при запуске Pangolin значение autovacuum_max_workers меньше autovacuum_worker_slots, может произойти переполнение слотов.

Параметры условий запуска автоочистки:

Параметр

Описание

Значение по умолчанию

Специальные значения параметров

autovacuum_vacuum_threshold

Минимальное количество измененных строк (UPDATE или DELETE) для запуска автоочистки

50

autovacuum_vacuum_scale_factor

Множитель к количеству строк в таблице применительно к autovacuum_vacuum_threshold

0.2

autovacuum_vacuum_insert_threshold

Минимальное количество добавленных строк (INSERT) для запуска автоочистки

1000

-1 - Отключить автоочистку из-за добавления строк

autovacuum_vacuum_insert_scale_factor

Множитель к количеству строк в таблице применительно к autovacuum_vacuum_insert_threshold

0.2

autovacuum_analyze_threshold

Минимальное количество операций со строками (INSERT, UPDATE, DELETE) для обновления статистики

50

autovacuum_analyze_scale_factor

Множитель к количеству строк в таблице применительно к autovacuum_analyze_threshold

0.1

Параметры заморозки строк и таблиц:

Параметр

Описание

Значение по умолчанию

vacuum_freeze_min_age

Возраст строк для заморозки при автоочистке

50000000

vacuum_multixact_freeze_min_age

Возраст строк для заморозки MultiXactId

50000000

vacuum_freeze_table_age

Возраст таблицы для сканирования всей таблицы и заморозки всех строк (агрессивная автоочистка)

150000000

vacuum_multixact_freeze_table_age

Возраст мультитранзакций для агрессивной автоочистки

150000000

autovacuum_freeze_max_age

Возраст для агрессивной автоочистки от переполнения xid («to prevent wraparound»)

10000000000

autovacuum_multixact_freeze_max_age

Возраст мультитранзакций для агрессивной автоочистки от переполнения MultiXact («to prevent wraparound»)

20000000000

autovacuum_disable_freeze_max_age

При включении параметра кластер игнорирует пороги для агрессивной автоочистки, предназначенной для защиты от переполнения счетчика транзакций (autovacuum_freeze_max_age и autovacuum_multixact_freeze_max_age)

off

Параметры для 32-битных счетчиков:

Параметр

Описание

Значение по умолчанию

vacuum_multixact_failsafe_age

Возраст мультитранзакций для аварийной агрессивной автоочистки от переполнения MultiXact («to prevent wraparound»)

1600000000

vacuum_failsafe_age

Возраст для аварийной агрессивной автоочистки от переполнения xid («to prevent wraparound»)

1600000000

примечание

Параметры аварийной автоочистки: 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», ждет блокировок с предыдущих запусков), пропуская другие БД и таблицы.