我们在运行 PostgreSQL 13 的一个数据库中发现了这种奇怪的行为。ExclusiveLock
我无法挖掘导致这种锁定的原因,因为锁定信息来自监控工具。
从我所看到的文档来看,ExclusiveLock
只能通过刷新获得materialised view
,但是我们的数据库中没有任何物化视图。经过一番研究,我最终找到了这个博客https://blog.heroku.com/curious-case-table-locking-update-query,这个人分享的案例与我的类似,因为我可以看到在此期间有几个查询RowExclusiveLock
,并且有几个查询同时更新同一行。但是,我找不到任何关于 PostgreSQL 在锁升级方面的行为的官方文档,就像其他数据库一样。
Postgres 是否会在极少数情况下升级锁定?哪些情况会导致升级?
PostgreSQL 不会升级锁(好吧,我在撒谎——当索引被删除时,索引页上的谓词锁会升级为表锁,但这不是这里发生的事情)。PostgreSQL 通过将行锁存储在行本身上而不是共享内存锁定表中来避免锁升级的需要。
如果您仔细查看该
pg_locks
条目,您会发现独占锁不是针对表,而是针对事务。每个事务都针对其自己的事务号拥有独占锁。如果会话遇到冲突的行锁,它会等待事务号上的共享锁,以等待锁定事务结束。这就是您一定看到的内容。也许这篇文章可以帮助您理解这个问题。