【示例】MySQL-MySQL中常见的锁

news2024/11/26 0:16:20

前言

本文主要讲述MySQL中常见的锁。

总结 | 各类别锁的名字

锁级别锁名字解释
全局锁read lock全局锁只有可读锁
表级锁 - 表锁read lock 表共享读锁
write lock 表独占写锁
表级锁 - 元数据锁(meta data lock,MDL)SHARED_READ_ONLY
SHARED_NO_READ_WRITE
SHARED_READ
SHARED_WRITE
EXCLUSIVE
表级锁 - 意向锁IS 意向共享锁
IX 意向排他锁
行级锁 - 行锁(Record Lock)S 共享锁
X 排他锁
行级锁 - 间隙锁(Gap Lock)Gap Lock
行级锁 - 临键锁(Next-Key Lock)Next-Key Lock

全局锁

概念 | 什么是全局锁?

什么是全局锁?

全局锁就是对整个数据库实例加锁,加锁后整个数据库实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。

全局锁应用场景?

全数据库的数据备份。在这个场景下,需要对数据库整体加锁,然后进行数据备份。

如果不加锁进行数据备份,会使数据一致性得不到保证。

应用 | 全局锁存在的问题及解决?

全局锁语法

# 加全局锁
flush tables with read lock;

# 进行相关操作

# 释放全局锁-1:SQL语句
unlock tables;

# 释放全局锁-2:关闭当前会话窗口

全局锁应用存在的问题

加了全局锁,整个数据库处于只读状态:业务正常的进展就会停滞。

如何解决该问题?

如果数据库的存储引擎支持可重复读的隔离级别,就能解决。原理是:

  • 在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。
  • 因为在可重复读的隔离级别下,即使其他事务更新了表的数据,也不会影响备份数据库时的 Read View,这就是事务四大特性中的隔离性,这样备份期间备份的数据一直是在开启事务时的数据。

mysqldump工具进行数据库备份

针对数据库全库备份这个情况,如果使用的备份数据库工具是 mysqldump,按如下用法即可:

mysqldump --single-transaction -uroot –p123456 itcast > itcast.sql

加上 –single-transaction 参数的时候,就会在备份数据库之前先开启事务。这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎。

InnoDB 存储引擎默认的事务隔离级别正是可重复读,因此可以采用这种方式来备份数据库。但是对于 MyISAM 这种不支持事务的引擎,在备份数据库时就要使用全局锁的方法。

表级锁

概念 | 什么是表级锁

表级锁就是每次操作锁住整张表。锁定粒度较大,容易发生锁冲突,并发性能较低。在MyISAM、InnoDB、BDB引擎中都有应用。

对于表级锁,主要有三类:表锁、元数据锁、意向锁

应用 | 表锁

表锁主要有两类:

  • 表共享读锁:read lock
  • 表独占写锁:write lock

应用语法:

# 加锁
lock tables 表名 read;	# 表共享读锁
lock tables 表名 write;	# 表独占写锁

# 释放锁-1:SQL语句
unlock tables;

# 释放锁-2:关闭当前会话窗口

表锁的特点:

特点
表共享读锁:read lock事务A上锁。不影响事务B的读操作,但影响B的写操作
表独占写锁:write lock事务A上锁。既影响事务B的读操作,也影响B的写操作

应用 | 元数据锁

元数据锁,meta data lock,简称:MDL。元数据锁是表级锁,是对一张表加的锁。元数据锁加锁的过程是系统自动控制,无需显示调用。


元数据锁的作用主要是维护一张表元数据的一致性,在表上有事务的时候,不能对元数据进行写入操作。

理解一下上面这段话涉及到的概念:

  • 元数据:指一张表的表结构
  • 不能对元数据进行写入操作:就是说不能更改表的表机构,即DDL操作失效。

在一些常见的SQL语句中,系统自动加入的是不同的元数据锁,主要有如下几类:

SQL元数据锁的类型说明
lock tables xxx read 加表锁-表共享读锁SHARED_READ_ONLY可以叫:MDL读锁(共享),特点可以参照表共享读锁
lock tables xxx write 加表锁-表独占写锁SHARED_NO_READ_WRITE可以叫:MDL写锁(排他),特点可以参照表独占写锁
SELECT ... 常规查询语句,不加锁
SELECT ... lock in share mode 加行锁-共享锁
SHARED_READ与这两个元数据锁兼容:SHARED_READ、SHARED_WRITE
与这一个元数据锁互斥:EXCLUSIVE
INSERT ... 常规插入语句,加行锁-排他锁
UPDATE ... 常规更新语句,加行锁-排他锁
DELETE ... 常规删除语句,加行锁-排他锁
SELECT ... FOR UPDATE 加行锁-排他锁
SHARED_WRITE与这两个元数据锁兼容:SHARED_READ、SHARED_WRITE
与这一个元数据锁互斥:EXCLUSIVE
ALTER TABLE ...EXCLUSIVE与其他任意的元数据锁都互斥
  • 兼容:即两个用户访问同一张表,一个是上锁A,一个是上锁B。锁A和锁B兼容,A、B两用户的请求就不会相互阻塞
  • 互斥:解释同上,但是A、B两用户的请求会相互阻塞

