DBAtlas · Атлас эксплуатации баз данных

Реорганизовать раздутую таблицу без долгих блокировок (pg_repack)

PostgreSQLОбслуживание

Команда

-- Once per target database (the pg_repack package must be installed on the server)
CREATE EXTENSION pg_repack;

# Dry run: show what would be done
pg_repack -h localhost -U postgres -d mydb --table=public.orders --dry-run

# Rewrite the table and its indexes: 2 parallel index builds, wait at most 60 s for locks
pg_repack -h localhost -U postgres -d mydb --table=public.orders --jobs=2 --wait-timeout=60 --no-kill-backend

# Rebuild indexes only
pg_repack -h localhost -U postgres -d mydb --table=public.orders --only-indexes

Что делает

В фоне строит уплотнённую копию таблицы, через триггер записывает параллельные изменения в журнальную таблицу и в конце меняет таблицы местами под кратковременной блокировкой ACCESS EXCLUSIVE; в отличие от VACUUM FULL не блокирует чтение/запись на всё время работы.

Когда использовать

Когда на работающей системе нужно вернуть сильное раздувание, которое VACUUM вернуть не может (подтверждено через pgstattuple).

Внимание

У таблицы должен быть PRIMARY KEY или UNIQUE-индекс по столбцам NOT NULL. Временно требуется дополнительное место на диске, равное таблице вместе с индексами, и создаётся большой объём WAL (отставание реплик, объём архива). Блокировки ACCESS EXCLUSIVE нужны в начале и в конце; по истечении --wait-timeout по умолчанию конфликтующие запросы отменяются, а при необходимости их сессии завершаются, тогда как --no-kill-backend вместо этого пропускает таблицу. Не выполняйте DDL на целевой таблице во время работы. Версии клиента и расширения должны совпадать. При прерывании очистите остатки через DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack;

Открыть в DBAtlas →

Связанные материалы