聊聊行锁、间隙锁、临键锁的区别

news2024/11/24 15:00:17

一、准备

创建 student
CREATE TABLE student (
id bigint NOT NULL,
age int DEFAULT NULL,
b int DEFAULT NULL,
a int DEFAULT NULL,
c int DEFAULT NULL,
PRIMARY KEY ( id ),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
插⼊数据
insert into student (id,age,a,b,c) values(1,1,1,1,1),(5,5,5,5,5),(9,9,9,9,9),(11,11,11,11,11);

二、锁区间

1.什么是锁区间?

区间从字⾯意思解释就是⼀个范围。

2.什么范围呢?怎么建⽴的呢?

mysql的锁区间是在当前会话创建后事物开始时当前数据库已存在数据相邻数据之间两两作为区间边界值。

3.相邻数据⼜以什么作为依据建⽴锁区间呢,有以下情况?

1.查询条件是主键索引

就以主键索引从⼩到达两两数据以主键列作为数据依据建⽴锁区间

2.查询条件时普通索引

和主键索引⼀致

3.组合索引

以组合索引第⼀个字段为依据

4.两个读索引

a字段建⽴索引,b字段建⽴索引

ab都作为查询条件,并且使⽤and作为条件,结果集求交集。

条件查询中涉及到的索引依照创建索引顺序排序,以排在第⼀个创建的索引作为锁区间依据字段。

5.组合索引

a字段建⽴索引,b字段建⽴索引

ab都作为查询条件,并且使⽤or作为条件,结果集求并集。

  • or ⾛索引,合并索引,两个字段都作为锁区间依据字段,其他操作满⾜任何⼀个字段的锁区间都将阻塞。
  • or不⾛索引,全表查询,两个字段都作为锁区间依据字段,其他操作满⾜任何⼀个字段的锁区间都将阻 塞。

三、从锁区间看临键锁和间隙锁的区别

从区间上看,临键锁和间隙锁的区别是锁区间不同,临键锁包含右边界数据,间隙锁不包含边界数据。

四、记录锁(Record Locks

select * from student where id=1 for update;
锁住 id=1 的记录。

当前查询的id不存在时,将升级为间隙锁

疑问1:升级为间隙锁,锁的是什么锁区间?

测试查询id = 3,此时数据库不存在id3的数据,

那么会以id字段作为依据找到id=3⼊的锁区间(1,5

疑问2:为什么是间隙锁锁区间不是临键锁锁区间有什么依据?

如果是临键锁我们更改边界值会阻塞
 
建⽴会话 1 ,执⾏选中 s q l
--insert into student (id,age,a,b,c) values(2,2,2,2,2);
insert into student (id,age,a,b,c) values(4,4,4,4,4);
update student set age = 9 where id = 5;
insert into student (id,age,a,b,c) values(6,6,6,6,6);

建⽴会话 2 ,执⾏ s q l

 

 
进⼊阻塞状态

 

执⾏会话 2 中的第⼆条 s q l
依然还是阻塞状态

 

执⾏会话 2 第三条 s q l ,修改边界值

 

并没有阻塞,执⾏成功

 

数据修改成功年龄成功修改为 9
我们可以测⼀下是否影响 id 在(5, 9 )区间的,执⾏选中 s q l

 

执⾏成功

 

因此当查询字段数值不存在时,只影响该数值落⼊的依据字段锁区间范围数据。
 

五、间隙锁(Gap Locks

间隙锁的触发⽅式:当我们进⾏范围查询的时候会触发间隙锁
 

1.主键作为查询条件

思考
Select * from student where id >5 for update 锁的是哪⾥?
预测:
1. 落⼊(1, 5 )锁区间
2. 落⼊(5, 9 )锁区间
3. 落⼊(1, 5 )锁区间和(5, 9 )锁区间
4. 两个都不落⼊
会话1 执⾏

会话 2

 

可得并没有落⼊(1, 5 )锁区间
 
会话 2 ,执⾏插⼊ id=6 ,阻塞了

落⼊了(5, 9)锁区间
那好,我们修改⼀下会话 1 id 条件值, id>5 改成 id>7

会话 2 执⾏,看右上⻆,仍然是阻塞状态

 

因为 7 仍然是落⼊(5, 9 )锁区间,进⽽导致该锁区间有效。 那好我们接着测试(9, 11 ),( 11 ,正⽆穷⼤)

 

 

依然是阻塞状态,因为查询的条件是 >5 ,(9, 11 ),( 11 ,正⽆穷⼤)也属于该范围内的锁区间,进⽽也会⽣效。
 

2.普通索引作为查询条件

和主键⼀致

3.组合索引作为查询条件

表数据以及字段顺序如下

测试⽤例:
1. 和数据库字段保持⼀致
2. 改变查询字段顺序
3. 改变表结构字段顺序
4. 改变组合索引字段顺序

3.1数据库字段顺序保持⼀致

创建组合索引 a,b
会话 1 执⾏选中 s q l

 

会话 2 执⾏选中 s q l

 

进⼊阻塞状态,因此 a >5 ⽣效,导致 a=6 时插⼊阻塞
 
我们将插⼊数据 a=6 改成 a=2 b=11 改为 2 ,只让插⼊数据 b=2 落⼊ b<9 中,

 

此时并没有阻塞因此,⽣效的是 a 字段, b 字段虽然也是组合索引字段,但是并没有满⾜范围的锁区间⽣效。
思考:
因为 a 字段在查询条件之前的原因导致 a>5 的锁区间⽣效了吗?好的,带着疑问来下⾯。
 

3.2改变查询字段顺序

where a>5 and b<9 for update;
改为 :
where b <9 and a>5 for update;
执⾏会话 1 选中 s q l

执⾏会话 2
a=2 改为 6,b=2 改为 11

 

a=6 时依然阻塞 ,a>5 仍然⽣效
执⾏会话 2
a=6 改为 2,b=11 改为 2
a=2,b=2 时并没有阻塞,因此查询条件顺序并不会影响⽣效字段。
思考:
不是条件查询顺序影响,会不会是表结构顺序影响?好的,带着疑问继续来下⾯。
 

3.3 改变表结构字段顺序

b 字段放在 a 字段之前
执⾏会话 1

执⾏会话 2
a=2 改为 6,b=2 改为 11

 

阻塞了。
执⾏会话 2
a=6 改为 2,b=11 改为 2

 

执⾏成功。
此处做个⼩总结:
使⽤组合索引作为条件查询,⽣效的锁区间与表结构字段顺序、查询条件字段顺序⽆关。

3.4改变组合索引字段顺序

表结构恢复

 

组合索引修改
会话 1 执⾏选中 s q l

 

会话 2 执⾏选中 s q l

 

插⼊ a=6 ,没有阻塞,此时 a 字段没有⽣效
删除插⼊数据,将 a=6 改为 a=4 ,将 b=11 改为 b=8, 执⾏会话 2

修改数据后重新插⼊,阻塞了
总结: 仅有组合索引⾸字段作为锁区间依据。
 

4 两个索引作为查询条件

测试⽤例:
1. 按照表结构顺序和查询条件顺序⼀致
2. 改变查询条件顺序
3. 改变表结构字段顺序
前提:
1. 删除组合索引( a,b
2. 建⽴普通索引 a,b
3. 删除表数据

4.1按照表结构顺序和查询条件顺序⼀致

会话 1 ,执⾏选中 s q l

 

会话 2 ,执⾏选中 s q l

 

a=6,b=11 时执⾏阻塞,因此 a>5 ⽣效。
会话 2 ,执⾏选中 s q l
a=6 改为 a=2,b=11 改为 b=8

 

并没有阻塞,

4.2改变查询条件顺序

会话 1 ,执⾏选中 s q l
会话 2 ,执⾏选中 s q l 

阻塞了, a>5 ⽣效
会话 2 ,执⾏选中 s q l

⽆阻塞, b<9 五⽣效
总结:两个索引的条件查询顺序不能影响使⽤哪个字段作为锁区间的依据

4.3改变表结构字段顺序

表结构

 

会话 1 ,执⾏选中 s q l

 

会话 2 ,执⾏选中 s q l
a=6 阻塞了,因此 a>5 ⽣效了
会话 2 ,执⾏选中 s q l

 

执⾏成功了

4.4修改索引创建顺序

将创建 b 字段索引提前到创建 a 字段索引之前

会话 1 ,执⾏选中 s q l

 

会话 2 ,执⾏选中 s q l

 

a=6 时为,⽆阻塞,因此 a>5 没有⽣效
会话 2 ,执⾏选中 s q l

 

b=8 时,阻塞了,因此 b<9 ⽣效
总结
表结构字段顺序和条件查询顺序不会影响锁区间依据字段,索引创建顺序影响锁区间依据字段。

5.合并索引和⾮合并索引

会话 1 ,执⾏选中 s q l
会话 2 ,执⾏选中 s q l
a=6 时,阻塞, a>5 ⽣效
会话 2 ,执⾏选中 s q l
b=2 时,阻塞, b<9 ⽣效
总结:
索引合并查询,条件字段中的索引都将作为锁区间依据字段。

6.普通字段

会话 1 ,执⾏选中 s q l

 

会话 2 ,执⾏选中 s q l

 

插⼊ c=6 时,阻塞,因为⾮索引字段查询时全表查询,锁的是全表,因此阻塞全表带有加锁操作。

7.组合索引和两个索引总结

表结构顺序和条件查询顺序不能影响组合索引和两个索引在条件查询时锁区间依据字段,组合索引锁区间依据字段
是创建组合索引时的⾸字段,两个索引锁区间依据字段是各个索引创建的顺序。
题外话:
插⼊数据的时候,先判断唯⼀ ID 是否已经存在,再去尝试加;
使⽤ o r 不⼀定⾛索引,即使⾛也是合并索引

六、临键锁

触发时机:当范围查询命中数据触发临键锁。
临键锁在 mysql8 进⾏了优化:
mysql5.7 版本
如: id>5 and id <10,Id=9 命中数据库数据, 9 左右锁区间为(5, 9],(9,11], 因此锁住的数据范围( 5,11]
Mysql8.0.28 版本
如: id>5 and id <10,Id=9 命中数据库数据, 9 左右锁区间为(5, 9),(9,11), ⼜因为命中 9 数据,因此锁住的数据范围 (5,11 )。

1.mysql5.7版本

会话 1 ,执⾏选中 s q l
会话 2 ,执⾏对 id=11 数据更新

 

发⽣了阻塞,符合我们前⾯介绍的。
 

2.Mysql8.0.28版本

会话 1 ,执⾏ s q l

 

会话 2 ,执⾏ s q l

 

会话 2 ,执⾏ s q l ,对 id=9 数据进⾏更新

 

会话 2 进⼊阻塞状态
会话 2 再次执⾏ s q l ,对 id=11 数据进⾏更新

 

本次会话 2 并没有阻塞,什么⻤?为什么不阻塞,猜测 mysql 开发者对临键锁进⾏了优化。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/861312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java【Spring】使用注解, 更简单的存储和获取 Bean

文章目录 前言一、存储 Bean1, 配置文件2, 五大类注解Bean 的命名规则 3, 方法注解Bean 的命名规则 二、获取 Bean1, 属性注入2, Setter 注入3, 构造方法注入4, Autowired 和 Resource 的区别5, 同一个类型的多个 Bean 注入问题 总结 前言 各位读者好, 我是小陈, 这是我的个人主…

机器学习、深度学习项目开发业务数据场景梳理汇总记录三

本文的主要作用是对历史项目开发过程中接触到的业务数据进行整体的汇总梳理&#xff0c;文章会随着项目的开发推进不断更新。 这里是续文&#xff0c;因为CSDN单篇文章内容太大的话就会崩溃的&#xff0c;别问我怎么知道的&#xff0c;问就是血泪教训&#xff0c;辛辛苦苦写了一…

C语言 指针与const

const 修饰变量&#xff0c;使得这个变量不能被修改。 const 对指针具有两种修饰的方式&#xff0c;且两种方式所限制的情况不同。 当const在 * 的左边 const int * p &n; 或者 int const * p &n; 当const在*的左边时&#xff0c;指针变量p所指向的空间内容无法被修…

C语言 指针与assert

assert 又称断言&#xff0c;需要包含头文件 assert.h 用于在运行时确保程序符合指定条件&#xff0c;如果不符合&#xff0c;就报错终止运行。 assert(p ! NULL); 上面代码在程序运行到这一行语句时&#xff0c;验证变量 p 是否等于 NULL。如果确实不等于 NULL &#xff0c;…

慎写指针类型的全局变量

简述: 在 关于range二三事[1] 第二个case中,介绍了对于指针类型的 切片/map变量A 的循环,要格外注意, 迭代出的value作用域是整个方法而非循环体内. 改进办法:在循环体中引入中间变量,"暂存"下每次迭代的value的值 但对于这个A,如果是全局变量,则又极有可能出现问题:…

Apache Maven简介安装及系统坏境配置eclipse配置Apache Maven---详细介绍

一&#xff0c;简介 Maven可以简化项目的构建和依赖管理&#xff0c;并提供了一种规范化和可复用的方式来管理Java项目。它广泛应用于Java开发领域&#xff0c;简单来说&#xff1a;它提供了一个简单而强大的方式来管理项目的构建、依赖关系和文档在企业级项目中被广泛采用。 1…

京东秋招攻略,备考在线测评和网申笔试

京东秋招简介 伴随着社会竞争越来越激烈&#xff0c;人们投递简历的岗位也变得越来越多元&#xff0c;而无论人们的选择面变成何样&#xff0c;那些知名度较高的企业&#xff0c;永远都备受关注&#xff0c;只要其一发布招聘公告&#xff0c;总有人第一时间踊跃报名。而作为这…

Java算法_ LRU 缓存(LeetCode_Hot100)

题目描述&#xff1a;请你设计并实现一个满足 LRU &#xff08;最近最少使用&#xff09; 缓存 约束的数据结构。 获得更多&#xff1f;算法思路:代码文档&#xff0c;算法解析的私得。 运行效果 完整代码 import java.util.HashMap; import java.util.Map;/*** 2 * Author: L…

winform中嵌入cefsharp, 并使用selenium控制

正常说&#xff0c; 需要安装的包 下面是所有的包 全部代码 using OpenQA.Selenium.Chrome; using OpenQA.Selenium; using System; using System.Windows.Forms; using CefSharp.WinForms; using CefSharp;namespace WindowsFormsApp2 {public partial class Form1 : Form{//…

(kubernetes)k8s常用资源管理

目录 k8s常用资源管理 1、创建一个pod 1&#xff09;创建yuml文件 2&#xff09;创建容器 3&#xff09;查看所有pod创建运行状态 4&#xff09;查看指定pod资源 5&#xff09;查看pod运行的详细信息 6&#xff09;验证运行的pod 2、pod管理 1&#xff09;删除pod 2…

搜索二叉树(二叉树进阶)

目录 1.二叉搜索树 1.1二叉搜索树概念 1.2二叉搜索树操作 2.3二叉搜索树的实现 2.4二叉搜索树的应用 2.5二叉搜索树的性能分析 1.二叉搜索树 1.1二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者是具有以下性质的二叉树&#xff…

mac安装nvm管理工具遇到的问题和解决方法

nvm 是一款可以管理多版本node的工具&#xff0c;因为是刚买没多久的电脑之前用的都是windows&#xff0c;昨天折腾了一下午终于倒腾好了 第一步&#xff1a; 卸载电脑已有的node&#xff1b;访问nvm脚本网址&#xff0c;另存为到电脑上任何目录&#xff0c;我是放在桌面上的…

OSPF技术入门(第三十四课)

1 OSPF的介绍 OSPF是一种链路状态路由协议,主要用于IP网络中的路由选择。它是一种开放协议,能够在不同的网络设备之间进行通信。OSPF利用链路状态数据库来描述网络拓扑结构,并通过Dijkstra算法计算出最短路径。它支持按照精确度划分的路由优先级,以及多个相等的路径,并能自…

微服务分布式搜索引擎 ElasticSearch 查询文档

文章目录 ⛄引言一、DSL查询文档⛅DSL 查询分类 二、DSL查询实例⛅全文检索查询⏰精确查询⚡地理坐标查询⌚复合查询 ⛵小结 ⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海…

服务器数据恢复-断电导致ext4文件系统文件丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器挂载一台存储设备&#xff0c;存储中划分一个Lun&#xff1b;服务器操作系统是Linux centos&#xff0c;EXT4文件系统。 服务器故障&分析&#xff1a; 意外断电导致服务器操作系统无法启动&#xff0c;系统在修复后可以正常启动&…

竞赛项目 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

在Ubuntu中使用Docker启动MySQL8的天坑

写在前面 简介&#xff1a; lower_case_table_names 是mysql设置大小写是否敏感的一个参数。 1.参数说明&#xff1a; lower_case_table_names0 表名存储为给定的大小和比较是区分大小写的 lower_case_table_names 1 表名存储在磁盘是小写的&#xff0c;但是比较的时候是不区…

CMAKE生成exe文件时运行时有cmd窗口

1、运行exe执行文件 会有cmd弹窗 2、解决方法 只需要在cmakelists.txt中添加set(CMAKE_CXX_FLAGS “-mwindows”) 或者在cmake时指定编译参数cmake -DCMAKE_CXX_FLAGS"-mwindows"即可 如果用的是c而不是c&#xff0c;就只需把CXX改为C 重新编译打包运行后没有cmd弹…

centos自动同步北京时间

1、安装ntpdate服务 yum -y install ntpdate 2、加入自动任务计划 查找ntpdate的路径&#xff1a; which ntpdate 复制这个路径。 编辑自动任务计划并加入ntpdate&#xff1a; crontab -e # 每小时第30分钟同步AD域控时间 30 * * * * /usr/sbin/ntpdate -u 192.168.2.8 > …

超低成本FPGA JTAG方案

今天给大家带来一款超低成本的FPGA JTAG方案&#xff0c;硬件核心是用树莓派Pico&#xff0c;使用相关芯片自己制作JTAG则非常便宜&#xff0c;RP2040某宝的报价只有4元&#xff0c;所以自己制作成本非常低廉&#xff0c;当然使用Pico成本也不是很高&#xff0c;所以今天就以Pi…