likes
comments
collection
share

Mysql到底有几种锁

作者站长头像
站长
· 阅读数 14

前言

在我之前对于mysql🔒锁的理解,我会毫不犹豫的说出,在innoDB 的引擎下是行锁,就是for update对每行数据进行加锁,在myISAM 引擎下是表锁,多线程并发的情况下将整个表进行加锁,还有就是页锁介于行锁和表锁之间,对每页数据进行加锁,或许这是一个很笼统的回答,后面对于mysql的深入学习理解,发现锁的状态还是要分情况的,并且不仅仅是行锁、表锁。

InnoDB锁分类

  1. 行锁:共享锁(S)事务读取记录的时候加锁、排他锁(X)事务改动记录的时候加锁。 使用场景: * T1、T2两个事务,T1对一行数据加S锁,T2依旧可以访问这条数据,获取这条记录的S锁 * T2加X锁,X锁对于S锁,以及X锁是互斥的
  2. 表级锁:意向锁 * 意向排他锁:IX,行锁加入X,表级会加IX锁 * 意向共享锁:IS,行锁加入S锁,表级会加IS锁
  3. 记录锁:Record Lock for update 仅仅锁住一行,select a from table where a =1 for update ,a字段为主键、或者为唯一索引,会加一个记录锁。
  4. 间隙锁:gap 两个索引之间的锁,锁住这两个索引区间的数据。
  5. 插入意向锁
  6. 临键锁(Next-Key Lock) 记录锁+间隙锁,某条记录前间隙加的锁, 并且会对索引记录之前的区间进行加锁。

MyISAM全局锁

因为MyISAM的特殊性,仅仅只支持全表锁,在于它的索引和数据是分离的,索引存储的是物理地址,通过物理地址是无法找到数据的;

另外MyISAM的主键索引是非聚集索引,了解非聚集索引的小伙伴都知道,非聚集索引的物理顺序和逻辑顺序没有必然的联系,存储方式也是分开存储的;

隔离级别与锁之间的联系

这边主要看RC和RR的场景;

Read Commint 场景

在mysql8.0中 select * from table for update 实际是加了3把锁,一把IX意向排他锁,一把主键锁、一把唯一索引锁 ,⚠️意向锁是可以并行的,不是互斥的。 在发生更新和查询的场景,查询需要将主键索引锁住,才能防止通过主键进行update并发的时候,update需要感知select * from table for update 的存在。

Reapeatable Read场景

  • 查询条件是唯一索引字段,数据库一共加了3把锁,IX意向排他锁、主键X排他锁(行锁)、唯一索引X排他锁
  • 主键索引,2把锁,IX意向排他锁、主键X排他锁,锁主键索引。
  • 普通索引,IX意向排锁(表锁)、X(行锁)、gap(间隙锁)

总结

随着不断的学习理解,在发现问题的时候,才能站在更多的角度去看待这个问题,更好的解决问题,认知不同看待问题站在的角度就不同。

转载自:https://juejin.cn/post/7251393791227035685
评论
请登录