我知道同时创建索引时,只需要一个SHARE ShareUpdateExclusiveLock 锁。
但是,在流程开始的一小段时间内是否需要更严格的锁定类型?还是整个操作只需要一个SHARE ShareUpdateExclusiveLock 锁?
我问是因为我想知道在同时创建索引时设置哪些类型的超时是有利的。
我知道同时创建索引时,只需要一个SHARE ShareUpdateExclusiveLock 锁。
但是,在流程开始的一小段时间内是否需要更严格的锁定类型?还是整个操作只需要一个SHARE ShareUpdateExclusiveLock 锁?
我问是因为我想知道在同时创建索引时设置哪些类型的超时是有利的。
好吧,当文档不足时,可以直接查看代码。为了避免将来可能的行号更改,我将提供已发布
PostgreSQL 13.1
(标签)的链接。REL_13_1
我可能不会描述来自客户端的命令的整个代码路径。通过语法,我们知道我们需要
IndexStmt
命令节点——并发和非并发创建索引的语法相同。一切有用的开始ProcessUtilitySlow
在这里,在评论中
case T_IndexStmt
,可以找到问题的直接答案:一般来说,PostgreSQL 在命令执行期间不会升级锁。并将采取最终需要的最强锁。因为
CREATE INDEX CONCURRENTLY
它ShareUpdateExclusiveLock
。不是SHARE
问题中提到的锁。但让我们继续阅读:
find_all_inheritors
继承者将获得相同的锁定模式。transformIndexStmt
可以找到一些锁定模式,但是NoLock
-AccessShareLock
它们比ShareUpdateExclusiveLock
DefineIndex
我们看到另一个提醒:并决定再次使用 ShareUpdateExclusiveLock 进行并发构建。这部分代码明显很长(仍然没有规划器那么大),但可读。
我错过了什么?大概。因此,让我们构建带有
-DLOCK_DEBUG
调试锁定行为选项的 PostgreSQL,看看会发生什么:trace_locks
会记录很多东西,但我们感兴趣的是:lock [12664,16387]
这里的意思是 databaseOID = 12664
,pg_class
OID = 16387
(这些行是从 记录的LockAcquireExtended
)。所以,我们实际上只
ShareUpdateExclusiveLock
在表本身上获取。OID=16393
与其他几个锁是该命令建立的索引。尽管针对此对象提到了重锁定级别,但它不会干扰其他查询。Create index concurrently
命令专门设计用于在运行正常的应用程序查询时安全工作。