MySQL 是怎么加锁的
MySQL 是怎么加锁的
什么 SQL 语句会加行级锁?
普通select不会加锁,除非是串行化隔离等级。但是select ...for update
或者select ...lock in share mode
加锁,统称为锁定读。还有update delete语句也会加锁
行级锁有哪些种类?
三种,分别是record lock,gap lock,next-key lock
record lock :只对某一行加锁
- record分为s和x
- s:共享锁,和s共享,和x互斥
- x:排他锁,和s,x都互斥
gap lock:对某个范围加锁
next-key lock:对某个返回和某一行加锁
行级锁分为共享锁(s)和排他锁(x)
MySQL 是怎么加行级锁的?
加锁的对象是索引,加锁的基本单位是next key lock.
如果next key lock可以在其他情况下可以避免幻读,就退化为gap 或者record
唯一索引等值查询
- 当查询的记录是「存在」的,在索引树上定位到这一条记录后,将该记录的索引中的 next-key lock 会退化成「record」。
- 当查询的记录是「不存在」的,在索引树找到第一条大于该查询记录的记录后,将该记录的索引中的 next-key lock 会退化成「gap lock」。
有什么命令可以分析加了什么锁?
通过命令select * from performance_schema.data_locks\G;
\G表示每个字段一行
通过LOCK_MODE 可以确认是 next-key 锁,还是间隙锁,还是记录锁:
- 如果 LOCK_MODE 为
X
,说明是 next-key 锁; - 如果 LOCK_MODE 为
X, REC_NOT_GAP
,说明是记录锁; - 如果 LOCK_MODE 为
X, GAP
,说明是间隙锁;
为什么唯一索引等值查询并且查询记录存在的场景下,该记录的索引中的 next-key lock 会退化成记录锁?
查到记录,如果插入会因为主键相同报错,不会改变记录
如果修改删除操作可以通过记录锁来阻塞,也不会改变记录
如果查询的值不存在,例如表的id字段有1,2,3,5如果查询4的话,会退化为gap锁。
在5上加了gap就可以避免幻读问题。首先范围是(3,5),只需要保证4不被插入,其他的数据有没有改变都可以,因为其他数据变了也不影响查询4的结果,语句只查询id=4的。
剩下的区域以后再探索吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)