Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

64.5. 索引唯一性检查 #

PostgreSQL 使用唯一索引来强制执行 SQL 唯一性约束,这些索引不允许具有相同键的多个条目。支持此功能的访问方法将 amcanunique 设置为 true。(目前,只有 b-tree 支持它。)在强制唯一性时,不会考虑 INCLUDE 子句中列出的列。

由于 MVCC,始终需要允许在索引中物理存在重复条目:这些条目可能引用单个逻辑行的连续版本。我们实际要强制执行的行为是,没有 MVCC 快照可以包含两个具有相等索引键的行。当将新行插入唯一索引时,这会细分为必须检查的以下情况

此外,在根据上述规则报告唯一性冲突之前,访问方法必须重新检查正在插入行的活动状态。如果已提交死,则不应报告违规。(在插入当前事务刚刚创建的行这种普通情况下,不会发生这种情况。但是,在CREATE UNIQUE INDEX CONCURRENTLY期间可能会发生。)

我们要求索引访问方法自行应用这些测试,这意味着它必须进入堆中以检查根据索引内容显示具有重复键的任何行的提交状态。毫无疑问,这是丑陋且不可模块化的,但它节省了重复的工作:如果我们进行单独的探测,则在查找插入新行索引条目的位置时,冲突行的索引查找本质上会重复。更重要的是,除非冲突检查是插入新索引条目的一个组成部分,否则没有明显的方法可以避免竞争条件。

如果唯一约束是可以延迟的,则会有额外的复杂性:我们需要能够为新行插入索引条目,但将任何唯一性冲突错误延迟到语句结束甚至更晚。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行初步唯一性检查。如果这表明绝对没有冲突的活动元组,我们就完成了。否则,我们安排在强制约束时进行重新检查。如果在重新检查时,插入的元组和具有相同键的其他元组都处于活动状态,则必须报告错误。(请注意,出于此目的,活动 实际上意味着索引条目 HOT 链中的任何元组都是活动状态。)为了实现这一点,aminsert 函数传递了一个checkUnique 参数,该参数具有以下值之一