MySQL行锁、记录锁、间隙锁、临建锁、意向锁、表锁

1、行锁

行锁实际上是加在索引上的,因此当执行的加锁的语句的条件列若是没有索引的的时候,此时加的就不是行锁,而是表锁

2、三种行锁

记录锁:MySQL会为该行的索引加上锁,避免其他的并发事务同事操作这一条数据。例如:select * from user where id = 1 for update,此时就会为id=1的这条记录加上记录锁。

间隙锁:它会锁定记录的间隙,间隙锁是不包含该索引记录本身的,是为了那些不存在的记录加锁。例如当前表中有id为1,5,9的三条记录,那么此时就存在(负无穷,1)、(1,5)、(5,9)、(9,正无穷)四个区间,间隙锁可以锁定上面的区间,避免其他并发事务往这些区间插入数据,利用这样的方式去解决RR隔离级别下部分幻读的问题。

临建锁(Next-Key Lock):可以理解为行锁+间隙锁的组合,间隙锁不锁定当前记录本身,而临建锁它实在锁住对应的区间的情况下,还会将当前记录也锁住,为当前记录加上记录锁,而在innodb存储引擎中,RR隔离级别的情况下,默认会采用临建锁去进行加行锁。但是针对不同的情况下,它可能会调整为记录锁、表锁以及间隙锁。

3、锁的调整情况

当对唯一索引去进行匹配时,对一个已经存在的数据去做等值判断,此时使用的是记录锁。

如果条件列没有索引,此时无法加行锁,此时用的就是表锁。

如果对唯一列做等值查询,且该加锁的记录不存在时,那么此时就使用间隙锁。例如表中有id=2,9这两条数据,此时当我们update ... id = 5的时候,那么就会对(2,9)这个区间加一个间隙锁

如果是对非唯一的普通索引做等值查询时,向右遍历的最后一个值不满足查询条件的时候,则会退化为一个间隙锁,这个原因是由于非唯一索引不能仅仅锁住当前记录本身,还要锁住下一个大于当前值的索引的间隙,避免由于插入重复的记录,导致出现幻读。例如有索引age=20,25这两条数据,当我们要对20去进行加锁的时候,由于是非唯一索引,因此还会继续向右遍历数据直到25,会锁住(20,25)之间的间隙,避免因为重复插入20导致出现幻读

如果是对唯一索引进行范围查询时,会一直向范围方向遍历到第一个不满足查询条件的值为止,知道正负无穷大,例如有id=80,88这条件记录,加锁的条件为id>=80,那么此时则会为80加上记录锁,(80,88)以及(88,正无穷)会加上对应的间隙锁,那这也就是组合起来变成临建锁

4、总结

MySQL锁是加在索引记录上面的。

如果是非唯一性索引,不论表中是否存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。

如果是唯一索引,如果表中存在该记录,只对该行记录加锁。如果表中不存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。

5、意向锁

一个表中有许多记录,一个事务为表中的某一行数据添加了行锁,另一个事务需要为该表添加表锁的时候,如何知道这个表中还有没有其他的行锁呢?

当需要加行锁的时候,MySQL会先为当前表加上意向锁,若此时有其他事务需要申请表锁的时候,则只需要判断该表是否存在兼容的意向锁即可。不需要遍历所有的行来判断是否存在行锁。

有了意向锁,不能再申请表锁,但是如果锁的不是同一行,其他事务是可以申请行锁的。

6、二级索引的更新加锁过程

  1. MySQL首先会在二级索引上找到对应的索引记录 并对其加锁
  2. 然后,因为二级索引中包含了对应行的主键值, MySQL会使用这个主键值来定位主键索引中的记录
  3. 一旦找到了主键索引中的记录,MySQL会对这 个记录加锁
  4. 在锁定了必要的索引记录之后,MySQL会执行 实际的数据更新
  5. 如果更新的列是二级索引的一部分,那么 MySQL还需要更新二级索引中的记录
  6. 更新完成后,MySQL会释放所有在此过程中获得所有锁
相关推荐
NineData10 小时前
NineData 迁移评估功能正式上线
数据库·dba
NineData15 小时前
数据库迁移总踩坑?用 NineData 迁移评估,提前识别所有兼容性风险
数据库·程序员·云计算
赵渝强老师17 小时前
【赵渝强老师】PostgreSQL中表的碎片
数据库·postgresql
全栈老石21 小时前
拆解低代码引擎核心:元数据驱动的"万能表"架构
数据库·低代码
倔强的石头_2 天前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou643 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
于眠牧北3 天前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql
李广坤4 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
Turnip12025 天前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
爱可生开源社区5 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba