您的当前位置:首页 >系统运维 >理清MySQL的行锁、意向锁、记录锁、间隙锁和临键锁 正文
时间:2025-11-04 08:12:06 来源:网络整理编辑:系统运维
在日常开发工作中,Mysql是常用的数据库之一,突然某天Mysql数据库告警提示出现了死锁问题,为了解决死锁问题,我们就需要掌握一些关于Mysql的锁的知识。1、行锁 在InnoDB存储引擎中行级锁
在日常开发工作中,理清录锁临键Mysql是行锁常用的数据库之一,突然某天Mysql数据库告警提示出现了死锁问题,锁记锁和锁为了解决死锁问题,间隙我们就需要掌握一些关于Mysql的理清录锁临键锁的知识。
在InnoDB存储引擎中行级锁每次操作锁住对应的锁记锁和锁行数据,锁定粒度最小,间隙发生锁冲突的理清录锁临键概率最低,并发度最高。行锁InnoDB的锁记锁和锁数据是基于索引组织的,行锁是间隙通过对索引上的索引项加锁来实现的,而不是理清录锁临键对记录加的锁。在InnoDB存储引擎下实现了共享锁和排他锁这两种行锁,行锁以下是锁记锁和锁两种锁的介绍:
(1)共享锁(简称:S)允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。(加了共享锁之后可以读取,源码库但是不可以写) ,典型是在查询后面添加for share。在Mysql的performance_schema下的data_locks表中记录关于锁的相关信息,记录锁信息的表位置所示的:
图片
执行如下的sql语句:
复制BEGIN; #共享锁 SELECT * from stock where id = 8 FOR SHARE;1.2.3.4.5.查询data_locks表的锁信息:
图片
S,REC_NOT_GAP:表示对id=8的数据添加一把读锁(S),其中REC_NOT_GAP表示锁的一个范围(是指到底去锁哪些数据),这里表示只锁住id=8的数据。
(2)排他锁(简称:X)允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。(加了写锁之后其他的事务不可以添加任何的锁【读锁、写锁都不可以】)默认每次insert、update、delete的时候都是加排他锁,如下的更新sql:
复制BEGIN; #排他锁 update stock set num= 81 where id = 8;1.2.3.查询data_locks表的b2b供应网锁信息:
图片
X,REC_NOT_GAP:表示对id=8的数据添加一把排他锁(X),同样的REC_NOT_GAP表示锁的一个范围。
如果对select查询添加for update的时候,此时就是排他锁,如下的sql:
复制BEGIN; #排他锁 SELECT * from stock where id = 8 FOR UPDATE;1.2.3.查询data_locks表的锁信息:
图片
排他锁和共享锁的兼容性如下锁整理:
图片
在案例中我们使用的是主键id做为where的查询条件,假设我们现在不使用id而是使用一个非索引字段作作为查询的条件,sql如下所示:
复制BEGIN; #共享锁 SELECT * from stock where name = A FOR SHARE;1.2.3.数据表中的现存的记录如下所示:
图片
执行sql后查询data_locks表的锁信息:
图片
我们可以发现目前锁类型就是表锁了。
锁一条真实存在的记录(数据库中真实存在的数据),如下图是数据表中的数据记录:
图片
通过sql查询id=8的记录,sql如下所示:
复制BEGIN; #共享锁 SELECT * from stock where id = 8 FOR SHARE;1.2.3.锁的b2b信息网结果:
图片
间隙是指索引跟索引之间的间隙,假设现在查询id=5的数据(数据库中id为5的数据不存在),如下的数据表数据:
图片
执行如下的sql:
复制BEGIN; #共享锁 SELECT * from stock where id = 5 FOR SHARE;1.2.3.查询data_locks表的锁信息:
图片
S表示的读锁,GAP表示的间隙的意思,8代表的是一个节点(真实的记录),这里的含义是1-8之间的间隙是锁住的,这个间隙之内不可以添加数据,但是可以修改数据。
临键锁是记录锁+间隙锁,因为在去加锁来锁数据的时候,那么可能既包含了区间也包含了一条真实的数据,假设数据表中的数据如下所示:
图片
现在执行sql:
复制BEGIN; #共享锁 SELECT * from stock where id > 5 and id < 14 FOR SHARE;1.2.3.查询data_locks表的锁信息:
图片
id=8这条数据的LOCK_MODE=S,它没有任何的标记,那么id=8这条数据就是临键锁(临键锁只标记了是X还是S);它表示既锁死了id=8这条数据,也锁死了id在1-8这个区间。
id=14这条数据中,它没有锁死id=14这个数据,只锁死了一个gap的区间。
意向锁是为了提高粗粒度锁的性能而设置的一种预判机制(意向锁是为了协调行锁和表锁的关系,用于优化InnoDB加锁的策略),意向锁的主要作用是避免为了判断表是否存在行锁而去全表扫描(即在一个操作发起实际资源的锁申请行为之前,先对更粗力度的资源发起一个加锁意向声明),意向锁是由InnoDB在操作数据之前自动加的,不需要用户干预。如下所示的意向锁:
图片
意向锁分为意向共享锁(IS锁)【事务在请求S锁前,要先获得IS锁】;意向排他锁(IX锁)【事务在请求X锁前,要先获得IX锁】
意向锁(IS/IX)和X锁是冲突的,如下所示事务A执行语句:
复制BEGIN; #共享锁 SELECT * from stock where id = 8 FOR SHARE;1.2.3.事务B的执行语句:
复制BEGIN; #排他锁 update stock set num= 140 where id = 14;1.2.3.执行的效果图如下所示:
图片
①事务A首先申请整个表的IS锁(成功)。
图片
②事务A申请id=8这一行的S锁(成功)。
图片
③事务B申请整个表的IX锁(成功);因为IS和IX锁是兼容的,并且IX锁和行级别的S锁也是兼容的。
图片
④事务B申请整个表的X锁(成功);
图片
所以整个过程的数据库锁的信息:
图片
如果现在事务A给行记录id=8加共享锁成功后,事务B给id=8的行记录加排他锁,此时事务B就需要等待事务A释放锁才能加锁成功,如下图所示:
图片
数据库的锁信息如下所示:
图片
可以发现事务B此时在等待锁。
意向锁与其他锁的兼容性如下表整理:
图片
意向锁是一种高效的锁机制,特别适用于支持行级锁的数据库系统,能够在多事务并发访问的环境下有效地管理锁,提高系统的并发性和数据一致性。
教你如何设置戴尔电脑的启动项(详解戴尔电脑启动设置及常见问题解答)2025-11-04 08:05
Vsftpd实现虚拟账号2025-11-04 07:52
腾讯云发布全新非关系型数据库KeeWiDB 创新性实现三级存储架构2025-11-04 07:45
ProFTPD中权限的设置2025-11-04 07:31
解决电脑错误oxc000007b的方法与技巧(探索常见电脑错误oxc000007b的原因及解决方案)2025-11-04 07:04
几种FTP的访问方法2025-11-04 06:45
Redis6通信协议升级至RESP3,一口气看完13种新数据类型2025-11-04 06:44
Java内存马连续剧——Filter内存马2025-11-04 06:26
新电脑到手硬盘检测错误的全面解决方案(确保您的新电脑硬盘正常运行,避免数据丢失和系统崩溃)2025-11-04 05:36
聊聊数据匿名化技术2025-11-04 05:28
如何更换声卡驱动?(详细教程和注意事项)2025-11-04 08:05
源码安装Proftpd与配置虚拟用户2025-11-04 07:57
Vsftpd下的文件操作控制2025-11-04 07:53
REST API设计原则:构建可扩展、易维护的 API2025-11-04 06:48
安卓手机U盘教程(一键实现数据传输,轻松管理手机存储)2025-11-04 06:47
NoSQL架构实践(一)以NoSQL为辅2025-11-04 06:44
Docker容器挖矿应急实例2025-11-04 06:24
调查称全球多所顶尖高校网站存在网络攻击风险2025-11-04 05:48
VivoX5Pro散热能力的评估(探索VivoX5Pro的散热效果及关键因素)2025-11-04 05:48
Check Point 王跃霖:电信网络诈骗的防护与应对策略2025-11-04 05:28