PostgreSQL ATTACH PARTITION 要求子表严格匹配父表的CHECK/NOT NULL约束、分区键表达式及类型,INHERITS表需先NO INHERIT;DETACH仅解除关系不删数据但移除隐式CHECK;二者均需ACCESS EXCLUSIVE锁,阻塞写入,不支持在线执行。

attach 分区时主表约束必须完全匹配
PostgreSQL 要求 ATTACH PARTITION 的目标表(即待挂载的分区表)必须满足所有父表的约束条件,尤其是 CHECK 约束和 NOT NULL 约束。即使你用的是范围或列表分区,PostgreSQL 仍会显式检查子表的约束是否能被父表的分区键逻辑覆盖。
- 如果子表有额外的
CHECK约束(比如CHECK (status = 'active')),而父表没有对应定义,ATTACH会失败 - 子表不能缺少父表中定义为
NOT NULL的分区键列的NOT NULL约束 - 使用
INHERITS创建的旧式继承表不能直接ATTACH,必须先NO INHERIT掉原继承关系
detach 操作不自动删除数据,但会断开约束依赖
DETACH PARTITION 只是解除父子关系,不会删数据、不改表结构、也不清索引。但要注意它会移除子表上由分区机制自动添加的隐式 CHECK 约束(例如 CHECK (created_at >= '2024-01-01' AND created_at )。
- detach 后子表变成普通表,其数据不再受父表约束检查,查询父表时也不会包含它
- 若子表仍有外键指向其他表,或被视图/函数引用,detach 仍可成功,但后续 DML 可能因约束缺失出错
- detach 前建议手动备份该分区的
CHECK定义,否则恢复 attach 时得重新推导边界
并发下 attach/detach 会持锁阻塞写入
这两个操作都需要在父表上获取 ACCESS EXCLUSIVE 锁,意味着:
- 所有对父表的
INSERT/UPDATE/DELETE会被阻塞,直到操作完成 - 长事务或大分区(尤其带大量索引)会让锁持有时间显著增加
- 不支持在线执行:无法在业务高峰期间静默完成;若需最小化影响,应选低峰期,并提前
VACUUM目标分区以减少锁内扫描开销
分区键表达式变更后 attach 会失败
如果父表使用表达式分区(如 PARTITION BY RANGE (date_trunc('month', created_at))),那么待 attach 的子表必须:
- 使用完全相同的表达式定义分区键,包括函数名、参数顺序、时区设置(如
date_trunc('month', created_at AT TIME ZONE 'UTC')和... AT TIME ZONE 'Asia/Shanghai'被视为不同) - 子表的分区键列类型必须与表达式结果类型严格一致(例如
date_trunc返回TIMESTAMP WITHOUT TIME ZONE,就不能用TIMESTAMP WITH TIME ZONE列直接映射)
这类不匹配通常报错:partition constraint is violated by some row,但实际原因常是表达式语义不等价,而非真有脏数据。










