MYSQL中的锁

news2025/7/14 3:21:18

全局锁

就是对整个数据库进行加锁,加锁之后整个数据库就处于只读状态,后续的DML写语句,DDL语句,以及对更新事务的提交操作都会被阻塞,典型地使用场景就是做整个数据库的逻辑备份,对所有的表进行锁定,从而获取到一致性视图,保证数据的完整性,是锁粒度最大的锁,只能进行查询操作

就是将我们数据库中的数据,放到一个文件里面做数据备份

加全局锁:flush tables with read lock;

进行数据备份:mysqldump -uroot -p12503487 数据库名> D:/mysql.sql

释放锁:unlock tables;

表级锁:每一次操作直接进行锁住整张表,锁的粒度大,锁冲突的概率比较高,并发性是最低的,应用在MYISM,INNDB引擎当中,对于表级锁,主要分成三类:

一.表锁:对于表锁,主要分为两类:

加锁操作:

lock tables 表名+read;表示加读锁

lock tables 表名+write;表示加写锁

解锁操作:

unlock tables;

1)表共享读锁:

所有操作只能读,不能写,所有客户端都可以读,都不可以写

1.1)首先客户端1对这张表加了一个读锁,就会把这张表锁住了,那么客户端1肯定是可以读取这张表的数据的,那么客户端1只能读取这张表里面的数据,是不能够写数据和操作事务

1.2)此时假设有一个客户端2想读取这张表的数据是可以的,但是想写数据和操作事务是不可以的

对于当前加读锁的客户端,进行更新操作直接会出现报错信息,对于其他客户端,想要操作这张表,即使输入SQL语句,也会阻塞等待,只有等到对应的加锁的客户端把所释放之后,之前阻塞的SQL语句才可以执行成功

2)表共享写锁:metadata

当前加写锁的客户端既能进行读,也可以进行写操作,但是别的客户端既不可以读,也是不可以写的,就会阻塞等待,一直阻塞到表锁释放为止

二:元数据锁:元数据锁,无需进行显式使用,在我们访问一张表的时候会自动加上,也就是说某一张表存在未提交的事务,我们是不能修改这张表的表结构,如果输入了对应的SQL语句,就会出现阻塞状态,为了防止DDL和DML语句冲突,保证数据读写的正确性

当我们对一张表进行增删改查的时候,加上MDL读锁(共享锁)-----兼容

当我们对表结构进行变更的时候,会加上MDL写锁(排它锁)

1)比如说咱们的客户端1开启了一个事务,现在进行查询select * from student,咱们的客户端2想要进行修改这个表结构:alert table add column Java int,这个客户端就会出现阻塞状态

2)一直阻塞到事务提交

元数据锁可以认为就是认为是一张表的结构;

三:意向锁:是给表中的行加锁的时候(顺便加上的)

1)假设我们没有意向锁,那么客户端1对表加上了行锁之后,客户端二如何给表进行加锁呢?

2)我们对于一个客户端1,开启一个事务,进行数据的更新操作DML语句,在进行更新的时候,会给涉及到的行进行加锁,客户端2想要对这张表进行加锁的时候,会检查当前表中是否有对应的行锁,如果说没有,就进行添加表锁,

3)此时就会从第一行数据,检查到最后一行数据,效率很低

意向共享锁(IS):由select ......lock in share mode 添加,和表级共享锁(read)兼容,和表级排它锁互斥(write);

1)select * from score where id=1 lock in share mode;
表示给这一行数据加上一个行锁的共享锁,还会给这一张score表加上一个意向共享锁,咱们现在的侧重点是给这张表加上意向共享锁
2)其他会话进行给整张表进行加锁的时候:lock table score read;//表示给表加锁成功,因为意向共享锁和(给表加读锁)是兼容的
3)如果说其他会话加上了lock table score write;//表示加锁失败,因为意向共享锁是(和给表加写锁)是互斥的,一直处于阻塞状态

意向排它锁:由insert update delete,select.....for update进行添加,和表级共享锁(read)和表级排它锁互斥(write),但是意向锁之间不会互斥;

当我们顺便给一行进行加锁的时候:
update student set username="A";
1)此时就会给表锁自动加上一个意向排它锁,那么此时别的客户端
进行给整张表加读锁和写锁都会失败
2)因为此时InnoDB引擎会自动进行判断当前表是否有意向锁,有的话,是意向排它锁还是意向共享锁,再决定和当前给表加读锁和写锁是否互斥

1)客户端1在进行执行DML语句操作的时候,会对涉及到的行进行加锁,同时也会对该表进行加锁(意向锁)