应用 | 意向锁

意向锁是作用是为了避免在进行SQL-DML操作的时候,加的行锁与表锁产生冲突。意向锁也是系统控制的

在InnoDB中加入意向锁,使得表锁在上锁的时候不用检查每行数据是否加行锁,从而减少了表锁的检查操作。

  • 若没有意向锁:A对某一行加了行锁,B需要对该表加表锁,就需要判断每一行数据是否有锁,效率较慢。

  • 若是有了意向锁:A对某一行加了行锁,同时对该表加上意向锁,B锁需要对该表加表锁,通过是否有意向锁,就可以知道能否成功加锁,而不用遍历每一行数据


意向锁主要有如下两类:

SQL意向锁的类型说明
SELECT ... lock in share mode 加行锁-共享锁意向共享锁(IS)兼容:表锁-表锁共享锁
互斥:表锁-表锁排他锁
INSERT ... 常规插入语句,加行锁-排他锁
UPDATE ... 常规更新语句,加行锁-排他锁
DELETE ... 常规删除语句,加行锁-排他锁
SELECT ... FOR UPDATE 加行锁-排他锁
意向排他锁(IX)互斥:表锁-表锁共享锁、表锁-表锁排他锁

意向锁的主要特点有:

  • 一旦事务完成提交:意向共享锁、意向排他锁,都会自动释放

  • 意向锁之间不会互斥:即该表可以同时存在:意向共享锁、意向排他锁,这个时候,两个表锁类型的任意一个都不能成功上锁

  • 意向锁同元数据锁一样,不是主动加的,而是SQL操作后,系统会对应加上相应的意向锁。

总结 | 表锁、元数据锁、意向锁

三种表级锁,关键的是表锁。另外两个表级锁:元数据锁、意向锁,都是随着SQL语句的执行,自动添加的对应锁。

行级锁

概念 | 什么行级锁?

行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

InnoDB引擎是基于索引组织的,行锁也是通过索引上锁的,而不是通过记录上锁,行级锁主要有如下三类:行锁、间隙锁、临键锁。


三种行级锁的图示:

  • 行锁(Record Lock):锁住单个行记录的数据,可防止其他事务对该数据进行:UPDATE、DELETE操作

image-20240328180623684

  • 间隙锁(Gap Lock):锁住索引记录间隙,不对行记录上锁,可防止其他事务对该数据进行:INSERT操作。用来防止幻读

image-20240328180847930

  • 临键锁(Next-Key Lock):行锁和间隙锁的组合,既锁住数据,又锁住间隙

image-20240328181441970


行锁的分类

行锁主要有两种类型:

  • 共享锁(S):允许其他事务对加了该锁的行记录进行读取,但不允许修改
  • 排他锁(X):不允许其他事务对加了该锁的行记录进行读取,也不允许修改
解释
共享锁兼容:共享锁
排斥:排他锁
排他锁排斥:共享锁、排他锁

三种行级锁的排斥、共享情况:

  • 行锁:有共享锁和排他锁之间的排斥、兼容规则

  • 间隙锁:不同间隙锁之间相互兼容。即使两个事务锁住同一个间隙,也是相互兼容的

  • 临键锁:组成是间隙锁 + 行锁,行锁之间是有排斥规则的。当获取到一个X型的临键锁,有范围重叠的临键锁是会互斥的

概念 | 行锁&间隙锁&临键锁的使用规则

相关应用示例,参考文章:小林Coding。文章里面关于加锁顺序的判断还是很直观明确的,赞!

下文为文章内容总结:

默认情况下,InnoDB引擎在RR事务隔离级别下运行,使用临键锁进行搜索和索引扫描,来防止幻读。而在某些情况下,临键锁会优化或者说退化为间隙锁/行锁。

在RR事务隔离级别下,相关加锁规则可以总结如下:

原则1:查找过程中访问到的对象才会加锁

原则2:加锁的基本单位是临键锁,其区间是前开后闭:(前开,后闭]


下面的优化原则,针对如下数据库记录进行验证:

