Сайт использует сookies для хранения данных. Продолжая использовать сайт, вы даёте согласие на работу с этими файлами.

ОК
🧱
Данные
Опубликовано:
28.07.2026
Обновлено:
03.08.2026

pg_repack против VACUUM FULL: когда и что использовать

Илья Новиков

Раздувание таблиц (bloat) - неизбежная плата за механизм MVCC (Multiversion Concurrency Control) в PostgreSQL. Когда autovacuum не справляется, а обычный VACUUM не способен вернуть место операционной системе, перед администратором встаёт выбор: запланировать жёсткую блокировку с VACUUM FULL или провести онлайн-реорганизацию через pg_repack. Разберёмся, в каких случаях оправдан каждый из инструментов и на что обратить внимание в продакшен-среде.

Почему раздувание таблиц - это проблема

Как MVCC порождает мёртвые строки

PostgreSQL обеспечивает конкурентный доступ к данным за счёт многоверсионности (MVCC). Каждое обновление или удаление не перезаписывает строку на месте, а создаёт новую версию и оставляет старую помеченной как неактуальную. Со временем доля таких «мёртвых» кортежей (dead tuples) растёт, таблица раздувается, а индексы хранят ссылки на уже невидимые данные.

Типичные сценарии: массовые UPDATE/DELETE и их последствия

Самое заметное распухание возникает после массовых операций: пакетной очистки устаревших записей, длительных миграций или сбоев в настройках autovacuum. Таблица может занимать в несколько раз больше места, чем реальный объём «живых» данных. Обычный VACUUM освобождает пространство внутри файлов таблицы, но не умеет возвращать лишние страницы файловой системе. Поэтому страдает и производительность - sequential scan вынужден обходить огромное количество пустых или мёртвых блоков.

VACUUM FULL - встроенное, но блокирующее решение

Как работает VACUUM FULL: перезапись таблицы в новый heap‑файл

VACUUM FULL действует радикально: он полностью переписывает таблицу. Создаётся новый компактный набор файлов данных, в него копируются только живые строки, после чего старый heap‑файл удаляется, а все индексы перестраиваются с нуля. Благодаря этому достигается максимальное уплотнение и операционная система гарантированно получает высвобожденное место.

Блокировки и недоступность: ACCESS EXCLUSIVE на всё время операции

Главный недостаток встроенного метода - эксклюзивная блокировка (ACCESS EXCLUSIVE), которая накладывается на целевую таблицу с первой и до последней секунды выполнения команды. На это время любые попытки читать или писать в таблицу приостанавливаются, а параллельные запросы выстраиваются в очередь. Для небольших таблиц блокировка длится секунды, но для крупных продуктивных таблиц простой может растянуться на десятки минут и часов.

Ресурсы: потребность в двойном объёме дискового пространства

Поскольку операция создаёт полную новую копию таблицы и всех её индексов, до завершения команды в файловой системе должно быть достаточно места для одновременного хранения и старого, и нового набора файлов. Это означает, что для таблицы, реально занимающей 100 ГБ дискового пространства, понадобится ещё около 100 ГБ свободного места, иначе операция не выполнится.

Когда выбирать VACUUM FULL: запланированное окно, отсутствие pg_repack, экстренное освобождение места

VACUUM FULL оправдан, если у вас есть согласованное окно обслуживания и кратковременная недоступность сервиса допустима. Его также применяют в экстренных ситуациях, когда диск заполнен настолько, что нет возможности установить расширения, или таблица не удовлетворяет требованиям pg_repack. В управляемых средах, где pg_repack не настроен или запрещён политиками безопасности, встроенная команда может оказаться единственным доступным способом гарантированно вернуть место.

pg_repack - онлайн-реорганизация без длительного простоя

Как работает pg_repack: копия, отслеживание изменений и короткое переключение

pg_repack - расширение PostgreSQL для реорганизации таблиц и индексов. Сначала оно создаёт новую, компактную версию объекта, параллельно отслеживая все изменения, которые производятся приложением в оригинальной таблице. Когда основная копия готова, pg_repack применяет накопленную дельту и на очень короткое время захватывает эксклюзивную блокировку, чтобы подменить старые файлы новыми. После этого работа приложения продолжается уже с оптимизированным хранилищем.

Блокировки: кратковременный исключительный lock только в начале и в конце

В отличие от VACUUM FULL, pg_repack удерживает ACCESS EXCLUSIVE лишь на несколько миллисекунд в начале сессии (для синхронизации метаданных) и в момент финального переключения. Всё остальное время таблица полностью доступна для чтения и записи. Поэтому сервис остаётся работоспособным даже при реорганизации очень больших производственных таблиц.

Ограничения: обязательный PRIMARY KEY или UNIQUE индекс

Ключевое ограничение pg_repack - он работает только с таблицами, у которых есть первичный ключ или хотя бы один уникальный индекс. Без надёжного способа однозначно идентифицировать каждую строку механизм отслеживания изменений не может корректно синхронизировать оригинал и копию. Если таблица не удовлетворяет этому условию, pg_repack использовать не получится.

Когда выбирать pg_repack: продакшен с критичной доступностью, облачные сервисы

Основная область применения - базы данных с высокими требованиями к непрерывности. Когда сервис должен принимать запросы круглосуточно и каждая минута простоя обходится дорого, pg_repack становится предпочтительным решением. Он же отлично подходит для управляемых облачных инсталляций вроде Amazon RDS или Aurora, где его можно подключить и использовать, соблюдая рекомендации по настройке расширений.

Сравнение VACUUM FULL и pg_repack: ключевые различия

Влияние на доступность и время блокировки

