Innodb加锁规则

2021-07-27 14:41:13 浏览数 (1)

加锁顺序

普通select查询

  • 获取表级锁: MDL读锁
  • 不需要其他锁: 因为使用的是MVCC,所以不需要行锁 ps: 很多地方都说使用了MVCC就不需要加锁,实际上是不需要行锁,MDL读锁还是需要的

共享读select in share mode

  • 首先获取表级锁: MDL写锁
  • 再获取表级锁: 意向共享锁
  • 再获取行级锁: 根据不同语句获取对应的行锁和间隙锁

insert插入

  • 首先获取表级锁: MDL写锁
  • 再获取表级锁: 意向排它锁
  • 再获取行级锁: 插入意向锁

update/delete

  • 首先获取表级锁: MDL写锁
  • 再获取表级锁: 意向排它锁
  • 再获取行级锁: 根据不同语句获取对应的行锁和间隙锁

行锁加锁规则

两个“原则”、两个“优化”和一个“bug”

  • 原则 1:加锁的基本单位是 next-key lock。希望你还记得,next-key lock 是前开后闭区间。
  • 原则 2:查找过程中访问到的对象才会加锁。
  • 优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。
  • 优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。
  • 一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

锁冲突和兼容规则

  • MDL: MDL只与MDL存在冲突,读锁兼容读锁,写锁与读锁或写锁都不兼容
  • 意向锁规则: (IS 意向共享锁, IX意向排它锁, S共享锁, X排它锁)

IS

IX

S

X

IS

IX

S

X

  • 行锁规则: record lock行锁,gap lock间隙锁, insert intension lock间隙锁, next key lock(行锁 间隙锁)

加的锁 已存在的锁

record lock

gap lock

insert intention lock

next key lock

record lock

gap lock

insert intention lock

next key lock

参考

  • MySQL实战45讲: 为什么我只改一行的语句,锁这么多?
  • MySQL加锁分析

0 人点赞