2)而其他的客户端,在对这张表加上表锁的时候,会先根据给表曾经加上的意向锁来进行判定是否可以成功的加上表锁,而不用再判断行锁情况了

3)而意向锁的种类以及是否最终表锁最终是否会添加成功,完全取决于加行锁的时候的行为

一旦我们的事务提交了,那么最终我们的意向共享锁,意向排它锁都会进行释放

行级锁:

1)行级锁是每一次操作都会锁住对应的行数据,锁的粒度最小,发生锁冲突的概率最低并发最高,应用在InnoDB引擎当中

2)InnoDB引擎是基于索引来进行组织的,行锁是针对索引上面的索引项来进行加锁实现的,而不是针对记录进行加锁

一:行锁:

锁住单个行记录的锁,防止其他事务进行update和delete,在read commited 和reapitable read都支持:

 在InnoDB引擎里面我们进行提供了两种类型的行锁:

1)共享锁:S共享锁和共享锁之间是兼容的,共享锁和排它锁之间是互斥的,事务A可以获取到这一行数据的共享锁,事务B可以获取到这个数据行的共享锁

2)排它锁S:某一个事务获取到了某一行数据的排它锁,就不能在获取到这一行数据的共享锁和排它锁了,排它锁和排它锁都是互斥的

常用的对数据进行增删改查的加行锁操作:

1)insert update delete 会自动加上排它锁

2)select 不会加上任何锁

3)select+对应的SQL语句+lock+in+share++mode;----会自动加上共享锁

4)select+for+update会自动加上排它锁

假设现在客户端1进行给行数据加上共享锁:
1)select * from stu where userID=1 lock in share model;
现在客户端2进行操作:
1)update set username="Java" where userID=3;//这条语句将会被正常执行,因为之前共享锁所得是id=1的叶子节点的数据,但是id=3的叶子节点的数据并没有被锁住
2)update set username="C++" where userID=1;//这个就会失败,之前在第一个客户端已经给id=1的行数据加上了共享锁,而此时还想加排它锁,那么此时就会出现不兼容的情况,就会出现堵塞等待
此时我们在进行举一个例子:
1)客户端1进行修改操作:
update student set username="" where id=1;
2)当我们的第二个客户端也进行操作更新的时候,就会失败:
update userInfo set username="admin" where userID=6;此时执行着一条语句的时候就会尝试给这一行加上排它锁,但是之前已经加过排它锁了,排它锁和排它锁之间互斥,所以会一直进行阻塞等待
3)我们的第二个客户端再去执行:select * from userInfo;
4)select * from userInfo where userID=6 lock in share mode;此时我们想查询这一行数据,会自动加上共享锁,共享锁和排它锁之间会互斥

注意:

1)当我们对唯一索引进行检索的时候,对已经存在的记录进行等值匹配的时候,会被自动优化成行锁

2)InnoDB的行锁是针对索引来进行加的锁,不通过索引来进行检索数据,那么InnoDB引擎会对表中所有的记录进行加锁,此时就会升级成表锁,当我们针对索引字段进行更新操作,就可以避免行锁升级成表锁的情况

3)此时我们开启一个事务update student set username="Java" where username="Java",此时我们并没有针对name字段进行建立索引,此时我们但是根据name字段来进行查询,就会出现直接给整张表加锁

4)此时我们进行对整张表的任意一个字段,都会失败

二:间隙锁(Gap)

间隙锁是直接锁住索引间隙记录(不会包含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行插入操作,产生幻读,在可重复读的事务隔离级别下支持

 

间隙锁Gap,左右都是开区间,间隙锁+行锁合称next-key lock,每个 next-key lock 是前开后闭区间。间隙锁和next-key lock的引入帮我们解决幻读问题。

三:临键锁:行锁和间隙锁进行组合,不仅锁住对应的行,还锁住了前面的间隙(RR下支持)

 

默认情况下:InnoDB使用repeatable read事务隔离级别来进行运行,InnoDb使用临建锁来进行搜索和索引扫描:

1)当我们进行索引上面的等值查询的时候,给不存在的记录进行加锁的时候,优化成间隙锁,会优化成两端区间的间隙加锁

1)select * from stu;
+----+------+----------+
| id | name | password |
+----+------+----------+
|  1 | A    | 1234     |
|  4 | B    | 8899     |
+----+------+----------+
2 rows in set (0.00 sec)
2)mysql> create index nameIndex on stu(name);//我们给他建立唯一索引
3)pdate stu set name="Java" where id=2;现在我们进行数据的更新操作
此时客户端2进行开启事务,进行尝试在1和4之间插入数据:
insert into stu values(3,"N","777888");
此时就会插入失败

2)当我们进行加锁的时候,我们是针对索引来进行加锁的,而索引是一个B+树,而B+树的叶子结点是一个有序的双向链表,

