Традиционно каждую осень выходит очередная мажорная версия СУБД PostgreSQL. Что нам готовит 19я версия — рассказываем с нашим экспертом по СУБД и автором курса по архитектуре и тюнингу SQL в PostgreSQL, Николаем Ихалайненом. В прошлых выпусках смотрели на нововведения для разработки, теперь настала очередь новинок для администрирования.
В PostgreSQL 19 появляется новая команда REPACK, которая предназначена для физической перепаковки таблиц. Она помогает устранить bloat, то есть избыточно занятое место, которое накапливается после большого количества операций UPDATE и DELETE.
REPACK не меняет сам принцип работы таких операций. PostgreSQL по-прежнему создает новую физическую копию таблицы, переносит в нее актуальные версии строк, пересоздает индексы, а затем заменяет старые файлы новыми. Именно за счет этого таблица становится компактнее, а неиспользуемое пространство может быть возвращено операционной системе.
Раньше похожие задачи решались с помощью команд VACUUM FULL и CLUSTER. VACUUM FULL использовался для освобождения места на диске, а CLUSTER — для физического упорядочивания строк таблицы по индексу. Однако обе операции требуют сильной блокировки таблицы, что особенно проблематично для крупных и активно используемых таблиц.
REPACK объединяет эти сценарии в одной команде. При обычном запуске он также блокирует таблицу, но при использовании опции CONCURRENTLY основная часть работы выполняется без длительной блокировки чтения и записи. Сильная блокировка все равно требуется, но обычно только на коротком финальном этапе, когда PostgreSQL заменяет старые файлы таблицы и индексов новыми.
Пример перепаковки таблицы в конкурентном режиме:
REPACK (CONCURRENTLY) orders;
В этом примере таблица orders переписывается в более компактном виде. Для пользователей и приложений это означает, что таблица в основном остается доступной во время операции, хотя кратковременная блокировка на финальном этапе все равно возможна.
Если необходимо не только убрать bloat, но и физически упорядочить строки таблицы по определенному индексу, можно использовать вариант с USING INDEX:
REPACK orders USING INDEX orders_order_date_idx;
Такой вариант близок по смыслу к CLUSTER: строки таблицы будут расположены в порядке, заданном индексом orders_order_date_idx, например по дате заказа.
После выполнения REPACK обычно нет необходимости дополнительно запускать VACUUM FULL или CLUSTER для той же таблицы. REPACK уже выполняет соответствующую физическую работу: уменьшает bloat, пересоздает индексы и, при использовании USING INDEX, упорядочивает строки по индексу.
Прошлые выпуски: PG19-I, PG19-II и PG19-III