image-20240413103330436

优化:在(唯一)索引上进行等值查询,如果这条记录存在,则将临键锁退化为行锁。

select * from user where id = 1 for update;

image-20240413103527397

优化:在(唯一)索引上进行等值查询,如果这条记录不存在,则将临键锁退化为间隙锁

select * from user where id = 2 for update;

image-20240413103820288

优化:在(唯一)索引上进行范围查询,加锁的范围视情况而定

  • 范围查询:>
select * from user where id > 15 for update;

image-20240413104124003

  • 范围查询:>=
select * from user where id >= 15 for update;

image-20240413104204725

  • 范围查询:< 并且条件值记录不存在
select * from user where id < 6 for update;

image-20240413104251830

  • 范围查询:<= 并且条件值记录存在
select * from user where id <= 5 for update;

image-20240413104706456

  • 范围查询:< 并且条件值的记录存在
select * from user where id < 5 for update;

image-20240413104822714

优化:在(非唯一)索引上进行等值查询,加锁的范围视情况而定

  • 等值查询,查询的值不存在
select * from user where age = 25 for update;

image-20240413105402360

  • 等值查询,查询的值存在
select * from user where age = 22 for update;

image-20240413105453164

优化:在(非唯一)索引上进行范围查询

select * from user where age >= 22  for update;

image-20240413105609858

概念 | 不同事务隔离级别下,行级锁的使用情况

不同事务隔离级别下,行级锁的使用情况:(总结不到位,边学边完善吧)

隔离级别是否会产生脏读是否会产生不可重复读是否会产生幻读行级锁支持
READ UNCOMMITTED,读未提交行锁
READ COMMITTED,读提交×行锁
REPEATABLE READ(MySQL默认隔离级别),可重复读××√(没有完全解决幻读)行锁、间隙锁、临键锁
SERIALIZABLE,串行化读×××行锁、临键锁

隔离级别从上到下,越来越高。隔离级别越高,数据越安全,性能越低。

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

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

相关文章

突破像素限制,尽显照片细腻之美——Topaz Gigapixel AI for Mac/Win

在这个数字化的时代&#xff0c;我们都热爱用照片记录生活中的美好瞬间。然而&#xff0c;有时候我们会发现&#xff0c;由于各种原因&#xff0c;照片的像素可能无法满足我们的需求。这时候&#xff0c;Topaz Gigapixel AI for Mac/Win 这款强大的照片放大工具应运而生。 Top…

09-ARM开发板的HelloWorld

在ARM开发板上运行x86_64平台程序 前面在Ubuntu系统编译生成了X86_64平台的HelloWorld程序&#xff0c;通过NFS服务器&#xff0c;尝试在开发板上直接运行。 如图所示&#xff0c;程序无法正常运行&#xff0c;终端提示ARM开发板在执行x86架构&#xff08;Intel或AMD&#xff…

童年女神大盘点:谁是第一个让你心动的动漫女神?

每当提起我们的童年记忆&#xff0c;总有一抹亮丽的色彩来自于那些国产动漫中的女性角色&#xff0c;她们以其独特的魅力、鲜明的性格和卓越的才智&#xff0c;深深地烙印在了我们的心底&#xff0c;成为了一代人的集体回忆。今天&#xff0c;让我们一同回首&#xff0c;盘点那…

centos 7 sshd服务无法自动随机启动

centos 7 sshd 服务无法伴随主机启动而启动&#xff0c;而使用systemctl start sshd可以启动&#xff0c;很奇怪。 后来使用Kimi查询&#xff0c;有提示“检查系统启动服务的顺序和状态” systemctl list-dependencies <service>确保所有依赖服务都已正常启动。 查看本…

Flutter第九弹 构建列表元素间距

目标&#xff1a; 1&#xff09;Flutter Widget组件之间间距怎么表示&#xff1f; 2&#xff09;列表怎么定义子项之间间距&#xff1f; 一、间距的表示组件 列表组件的间距一般采用固定间距&#xff0c;间距占据可见的空间。 已经使用的表示间距的组件 Spacer&#xff1a…

2024年妈妈杯数学建模C题思路分析-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成&#xff0c;图 ’ 是一个简化的物流 网络示意图。其中&#xff0c;分拣中心作为网络的中间环节&#xff0c;需要将包裹按照不同 流向进行分拣并发往下一个场地&#xff0c;最终使包裹…

vue,table页签里的一列,点击时,会弹出时间线提示,高度自适应

需求&#xff1a;点击商品来源这一列 弹出一个时间线&#xff0c;查看商品的来源记录 <el-popover></el-popover> 弹出框组件 <el-timeline-item></el-timeline-item>时间线组件slot-scopescope slot是插槽&#xff0c;slot-scope“scope“语义更加明…

