引言
在研究分区表相关解决方案时,曾聚焦于如何在包含多个子表的分区表内,实现跨分区的数据唯一性保障。这类功能有时被称为全局索引,相关领域的讨论可参考邮件线程此处。尽管其中提出的思路具备一定合理性,但对应的实现方式却引发了较多争议 —— 该方式改变了分区索引的存储逻辑,本质是将所有分区索引合并存储,并以TableOid作为内部引用的键值。
基于此,探索一种替代方案:在不改变 PostgreSQL 原有核心机制的前提下,实现跨分区唯一性保障。而要推进这一探索,首要任务是先厘清 PostgreSQL 分区表中,唯一性机制的底层工作原理。
CREATE INDEX 语句的唯一性保障
PostgreSQL 会通过以下基本流程检查唯一性冲突:
- 对目标子分区表执行堆扫描(heap scan)。
- 将可见元组(visible tuples)存储到一个
BTSpool结构(记为 spool1)中,将无效元组(dead tuples)存储到另一个BTSpool结构(记为 spool2)中。因此,这里会用到两个BTSpool结构;若表中无无效元组,或无需保障唯一性,则 spool2 可能为 NULL。BTSpool结构可理解为索引元组的集合。 - 若 spool1 和 spool2 存在,则对其进行排序。
- 排序算法内置重复检测功能:若排序后有两个相同的元组连续出现,即判定为重复;若该索引要求唯一性,则会在此处抛出错误。
- 若排序过程中未检测到重复,PostgreSQL 会基于 spool1 和 spool2 构建索引树。
- 索引创建完成后,销毁所有
BTSpool结构。 - 上述逻辑位于
src/backend/access/nbtree/nbtsort.c文件的btbuild()函数中,并由indexcmd

最低0.47元/天 解锁文章
1640

被折叠的 条评论
为什么被折叠?