1)当前假设是唯一索引,那么我对18这个记录进行操作的时候,是不会插入一条记录是18的数据的 

2)但是此时是非唯一索引,有可能在18之后进行加锁,也有可能对18到29之间继续加锁,那么会向后遍历一个值不满足需求的时候,临建锁会退化成间隙锁,会对18-29和16-18这段空隙进行加锁

3)我们接下来进行演示一下:

客户端1:
//1.先创建一张表create table stu(id int,username varchar(50),password varchar(50),age varchar(40));
//2.进行插入语句:
 select * from stu;
+------+----------+----------+------+
| id   | username | password | age  |
+------+----------+----------+------+
|    1 | A        | 126      | 1    |
|    2 | B        | 89       | 3    |
|    3 | C        | 90       | 10   |
+------+----------+----------+------+
//3.进行查询:针对age字段创建普通索引:create index age on stu(age);
//4.开启事务:
 start transcation;
//5.进行更新操作: update stu set password="90" where age=3;
客户端2:
开启事务进行插入操作: insert into stu values(2,"D","ooo",2);失败
客户端3:
开启事务进行插入操作: insert into stu values(2,"D","ooo",8);失败
//因为此时年龄字段,已经对1-3和3-10这段区间进行加上了间隙锁

3)索引上面的范围查询,会进行访问到不满足条件的第一个值为止:

start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql>  select * from stu where age>4 lock in share mode;
+------+----------+----------+------+
| id   | username | password | age  |
+------+----------+----------+------+
|    3 | C        | 90       | 10   |
|    2 | D        | ooo      | 12   |
+------+----------+----------+------+
此时就在年龄4以后加了间隙锁,以后的其他客户端不允许在

覆盖索引定义:MySQL 执行计划 explain 结果里的 key 有使用索引,如果 select 后面查询的字段都可以从这个索引的树中获取,这种情况一般可以说是用到了覆盖索引,extra 里一般都有 using index;覆盖索引一般针对的是辅助索引,整个査询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值。

1.覆盖索引是一种数据查询方式,不是索引类型
2.在索引数据结构中,通过索引值可以直接找到要查询字段的值,而不需要通过主键值回表查询,那么就叫覆盖索引
3.查询的字段被使用到的索引树全部覆盖到

4)假设你定义一个联合索引

create index id_name_age on user(name,age);
5)查询名称为 liudehua 的年龄:

select name, age from user where name = "生命在于运动"
6)上述语句中,查找的字段 name 和 age 都包含在联合索引 id_name_age 的索引树中,这样的查询就是覆盖索引查询。

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

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

相关文章

非凡社群管理之如何高效的进行社群管理

一、初始成员的严格筛选 我们建立社群初期,就要严格筛选初始会员,争取让我们找到的第一批种子用户,就是有着共同的连接点。而不是找到一群人之后,再去培养大家的同好。这样不仅吃力不讨好,往往效果也不太高&#xf…

Kafka系列之:实现Kafka Connect集群访问认证

Kafka系列之:实现Kafka Connect集群访问认证 一、Kafka Connect访问控制二、Kafka Connect技术知识三、详细介绍Kafka connect访问认证实现过程四、启动Kafka Connect集群五、测试Kafka Connect集群访问认证一、Kafka Connect访问控制 实现的效果如下所示: 错误的用户名和密…

nginx降权及匹配php

1.nginx降权 1.1 capabilities的介绍与运用 1.2 用普通用户启动nginx 1.3 root用户权限赋予 1.4 查看普通用户的nginx权限 1.5 查看nginx的欢迎网页 2.nginx与php的相互匹配 2.1 安装php及php-fpm包 2.2 检查php-fpm服务运行状态 2.3 php-fpm上的配置 2.4 nginx上的配…

基于matlab的精馏塔作业模拟仿真

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 原料物性表如下: 表3-1原料物理性质表 组分 质量流率 质量分数 摩尔流率 摩尔分数 分子量 常压沸点 丙烷 472.938 7.567…

SpringBoot SpringBoot 原理篇 1 自动配置 1.9 bean 的加载方式【七】

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.9 bean 的加载方式【七】1.9.1 ImportBeanDefinitionRegistrar1 …

mysql 到底是 join性能好,还是in一下更快呢

先总结: 数据量小的时候,用join更划算数据量大的时候,join的成本更高,但相对来说join的速度会更快数据量过大的时候,in的数据量过多,会有无法执行SQL的问题,待解决 事情是这样的,去…

浅谈Spring Cloud Gateway源码