数学建模-最优包衣厚度终点判别法-三(Bayes判别分析法和梯度下降算法)

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是viperrrrrrr~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff…

Python(10):常见的4种设计模式(单例/工厂/策略/观察者)

文章目录 一、单例模式二、工厂模式三、策略模式四、观察者模式 程序中设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案&#xff0c;这些解决方案是众多软件按开发人员经过相当长的一段时间的实验和错误总结出来的。使用设计模式是为了重用代码、让代码更容易…

对于所有对象都通用的方法⭐良好习惯总结

对于所有对象都通用的方法⭐良好习惯总结 Object是每个类的父类&#xff0c;它提供一些非final方法&#xff1a;equals、hashCode、clone、toString、finalize... 这些方法在设计上是可以被子类重写的&#xff0c;但是重写前需要遵守相关的规定&#xff0c;否则在使用时就可能…

MYBATIS获取参数值

MYBATIS最核心的莫过于动态的获取各种的参数值, 为了将来更好的使用MYBATIS进行开发, 我们必须先打好 "获取参数值" 这一基础 一. MYBATIS获取参数值的两种情况: 1.${} 实质:字符串的拼接 注解:${}使用的字符串拼接的方式拼接SQL语句, 所以, 如果其中出现了字符串…

23. 【Android教程】轮播滚动视图:ViewFlipper

轮播视图 ViewFlipper 是 Android 从第一个版本就开始提供的 UI 控件&#xff0c;它能够承载多个 View&#xff0c;但一个时机只会有一个 View 展示在屏幕上。通过 ViewFlipper 我们可以实现很多常见的带有展示类型的功能&#xff0c;类似 Gallery、轮播图、导航栏、广告banner…

基于Springboot+Vue的Java项目-旅游网站系统(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

C# WinForm —— 项目目录结构

1. WinForm 应用程序项目 Properties&#xff1a;属性文件夹存放了一个自动生成的类文件AssemblyInfo.cs&#xff0c;保存了一些应用程序集的一些信息引用存放了一些为应用程序提供所需的&#xff0c;某些功能的一些程序集&#xff08;dll文件&#xff09;等添加引用&#xff…

一些知识点小细节

当遇到的问题有关逆序输出&#xff0c;可以转换一下思想&#xff0c;就是使用for循环的时候&#xff0c;i的初始化是从数组或者是字符串的最后一个&#xff0c;然后注意设置循环结束的条件&#xff0c;最重要的是不要忘记i--;而不是I&#xff1b; 注意&#xff1a;当要逆序输出…

蚓链赋能企业拥有“数据能力”会带来哪些变革?

数字时代&#xff0c;对任何一家无论大小的企业&#xff0c;数据都是不可或缺的资源和工具。蚓链赋能企业拥有“数据能力”将会给企业带来哪些变革呢&#xff1f; 首先&#xff0c;将会提高企业的业务效率&#xff0c;通过数据分析和挖掘&#xff0c;企业可以更好地了解客户需…

Composer安装与配置

Composer&#xff0c;作为PHP的依赖管理工具&#xff0c;极大地简化了PHP项目中第三方库的安装、更新与管理过程。本文将详细介绍Composer的安装步骤、基本配置方法&#xff0c;以及一些实用的操作示例&#xff0c;帮助读者快速上手并熟练运用Composer。 一、Composer安装 环…

redis 数据迁移到rds2214(TongRDS-2.2.1.3.Load版 by lqw)

​ 文章目录 一.备份redis文件 vi redis.conf &#xff0c;看看有没有这两行设置&#xff0c;有的话改成跟下面的一致&#xff1a; appendonly yes appendfilename “appendonly.aof” 之后连接redis客户端&#xff0c;输入INFO persistence&#xff0c;如图所示即为开启成功…

中国历年GDP统计-探数API统计

数据介绍 时间维度&#xff1a;1978年-2021年 单位&#xff1a;亿元 该数据来源于国家统计局发布的中国统计年鉴2021&#xff0c;为按当年价格计算的中国历年GDP以及人均GDP。 数据说明&#xff1a; 数据来源于国家统计局。

SpringBoot-自定义Starter精华版

SpringBoot自定义Starter精华版 一、自定义 Starter 分析 项目首先加载 starter,starter加载自动配置类&#xff0c;然后再通过配置绑定对象读取配置属性&#xff0c;注册组件。 二、实现步骤 ​ 开发的自定义 Starter 需求是&#xff0c;项目依赖starterTest-spring-boot-s…