VACUUM FULL блокирует таблицу на всё время перестроения - от старта до полного завершения. pg_repack ограничивает блокировку короткими техническими интервалами. На практике это означает, что с VACUUM FULL вам придётся останавливать прикладной трафик, а с pg_repack - можно продолжать работу, не планируя полноценное окно недоступности.

Требования к свободному месту и производительность

Оба инструмента нуждаются примерно в двойном объёме дискового пространства на время операции, так как и там, и там создаётся полная копия данных с индексами. По скорости непосредственно перестроения pg_repack сопоставим с командой CLUSTER, а VACUUM FULL в зависимости от версии PostgreSQL может работать быстрее или медленнее, но не на порядки. Основной выигрыш - не в часах выполнения, а в сохранении доступа к таблице.

Зависимость от наличия первичного ключа или уникального индекса

VACUUM FULL не предъявляет никаких требований к структуре таблицы, кроме наличия достаточного места и прав. pg_repack же невозможно запустить на таблице, где отсутствуют PRIMARY KEY или UNIQUE-индексы на любом столбце или наборе столбцов. Если архитектура приложения этого не предусматривает, выбор инструмента предопределён.

Использование в управляемых сервисах (RDS, Aurora)

pg_repack доступен в Amazon RDS и Aurora, но требует осознанной настройки: добавления расширения и корректировки параметров, разрешающих его работу. VACUUM FULL работает в облаке «из коробки», но и последствия у него те же - полная блокировка. Поэтому в облаке компромисс такой же, как и на собственных серверах: хотите избежать простоя - внедряйте pg_repack.

Рекомендации по выбору инструмента

Если простой допустим

При наличии регламентного окна обслуживания, когда пользователей можно предупредить, а мониторинг приглушить, VACUUM FULL - простое и надёжное средство без дополнительных зависимостей. Оно гарантированно возвращает место и не требует установки сторонних расширений.

Если сервис должен оставаться доступным

Выбирайте pg_repack. Он даёт почти нулевое время недоступности, позволяя проводить реорганизацию в фоновом режиме без отключения прикладных систем. Перед запуском убедитесь в наличии свободного места на диске и корректно настроенном мониторинге, чтобы вовремя заметить проблемы с отслеживанием изменений.

Если на таблице нет подходящего индекса

Единственный разумный выход в такой ситуации - VACUUM FULL, либо предварительное добавление уникального индекса, если бизнес-логика это позволяет. Осознанно создавать индекс только ради запуска pg_repack стоит далеко не всегда: оцените, не дешевле ли будет запланировать короткий простой для VACUUM FULL.

Если работаете в облаке: что нужно знать о pg_repack в RDS и Aurora

Убедитесь, что в вашем облачном окружении расширение можно активировать. В RDS и Aurora потребуется добавить pg_repack в shared_preload_libraries и установить его, после чего получить кратковременную блокировку в начале работы утилиты не будет проблемой. Обязательно протестируйте процесс на копии продукционной базы - в облаке управление ресурсами может отличаться от собственного «железа».

FAQ

Можно ли использовать pg_repack, если на таблице нет первичного ключа?
Нет. Обязательное условие - наличие первичного ключа или хотя бы одного уникального индекса. Без этого pg_repack не сможет корректно отслеживать изменения строк во время перестроения.

Как понять, что пора применять VACUUM FULL или pg_repack?
Явный признак - таблица занимает заметно больше места, чем ожидается исходя из количества живых строк, при этом обычный VACUUM и повторяющийся autovacuum не возвращают дисковое пространство операционной системе. Определить уровень раздувания можно по соотношению «мёртвых» и живых кортежей в статистике, не дожидаясь заполнения диска.

Что произойдёт, если прервать pg_repack?
Процесс прекратится, временная копия таблицы будет удалена, а оригинальная таблица останется нетронутой. Никаких необратимых изменений не случится, но реорганизацию придётся запустить повторно.

Есть ли альтернативы pg_repack и VACUUM FULL?
Помимо ручного пересоздания таблицы через CREATE TABLE AS… или утилит вроде pg_squeeze, принципиальных замен с минимальным простоем немного. Выбор обычно сводится к тому, насколько критична блокировка и есть ли на таблице подходящий индекс.

Как pg_repack себя ведёт с секционированными таблицами?
pg_repack поддерживает секционированные таблицы, но в продакшен-среде часто безопаснее обрабатывать каждую секцию по отдельности. Это даёт более предсказуемое время выполнения и снижает риск блокировок на родительской структуре.

Нужно ли останавливать приложение при VACUUM FULL?
Да. Поскольку команда удерживает ACCESS EXCLUSIVE, приложение не сможет ни читать, ни писать в таблицу до завершения операции. Любой открытый или новый запрос будет ожидать снятия блокировки, что внешне эквивалентно простою сервиса для этой таблицы.

Вывод

VACUUM FULL - встроенная и радикальная мера для гарантированного возврата дискового пространства, но ценой полной недоступности данных. pg_repack сохраняет работоспособность приложений ценой дополнительных требований к структуре таблицы и настройке окружения. Универсального ответа нет: ориентируйтесь на критичность простоя, наличие первичного ключа и возможности инфраструктуры. В любом случае перед запуском протестируйте операцию на нерабочей копии и убедитесь, что свежая резервная копия под рукой.

Источники

Это авторская статья, основанная на личном опыте и субъективном взгляде автора. Заметили ошибку или битую ссылку? Сообщите нам: info@codesrc.ru - мы оперативно исправим. Спасибо, что помогаете делать блог лучше.
Следите за нами в соцсетях:

Читайте также