首页 > 数据库 > PostgreSQL > PostgreSQL 中唯一索引的工作原理
在研究分区表相关解决方案时,曾聚焦于如何在包含多个子表的分区表内,实现跨分区的数据唯一性保障。这类功能有时被称为全局索引,相关领域的讨论可参考邮件线程此处。尽管其中提出的思路具备一定合理性,但对应的实现方式却引发了较多争议 —— 该方式改变了分区索引的存储逻辑,本质是将所有分区索引合并存储,并以TableOid作为内部引用的键值。
基于此,探索一种替代方案:在不改变 PostgreSQL 原有核心机制的前提下,实现跨分区唯一性保障。而要推进这一探索,首要任务是先厘清 PostgreSQL 分区表中,唯一性机制的底层工作原理。
PostgreSQL 会通过以下基本流程检查唯一性冲突:
BTSpool结构(记为 spool1)中,将无效元组(dead tuples)存储到另一个
BTSpool结构(记为 spool2)中。因此,这里会用到两个
BTSpool结构;若表中无无效元组,或无需保障唯一性,则 spool2 可能为 NULL。
BTSpool结构可理解为索引元组的集合。BTSpool结构。src/backend/access/nbtree/nbtsort.c文件的
btbuild()函数中,并由
indexcmds.c文件的
DefineIndex函数调用。根据活跃子分区表的数量,
DefineIndex会多次调用
btbuild。在规划器(planner)和优化器(optimizer)阶段,PostgreSQL 已确定新数据应插入或更新至哪个子分区表:
src/backend/access/nbtree/nbtinsert.c文件中的
_bt_doinsert()函数,尝试插入与该堆元组关联的新索引元组。_bt_check_unique()函数从堆分区表中查询是否存在匹配的现有元组。CREATE UNIQUE INDEX CONCURRENTLY(并发创建唯一索引)操作。上述逻辑主要位于
src/backend/access/nbtree/nbtinsert.c文件的
_bt_doinsert()和
_bt_check_unique()函数中。
待附加(ATTACH)的表可能已定义唯一索引(或非唯一索引),也可能完全没有索引。ATTACH 操作过程中存在两种潜在情况:
2.0节中定义的步骤。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70043484/viewspace-3094858/ ,如需转载,请注明出处,否则将追究法律责任。