在不阻塞在线流量的情况下卸载旧分区(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 完成。不带 CONCURRENTLY 的普通 DETACH 更快,但需要父表上的 ACCESS EXCLUSIVE;请配合 lock_timeout 尝试。