mysql Innodb锁的三种算法 record lock、gap lock、next key lock

77 阅读2分钟

环境:innodb引擎 rr隔离级别

一、record lock 记录锁

锁定单条记录

二、gap lock 间隙锁

锁定两个记录之间的间隙

三、next key lock 临键锁

锁定记录之间的间隙和记录本身

四、加锁规则 : 两个原则 两个优化 一个BUG

加锁的默认基本单位是临键锁。

select * from t where for update

锁定全表情况下,会用一个个的临键锁把全表进行锁定。

例如:(-∞,5]、(5,10]、(10,15]、(15,+supremum]

临键锁是一个前开后闭区间。

10的临键锁区间就是上一个记录5到本记录10之间的间隙,和10本身——即(5,10]

查找过程中访问到的对象才会加锁。

优化1

索引上的等值查询,给唯一索引进行加锁时,数据中查找到指定行,临键锁退化为记录锁。

备注:等值查询到目标数据后,只给该行数据加记录锁,不再加其他的锁。

优化2

索引上的等值查询,向右遍历到最后一个值不满足等值条件时,临键锁退化为间隙锁——即不锁定最后一个不符合条件的值。

备注:比如查询id=12的值,12不存在,查询到15后,会锁定15的间隙,即15之前的间隙,不锁定15本身。

一个bug

唯一索引上的范围查询会访问到不满足条件的第一个值为止。

五、总结

还是不太清楚加锁的规则,只知道进行范围查询和等值查询的行不存在时,对附近的区间加锁,从而避免幻读问题。

接下来准备研究一下data_locks表和各个字段,看看具体的锁加在哪些地方,从而更清楚的理解临键锁的加锁机制。