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

Команды VACUUM FULL и CLUSTER

Команда VACUUM FULL удаляет все бесполезные записи (dead tuples) и полностью дефрагментирует действующие записи по всем файлам, где есть данные. Она выбирает действительное содержимое таблицы в новые файлы на диске, не содержащие ничего лишнего, что позволяет возвратить неиспользованное пространство операционной системе.

Несмотря на то, что алгоритм VACUUM FULL по коду имеет много общего с VACUUM (общие параметры и настройки, права, код работы с транзакциями), они делают с данными и объектами совершенно разные вещи.

Используя VACUUM FULL, следует всегда помнить о двух моментах:

  • никто не может ни прочитать, ни записать данные таблицы в продолжение всего времени работы VACUUM FULL;
  • на время работы команды требуется временное дисковое пространство, вплоть до полного объема таблицы с индексами, с учетом размещения объектов по табличным пространствам.

Алгоритм VACUUM FULL можно описать следующим образом:

  1. Для каждой таблицы выполните действия:

    • установите эксклюзивную блокировку на таблицу (AccessExclusiveLock);

    • создайте временный файл данных для таблицы (включая TOAST, если необходимо);

    • в цикле по каждой из действующих записей таблицы:

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

  2. Завершите цикл по таблицам.

  3. Если необходимо, удалите старые файлы и страницы 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. «Явные блокировки».