Команды 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. «Явные блокировки».