Команды VACUUM FULL и CLUSTER
Команда VACUUM FULL удаляет все бесполезные записи (dead tuples) и полностью дефрагментирует действующие записи по всем файлам, где есть данные. Она выбирает действительное содержимое таблицы в новые файлы на диске, не содержащие ничего лишнего, что позволяет возвратить неиспользованное пространство операционной системе.
Несмотря на то, что алгоритм VACUUM FULL по коду имеет много общего с VACUUM (общие параметры и настройки, права, код работы с транзакциями), они делают с данными и объектами совершенно разные вещи.
Используя VACUUM FULL, следует всегда помнить о двух моментах:
- никто не может ни прочитать, ни записать данные таблицы в продолжение всего времени работы
VACUUM FULL; - на время работы команды требуется временное дисковое пространство, вплоть до полного объема таблицы с индексами, с учетом размещения объектов по табличным пространствам.
Алгоритм VACUUM FULL можно описать следующим образом:
-
Для каждой таблицы выполните действия:
-
установите эксклюзивную блокировку на таблицу (AccessExclusiveLock);
-
создайте временный файл данных для таблицы (включая TOAST, если необходимо);
-
в цикле по каждой из действующих записей таблицы:
- скопируйте запись в промежуточный файл таблицы;
- если необходимо, заморозьте запись.
-
завершите цикл по записям.
-
-
Завершите цикл по таблицам.
-
Если необходимо, удалите старые файлы и страницы clog.
Полностью алгоритм можно изучить в исходных кодах сервера:
VACUUM FULL всегда выполняет агрессивную заморозку записей. Можно считать, что на время ее работы параметры vacuum_freeze_min_age и vacuum_freeze_table_age установлены в 0. Как если бы в обычной команде VACUUM использовался ключ FREEZE.
VACUUM FULL всегда сопровождается полной переиндексацией таблицы, поэтому параметр INDEX_CLEANUP тоже игнорируется. Всегда пересоздается и таблица хранения сверхбольших атрибутов TOAST.
VACUUM FULL не может выполняться в параллельном режиме.
VACUUM FULL организует манипуляции с каталогами по каждой из таблиц в отдельную транзакцию и требует выделения стольких транзакций, сколько таблиц очищает.
Длительный VACUUM FULL способен, как и любая длительная транзакция, вызвать инцидент с переходом сервера в состояние «только для чтения» по исчерпанию номеров транзакций. Подробнее описано в разделе «Автоочистка для предотвращения зацикливания счетчиков».
Будьте осторожны - планируйте VACUUM FULL по объемным таблицам на время минимальной транзакционной нагрузки!
Команду CLUSTER можно понимать как вариант VACUUM FULL, который в процессе переноса данных дополнительно упорядочивает таблицу в порядке сортировки указанного индекса, что повышает производительность запросов с выборкой и сортировкой по ключу индекса. Точнее, это VACUUM FULL реализован как вариант CLUSTER с отключенным упорядочиванием данных.
Подходит для:
- очистки таблицы после постоянного изменения ее назначения в архитектуре приложения, например, переноса большей части данных из таблицы в архивное хранилище;
- очистки таблицы, раздутой в результате пика аномальной нагрузки и/или существенного отставания автоочистки;
- полной дефрагментации таблицы;
- принудительного применения изменений параметров хранения таблицы к хранимым в таблице данным.
Не подходит для:
- периодической, регламентной очистки устаревших данных - рекомендуется для постоянной работы настроить автоочистку, а в масштабных трансформациях данных сразу выполнять
VACUUM, лучше с ключомANALYZE; - предотвращения оборота счетчика транзакций (wraparound) -
VACUUM FULLбудет отнимать почти закончившиеся номера транзакций, здесь рекомендуетсяVACUUMпо проблемным таблицам, можно с агрессивной заморозкой (FREEZE).
Блокировка во время VACUUM FULL
На уровне таблицы VACUUM FULL работает с постоянной блокировкой наивысшего уровня ACCESS EXCLUSIVE (AccessExclusiveLock). В этом режиме недопустимы любые параллельные операции с таблицей.
Этот уровень блокировки - единственный, на котором заблокирован даже оператор SELECT без FOR UPDATE/SHARE.
Подробнее - в документации, 13.3. «Явные блокировки».