锁分类
加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类。
全局锁(mysql server 实现)的典型使用场景是,做全库逻辑备份
表级锁(mysql server 实现)分两种,一种是表锁,一种是元数据锁(MDL)。
行级锁(innodb 引擎 实现)。
间隙锁(Gap Lock), 锁的就是两个值之间的空隙 ,防止幻读.跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作。间隙锁之间都不存在冲突关系
next-key lock ,间隙锁和行锁合称 next-key lock
两阶段锁协议
在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
加锁规则 (可重复读隔离级别下)
两个“原则”、两个“优化”和一个“bug”:
- 原则 1:加锁的基本单位是 next-key lock,next-key lock 是前开后闭区间。
- 原则 2:查找过程中访问到的对象才会加锁。
- 优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。
- 优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。
- 一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。
参考 丁奇 ·《MySQL实战45讲》
参考 《高性能MySQL》