После UPDATE или DELETE логический набор строк и физические файлы могут изменяться по-разному. Старая версия иногда ещё нужна читающей транзакции, а после завершения чтения её место не всегда немедленно возвращается файловой системе. Поэтому размер таблицы требует отдельного обслуживания.
Почему остаются старые данные
MVCC, многоверсионность, позволяет транзакциям видеть согласованное состояние данных. Если одна транзакция читает прежний снимок, а другая уже изменила строку, системе может понадобиться сохранить оба состояния до завершения соответствующих чтений.
Не всякая невидимая новой транзакции строка уже безопасна для удаления. Долгая транзакция может удерживать старый снимок и задерживать очистку. Поэтому при росте таблицы проверяют и характер изменений, и длительность транзакций. Завершившийся запрос внутри незавершённой транзакции не всегда означает, что старые версии больше никому не нужны.
Bloat называют избыточное физическое место, связанное с накоплением ненужных версий и свободных областей. Оно может увеличивать объём чтения и обслуживание индексов. Но одно отличие размера файла от числа видимых строк ещё не даёт точный размер bloat: влияют формат хранения, ширина, сжатие и уже выделенное свободное место.
Что делает VACUUM для heap
Обычный VACUUM очищает версии, которые больше не нужны транзакциям, и делает место доступным для повторного использования. В heap это прежде всего внутреннее переиспользование страниц. Если затем приходят новые записи, база может использовать освобождённые области вместо постоянного роста.
Это не обещает немедленного уменьшения файла на диске. Свободные участки внутри файла остаются частью выделенного пространства. В некоторых условиях можно освободить пустой конец файла, но это отличается от переписывания всей таблицы. Поэтому нормальный результат VACUUM может быть полезен и при почти неизменном размере файла.
VACUUM также участвует в обслуживании версий и индексов, а freeze защищает от проблем с возрастом идентификаторов транзакций. Расписание обслуживания зависит от объёма изменений и настроек кластера. Для распределённой таблицы нужно учитывать состояние всех сегментов: один переполненный диск уже способен сорвать общую операцию.
Что меняется у AO
В append-optimized таблицах UPDATE и DELETE оставляют скрытые строки в AO-файлах. Обычный VACUUM может выполнить compaction: перенести видимые строки из подходящего файла в новый и затем освободить старый. Это физическая работа с чтением и записью, а не мгновенное удаление признака невидимости.
Решение о compaction связано с долей скрытых строк в конкретном AO-файле и настройками порога. Порог нельзя трактовать как «вся таблица уменьшится на такой процент». У разных файлов разное состояние, а существующие транзакции могут влиять на возможность завершить очистку.
Обычная compaction допускает работу с таблицей во время переноса, но переключение файлов требует краткой блокировки. Поэтому описание «AO VACUUM вообще ничего не блокирует» тоже слишком сильное. При планировании учитывают конкурирующие операции и наличие места для промежуточной записи.
Чем отличается VACUUM FULL
VACUUM FULL выполняет более полное уплотнение с переписыванием данных. Он может вернуть больше пространства файловой системе, но требует дополнительного места под новую копию и блокировки ACCESS EXCLUSIVE. Пока она удерживается, другие операции с таблицей ждут.
Такую команду не добавляют после каждой загрузки ради красивого размера файла. Сначала оценивают накопленные изменения, ожидаемый выигрыш, запас диска и доступное окно. Если диск уже заполнен, переписывание без расчёта места может ухудшить ситуацию.
| Операция | Основная задача | Что она не гарантирует |
|---|---|---|
| VACUUM для heap | Очистка старых версий, повторное использование места | Сильное сокращение файла |
| VACUUM для AO | Очистка и подходящая compaction | Мгновенное сжатие всех файлов |
| VACUUM FULL | Более полное уплотнение | Работу без дополнительного диска и ожиданий |
| ANALYZE | Статистика для оптимизатора | Удаление старых версий |
Очистка, статистика и смена периода
ANALYZE и VACUUM решают разные задачи. Первый помогает выбрать план по текущим данным, второй обслуживает физическое состояние. Их можно запускать совместной формой, но полезно понимать, какой эффект ожидается от каждого этапа. Свежая статистика не освобождает диск, а очищенная таблица не обязательно имеет свежие оценки.
Для периодических данных иногда выгоднее подготовить новую часть и заменить период, чем массово обновлять строки старого. Это связано с партициями и правилами публикации. Переключение требует проверки данных, структуры, прав, зависимостей и блокировок; оно не становится безопасным только потому, что выполняется короткой командой.
Практический вопрос для обслуживания звучит так: что именно выросло и почему? Сначала отделяют прирост полезных данных от старых версий и временных файлов, затем проверяют длительные транзакции и распределение размера по сегментам. После этого выбирают операцию с понятным эффектом и стоимостью.