本文不谈Spring Cloud Gateway相关的使用,仅梳理在微服务项目中,在使用Spring Cloud Gateway做为服务网关后,接收到请求后的大体执行流程。 文章目录大致流程图具体流程一、DispatcherHandler二、getHandler1、getHandlerInternal2、lookupRo…

【GlobalMapper精品教程】027:路径剖面和和视线工具的使用

文章目录 一、路径剖面简介二、创建剖面图1. 加载DEM2. 创建剖面图3. 计算填挖方3. 保存剖面图一、路径剖面简介 路径剖面视线工具允许您使用加载的高程数据集沿用户指定的路径获取垂直剖面。 要定义生成3D路径剖面所遵循的路径,只需单击鼠标左键选择路径的点,然后石键单击…

[acwing周赛复盘] 第 60 场周赛20220716

[acwing周赛复盘] 第 60 场周赛20220716 一、本周周赛总结二、 4722. 数列元素1. 题目描述2. 思路分析3. 代码实现三、4723. 队列1. 题目描述2. 思路分析3. 代码实现四、4724. 靓号1. 题目描述2. 思路分析3. 代码实现六、参考链接一、本周周赛总结 第一次打acwing,…

POJ1007:DNA排序

一、Description One measure of unsortedness in a sequence is the number of pairs of entries that are out of order with respect to each other. For instance, in the letter sequence DAABEC’‘, this measure is 5, since D is greater than four letters to its ri…

傻白入门芯片设计,典型的2D/2D+/2.5D/3D封装技术(六)

集成电路终于成为了一级学科,对集成电路领域的投入也日益加大,集成电路属于电子集成技术的一种,那么,现在的电子集成技术发展到了什么程度呢? 先进的电子集成技术可以在不到芝麻粒大小的1平方毫米内集成1亿只以上的晶体…

Tableau 合集3:格式设置之可视化图显示百分比和提示工具对齐问题

一、前言 本文通过可视化图中显示不了百分比和提示工具无法对齐两个小问题出发,介绍了关于Tableau设置格式和工具提示的一些使用方法。 环境:Windows11 64位、Tableau desktop 2021.2 二、问题1:可视化图中显示不了百分比 问题描述&#…

springboot整合其它项目(连接池和监控)

目录 一、整合Druid 1. Druid是什么? 2.如何在Spring Boot中集成Druid连接池和监控? 二、整合Redis 1.集成redis之非注解式开发 2.集成redis之注解缓存开发 一、整合Druid 1. Druid是什么? Druid是Java语言中最好的数据库连接池。…

paddleocr识别模型训练记录

准备数据集 自己新建目录 下载识别预训练模型 下载之后是一个压缩包,解压后(注意:rec是自己新建的目录) 修改配置文件 修改内容: 1.训练后模型存储目录; 2.是否训练可视化; 3.训练数据集图…

tensorflow2 minist手写数字识别数据训练

✨ 博客主页:小小马车夫的主页 ✨ 所属专栏:Tensorflow 文章目录前言一、tenosrflow minist手写数字识别代码二、输出三、参考资料总结前言 刚开始学习tensorflow, 首先接触的是minist手写数字识别,用的梯度下降算法,…

linux下mysql的三种安装方法

目录1. 离线安装(.tar.gz安装包)2. 离线安装(rpm安装包)3. 在线安装(yum安装)前言安装环境 : Redhat Enterprise Linux 81. 离线安装(.tar.gz安装包) 参考这篇博客 2. 离线安装&am…

HTB-Toolbox

HTB-Toolbox信息收集提权信息收集 使用nmap简单扫描一下网站端口。 21 ftp22 ssh443 https? 去https看看。 网站基本是静态的。因为是https,所以有ssl协议,去看看吧。 more information里面能找到协议。 找到admin.megalogistic.com子域。…

Spring(完整版)

文章目录一、Spring(一)、Spring简介1、Spring概述2、Spring家族3、Spring Framework1、Spring Framework五大功能模块2、Spring Framework特性(二)、控制反转IOC1、IOC容器1、IOC思想2、IOC容器在Spring中的两种实现方式①BeanFactory②ApplicationContext③ApplicationContex…

配置elasticsearch用windows account(AD)登录

配置elasticsearch用windows account(AD)登录编辑es的配置文件创建role mapping文件添加windows account的密码给role mapping和cacert文件正确的权限重启kibana和elasticsearch在kibana页面登陆elasticsearch参考文章:• https://www.elasti…

vue中如何使用swiper以及解决swiper初始化过早的问题

后端的返回的数据用数组接收; 把swiper放到根组件里的mounted,也会出现swiper先初始化,dom再加载的问题: swiper初始化在mounted里执行;setTimeout定时器是从后端请求回来的数据; 代码执行顺序是:当组件创…