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

62.5. 索引唯一性检查 #

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

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

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

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

如果唯一约束是可以推迟的,那么情况会变得更复杂:我们需要能够为新行插入一个索引条目,但是任何唯一性冲突错误都要推迟到语句结束甚至更晚才能报告。为了避免重复索引的许多非必要的搜索,索引访问方法应当在最初插入时进行初步的唯一性检查。如果这表明一定不存在冲突的活动元组,那么我们便完成了。否则,我们计划在强制执行约束时重新检查。如果在重新检查时,插入的元组和一些其他具有相同键的元组同时处于活动状态,则应当报告错误。(注意,出于此目的,活动 实际上意味着 索引条目 HOT 链中的任何元组都是活动的。)为了实施这一点,向 aminsert 函数传递一个 checkUnique 参数,其中包含以下值之一