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

Отключить старую секцию, не блокируя рабочий трафик (DETACH CONCURRENTLY)

PostgreSQLСекционирование

Команда

-- Must run outside a transaction block
ALTER TABLE sales DETACH PARTITION sales_2026_01 CONCURRENTLY;

-- If interrupted (cancel, lost connection) the partition stays 'detach pending'; complete it:
ALTER TABLE sales DETACH PARTITION sales_2026_01 FINALIZE;

-- Any pending detach?
SELECT inhrelid::regclass AS partition_name, inhparent::regclass AS parent
FROM pg_inherits
WHERE inhdetachpending;

-- The detached table is now standalone: archive or drop it
DROP TABLE sales_2026_01;

Что делает

Отключает секцию в двух транзакциях; берёт на родителе только SHARE UPDATE EXCLUSIVE, поэтому выполняющиеся запросы не блокируются, и добавляет к отключённой таблице ограничение CHECK, эквивалентное границе секции.

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

При отключении старых периодов на работающей системе для хранения/архивирования (с последующим DROP, переносом в другое табличное пространство или архивом pg_dump).

Внимание

Нельзя выполнять внутри блока BEGIN ... COMMIT и нельзя использовать, если у родителя есть секция по умолчанию. Ожидает все транзакции, использующие родителя и начавшиеся до неё; долгие транзакции её затягивают. При прерывании секция остаётся скрытой от запросов, но не отключённой ('detach pending'), и её нужно завершить через FINALIZE. Обычный DETACH без CONCURRENTLY быстрее, но требует ACCESS EXCLUSIVE на родителе; пробуйте его с lock_timeout.

Открыть в DBAtlas →

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