数据库内核月报

数据库内核月报 - 2018 / 12

PgSQL · 原理介绍 · PostgreSQL行锁实现

Author: kangxian

锁是数据库很重要的机制,PostgreSQL支持表锁,行锁,了解PostgreSQL行锁机制有助于我们在应用中分析和解决行锁的问题。

锁模式

当前PG支持4种行锁模式: FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE,我们常见的delete场景获取的均为FOR UPDATE锁,而update场景会获取FOR NO KEY UPDATE或者FOR UPDATE,要看有没有唯一索引了。 下面表格记录了4种锁模式的兼容情况。

image.png

加锁流程

image.png

MultiXact

对于FOR UPDATE和FOR NO KEY UPDATE锁,可以方便通过Tuple上的xmax判断谁持有锁,而对于FOR SHARE和FOR KEY SHARE,一个Tuple上面可能会被多个事务加锁,Tuple上动态维护这些事务代价很高,为了便于维护这些事务状态,PG引入了MultiXact机制,把多事务记录到独立buffer和文件中,如图所示。当触发多事务机制时,会生成一个新的MultiXactId,把当前Tuple对应的所有锁成员放在MultiXactMemberPage中,并把新的MultiXactId保存在xmax中。

image.png

总结

PostgreSQL行锁相对于Oracle和MySQL的实现还是有区别的,Oracle记录在ITL中,但是不支持select for share,MySQL记录在bitmap中,但是当更新特别多的时候,产生大量的行锁,bitmap会占用大量内存。