问题描述
根据postgres docs section 13.3.2
除表和行锁外,页面级共享/独占锁 用于控制对共享中表页面的读/写访问 缓冲池。这些锁在一行被删除后立即释放 获取或更新。应用程序开发人员通常不需要 与页面级锁有关,但此处提到它们是为了 完整性。
我的理解是,我不必担心我的事务是否足够大,以至于它们可以锁定足够长的行,从而发生以下情况:T1锁定了P1上的R1,但想锁定R2上的R2,但不能这样做因为T2在P2的R3上有一个锁,并且直到它在P1的R4上得到锁才释放它。
T->交易
P->页
R->行
这个假设是正确的还是我应该使我的交易时间足够短以至于这种锁定不太可能发生?
解决方法
页面级锁始终保持很短的时间,无论您的事务花费多长时间。与其他锁不同,它们是在提交之前释放的,在不再需要时会立即释放。
此外,页面锁总是以无法参与死锁的方式获取(除非PostgreSQL有错误)。
详细信息:
使用LockPage
中的src/backend/storage/lmgr/lmgr.c
函数获取页锁。当前,当挂起列表集成到主索引(ginInsertCleanup
中的函数src/backend/access/gin/ginfast.c
)时,它们仅在索引清除期间与GIN索引一起使用:元页被锁定以防止该函数并发执行。