附录 D:分区能力索引
分区不是一个孤立功能:是否该用、查询能否裁剪、如何在线迁移、时间边界怎样表达、 旧分区如何冻结/退役,分布在五个章节。本附录把它们串成一条生命周期。
D.1 ch04:分区决策门
ch04.6 先问:
不要因为“表会变大”自动分区。分区会增加:
- parent/child catalog、DDL、statistics 与 plan 开销;
- partition creation/retention automation;
- constraint/unique/FK 设计限制;
- prepared/generic plan 与参数裁剪不确定性;
- cross-partition query/index/maintenance 复杂度;
- migration、default partition 和 late-arriving data 处理。
key 选择
| 策略 | 适合 | 风险 |
|---|---|---|
| RANGE(time/id) | 时间生命周期、递增范围 | hot partition、时区/边界、未来 partition |
| LIST(tenant/region/state) | 少量稳定离散域 | key 增长、skew、default 膨胀 |
| HASH(key) | 均匀分布/并行维护 | 生命周期语义弱、重分片成本 |
| multi-level | 同时有生命周期与隔离 | partition 数和运维复杂度乘积 |
使用 [start, end) 边界,显式时区与 catch-all/拒绝策略。parent-level PRIMARY KEY /
UNIQUE 必须满足当前 PostgreSQL 对 partition key 的要求;不能假设多个本地索引自动
提供任意全局唯一性。
决策交付物
D.2 ch07:规划时/执行时裁剪与父表统计
ch07.4 用 EXPLAIN 区分:
检查:
关注:
常见裁剪失败
- predicate 没落在 partition key;
- 隐式 cast、时区或函数阻止匹配;
- wrapper/表达式与 partition bound 不同;
- generic/custom prepared plan 行为不同;
- join value 只能在执行阶段知道;
- default partition 覆盖过大;
- 误把 constraint exclusion 与 declarative pruning 混为一谈。
“查询结果快”不证明裁剪;小数据可能全扫仍快。保存 plan、参数、table definition、 statistics 和 server version。
statistics
parent/child 的 statistics、autovacuum/analyze 与增量数据分布可能不同。检查:
不要只在一个 child ANALYZE 后推断 parent workload 已正确估算。
D.3 ch11:在线分区化
ch11.4 把“改成分区表”当迁移项目:
PostgreSQL 不能把普通表原地无成本变成 partitioned parent。迁移策略可用新表、shadow
write、logical change capture、短暂停写或 ATTACH PARTITION,但每种都要重新验证
锁、WAL、trigger/FK、sequence、replica 和 rollback。
ATTACH PARTITION
若待 attach 表已有能证明 bound 的匹配 CHECK constraint,PostgreSQL 可避免为验证
partition constraint 扫描它;具体锁与扫描行为绑定版本与对象状态。default partition
还可能需要验证它不含新 range 数据。执行前:
attach 后再验证 parent query、direct child access、privilege、trigger、FK、stats 与 backup/replication。
dual write 风险
应用双写或 trigger capture 可能产生:
优先同一 transaction 内可验证机制;仍需 source-of-truth、reconciliation 和 cutover watermark。不要以两个 row count 相等作为唯一证明。
D.4 ch16:时间分区场景
ch16.2 先定义时间:
partition key 必须匹配主要生命周期和查询。按 ingest time 分区容易接收 late event, 却不一定裁剪 event-time 查询;按 event time 分区需要 future/late/default 策略。
边界规则
不要用本地日期字符串猜 DST 边界。保存实际 bound:
partition 内索引
时间 range 裁剪减少 child 数,child 内仍要按谓词、排序和 join 选 B-tree/BRIN/GiST 等。 BRIN 依赖物理相关性,不是“时序表默认更快”;空间 + 时间查询还要验证两种 selectivity 如何组合。
D.5 ch28:分区生命周期、冻结与退役
ch28.5 把 partition state 作为有限状态机:
每次 transition 有:
sealed 不等于无需 vacuum
旧 partition 即使不再业务写入,仍可能需要:
- freeze XID/multixact;
- 清理过去更新留下的 dead tuple;
- 更新 visibility map;
- 完成 index/constraint validation;
- 处理仍引用它的 snapshot/slot/prepared transaction。
观察每个 child 的 age、stats 和 size,不只看 parent aggregate。
detach/drop 与大 DELETE
按完整 partition 退役通常能避免逐行 DELETE 的大量 WAL/dead tuples,但 DDL 仍有锁、 依赖、replication、backup 与业务风险。先确认:
DETACH 后对象仍占空间;DROP 才释放 relation,且是不可逆 schema/data action。不要
把 retention policy 直接变成无人审批的自动 drop。
五章闭环检查
任一答案未知,先修生命周期合同,不急于增加 partition 数。
返回附录目录 · 对象与证据速查 · ch04 分区决策门 · 查看全书目录