当前位置: 首页 > news >正文

超全MySQL锁机制介绍

图片

前言

MySQL作为关系型数据库管理系统中的佼佼者,为了保证数据的一致性和完整性,在并发控制方面采用了锁机制。锁机制是数据库管理系统用于控制对共享资源的访问,避免多个事务同时修改同一数据造成的数据不一致问题。了解MySQL的锁机制对于数据库管理员和开发人员来说都是至关重要的。本文将详细介绍MySQL的锁机制,包括其概念、分类、使用场景以及在实际编程中的应用。

一、MySQL锁机制概念

MySQL的锁机制是为了保证事务的隔离性,通过锁定数据库资源来防止多个事务并发执行时导致数据不一致。锁可以分为共享锁和排他锁两种类型,共享锁允许多个事务读取同一资源,而排他锁则阻止其他事务访问已锁定的资源。

二、MySQL锁的分类

1、从性能上分类:

  • 行锁:锁定表中的某一行或多行记录,其他事务不能修改被锁定的行,但可以同时读取或修改其他行。行锁粒度较小,并发度高,但加锁开销较大。

  • 表锁:锁定整张表,阻止其他事务对该表进行写操作(但可能允许读操作,具体取决于锁的类型)。表锁粒度大,开销小,但并发度低。

2、从对数据操作的粒度分类:

  • 全局锁:锁住整个Database,由MySQL的SQL layer层实现;

  • 表锁:锁住某个表,由MySQL的SQL layer层实现;

  • 页锁:在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中有多个行记录;

  • 间隙锁:锁的是两个值之间的空隙,间隙锁是在可重复读隔离级别下才会生效;

  • 行锁:锁某一数据Row的索引,也可锁定行索引之间的间隙(即间隙锁),由存储引擎实现;

3、从对数据库操作的类型分类:

  • 读锁:又叫共享锁,针对同一份数据,多个读操作可以同时进行而不会互相影响;

  • 写锁:当前写操作没有完成前,它会阻断其他写锁和读锁,数据修改操作都会加写锁,查询也可以通过for update加写锁;

  • 意向锁:又称I锁,针对表锁,主要是为了提高加表锁的效率,是MySQL数据库自己加的。当有事务给表的数据行加了共享锁或排他锁,同时会给表设置一个标识,代表已经有行锁了,其他事务要想对表加表锁时,就不必逐行判断有没有行锁可能跟表锁冲突了,直接读这个标识就可以确定自己该不该加表锁。

三、锁详解

1. 行锁

行锁是MySQL中最细粒度的锁,它仅对表中的某一行记录进行加锁。当事务需要对某行记录进行修改时,会先对该行记录加行锁,其他事务在行锁释放前无法修改该行记录,但可以同时读取或修改其他行记录。

使用场景:高并发、更新操作频繁的场景。

特点:行锁提高了并发性能,但可能增加锁的开销,因为需要更频繁地加锁和解锁。

实现原理:行锁通常基于索引实现。只有在使用索引条件检索数据时,MySQL才会使用行级锁。

SQL示例:


START TRANSACTION;  
SELECT * FROM table_name WHERE id = 1 FOR UPDATE;  -- 对id为1的行加行锁  
-- 进行修改操作  
COMMIT;  -- 提交事务,释放行锁

2. 表锁

表锁是对整个表加锁,阻止其他事务对该表进行写操作(可能允许读操作,取决于锁的类型)。表锁的开销较小,但并发度低,因为它会阻塞其他事务对整个表的访问。

使用场景:通常用于MyISAM存储引擎,或者在只需要读取整个表而不需要频繁更新的场景下使用。

特点:表锁的开销小、加锁快,但并发度最低,因为它锁定整个表,容易发生锁冲突。

LOCK TABLES table_name WRITE;  -- 对表加写锁  
-- 进行修改操作  
UNLOCK TABLES;  -- 释放锁

​​​​​​3. 全局锁

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

应用场景:做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。如果不加全局锁,先后执行数据备份和业务的数据更新操作,会导致数据不一致

使用全局锁进行数据库逻辑备份的过程:

  • 加全局锁

flush tables with read lock;

mysqldump是数据库用于数据备份的工具,执行数据备份。

注意:mysqldump是MySQL提供的一个工具,不是sql语句,需要在windows命令行中执行

mysqldump -uroot -p123456 user>user.sql

在加锁后,DML和DDL被阻塞,其他客户端不能写入数据,但是DQL可以执行,其他客户端可以查找数据

备份结束,得到备份后的文件,释放锁

unlock tables;

图片

4. 页锁

只有BDB存储引擎支持页锁,页锁就是在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行。页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。

5. 间隙锁

间隙锁是MySQL中用来保证事务的并发性和一致性的锁机制。它的作用是锁定记录间的间隙,防止其他事务在间隙中插入或删除记录,从而避免了脏读和不可重复读等问题的出现。间隙锁是在访问索引时产生的,它会锁住索引中的区间范围,而不是具体的记录。当一个事务在访问索引时,如果发现索引中的某个间隙没有被锁定,则会产生间隙锁,锁定该间隙。当其他事务尝试在同一个间隙中插入或删除记录时,会被阻塞,直到持有间隙锁的事务提交或回滚。间隙锁主要解决了幻读的问题,特别是在InnoDB存储引擎的可重复读事务隔离级别下。

6. 共享锁(S锁)

共享锁又称读锁,允许多个事务对同一资源加共享锁进行并发读操作,但加共享锁的事务不能修改数据。

使用场景:多个事务需要同时读取同一数据,而不需要修改的场景。

SQL示例:

SELECT * FROM table_name LOCK IN SHARE MODE; -- 对查询结果加共享锁

7. 排他锁(X锁)

排他锁又称写锁,它阻止其他事务对已锁定资源进行读写操作。当一个事务对某行记录加排他锁进行修改时,其他事务无法访问该行,直到排他锁释放。

使用场景:需要对数据进行修改,且要求修改期间数据不被其他事务访问的场景。

SQL示例:SELECT ... FOR UPDATE实际上就是对所选行加排他锁。

8. 意向锁

意向锁是InnoDB为了支持多粒度锁定而自动加的锁。当事务想要在行上加共享锁或排他锁时,它首先必须在表级别获得相应的意向锁。意向锁表明事务希望在行上加锁,但并不会阻止其他事务对表进行加锁操作。

意向锁是隐式的,不需要用户显式加锁,它分为意向共享锁(IS锁)和意向排他锁(IX锁)。

SQL示例:意向锁是InnoDB内部自动处理的,不需要用户通过SQL语句来显式请求。当执行如SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE等操作时,InnoDB会自动在相应的表上加意向锁。

四、锁的升级

锁的升级是指,在并发事务执行过程中,当某个事务无法满足当前所需的锁级别时,系统会自动将该事务的锁级别升级为更高级别的锁。这通常是为了保证数据的一致性和并发性能。

在MySQL中,锁升级主要发生在以下情况:

当某个事务需要获取的是行级锁,但由于并发冲突或其他原因无法满足事务的要求时,系统会将该事务的锁级别升级为表级锁。

当某个事务操作的对象不符合行锁加锁规则,比如没有走索引或非唯一索引记录数达到一定数量,系统也会将该事务的锁级别升级为表级锁。

合理的索引设计、适当的事务隔离级别设置可以帮助减少锁升级的发生,从而提高并发性能和系统吞吐量。

五、锁的重新请求

锁的重新请求通常发生在以下情况:当一个事务在持有锁的状态下,需要再次访问已经被其他事务锁定的资源时,该事务会重新请求锁。这种情况下,系统会根据当前的锁情况和策略来决定是否授予该事务新的锁。

在实际应用中,锁的重新请求可能会因为锁等待、锁冲突等原因而失败,导致事务被阻塞或回滚。因此,在编写数据库应用时,需要合理设计事务的逻辑,避免长时间持有锁,以减少锁冲突和提高系统的并发性能。

需要注意的是,无论是锁的升级还是锁的重新请求,都需要在数据库管理系统(DBMS)的控制下进行,以确保数据的一致性和完整性。同时,开发人员也需要了解并遵循DBMS的锁机制规则,以编写出高效、稳定的数据库应用。

六、可能出现的问题及解决方案

在实际应用中,可能会遇到死锁、锁等待超时等问题。死锁是指两个或多个事务相互等待对方释放资源,导致都无法继续执行。解决死锁的方法包括调整事务的执行顺序、使用超时设置等。锁等待超时通常发生在高并发场景下,当某个事务长时间持有锁不放时,其他事务会因为等待锁而超时。解决这类问题可以通过优化查询语句、减少锁的持有时间、增加锁等待超时时间等方式。

查看死锁

使用SHOW ENGINE INNODB STATUS命令:

这个命令提供了关于InnoDB存储引擎的详细状态信息,其中也包含了最近的死锁信息。你可以运行这个命令,然后查找LATEST DETECTED DEADLOCK部分来查看死锁的详细信息。

在输出中,查找LATEST DETECTED DEADLOCK部分,它会显示导致死锁的SQL语句以及事务的详细信息。

2. 查看information_schema数据库:

information_schema数据库中的INNODB_LOCKS和INNODB_LOCK_WAITS表也包含了关于InnoDB锁的信息。你可以查询这些表来获取当前锁的状态和等待情况。

SELECT * FROM information_schema.INNODB_LOCKS;  
SELECT * FROM information_schema.INNODB_LOCK_WAITS;

处理死锁

1. 超时设置:

你可以通过设置事务的超时时间来避免长时间等待。如果事务在指定的时间内无法获得所需的锁,它将自动回滚,从而避免死锁。

2. 优化查询和索引:

很多时候,死锁是由于不恰当的查询或缺少索引导致的。优化查询语句,确保它们能够高效地使用索引,可以减少锁的竞争和死锁的可能性。

3. 调整锁的顺序:

如果两个事务尝试以不同的顺序锁定资源,它们可能会发生死锁。尝试调整事务中锁定资源的顺序,使它们以相同的顺序进行,可以减少死锁的风险。

4. 使用低隔离级别:

在某些情况下,降低事务的隔离级别可以减少锁的需求,从而降低死锁的可能性。但请注意,这可能会增加其他并发问题(如脏读或不可重复读)的风险。

5. 避免大事务:

大事务通常持有锁的时间更长,增加了与其他事务发生死锁的机会。尽量将大事务拆分成多个小事务,以减少锁的持有时间。

6. 分析并重构代码:

在某些情况下,死锁可能是由于应用程序的逻辑错误导致的。仔细分析代码,确保事务的逻辑正确,并避免在事务中执行不必要的操作。

7. 使用第三方工具:

有些第三方工具可以帮助你监控和管理MySQL中的锁和死锁情况。这些工具可以提供更详细的信息和建议,帮助你更有效地处理死锁问题。

总之,处理MySQL中的死锁需要综合考虑多个方面,包括查询优化、索引设计、事务管理以及应用程序逻辑等。通过合理的配置和优化,你可以减少死锁的发生,提高数据库的性能和稳定性。

结语

了解MySQL中的锁机制对于数据库管理员和开发人员来说至关重要,它能帮助我们更好地控制并发访问,确保数据的一致性和完整性。通过合理使用不同的锁类型,我们可以提高系统的并发性能,减少锁冲突和死锁等问题。在实际应用中,需要根据具体的业务场景和需求选择合适的锁策略,并关注可能出现的问题,采取相应的优化措施。

相关文章:

超全MySQL锁机制介绍

前言 MySQL作为关系型数据库管理系统中的佼佼者,为了保证数据的一致性和完整性,在并发控制方面采用了锁机制。锁机制是数据库管理系统用于控制对共享资源的访问,避免多个事务同时修改同一数据造成的数据不一致问题。了解MySQL的锁机制对于数…...

【CV】计算机视觉中的特征追踪与背景处理

计算机视觉领域中的重要任务之一是视频特征追踪,它可以用于目标跟踪、运动分析、行为识别等应用。然而,在实际应用中,经常会遇到需要仅处理视频中特定特征物体而忽略背景的情况,这就需要进行背景处理。本文将介绍如何使用Python和…...

CAPL如何实现TLS握手认证

CAPL有专门的章节介绍如何实现TLS握手认证的函数: CAPL调用哪些函数实现TLS握手认证,需要了解TLS在整个通信过程的哪个阶段。 首先TCP需要建立连接,这是TLS握手的前提。当TLS握手认证完成后,可以传输数据。 所以TLS握手开始前需要确保TCP建立连接,TCP传输数据前需要确保…...

Linux -- 日志

一 日志的重要性 在之前的编程经历中,如果我们的程序运行出现了问题,都是通过 标准输出 或 标准错误 将 错误信息 直接输出到屏幕上,以此来排除程序中的错误。 这在我们以往所写的程序中使用没啥问题,但如果出错的是一个不断在运行…...

WebRtc 视频通话,语音通话实现方案

先了解一下流程 和 流程图(chatGpt的回答) 实现 (底层代码实现, 可作为demo熟悉) 小demo <template><div><video ref"localVideo" autoplay muted></video> <!-- 本地视频元素&#xff0c;用于显示本地视频 --><video ref"r…...

IndyTcpServer使用详解

1、IndyTCPserver的创建 IdTCPServer1.DefaultPort:= 8000; IdTCPServer1.ListenQueue:= 1024; //同时处理请求队列数限制 IdTCPServer1.MaxConnections:= 1024; //同时连接数量限制,为0不限制连接数 IdTCPServer1.ContextClass:= TNewIdServerContext; //设置为自定义TIdSe…...

pytest + yaml 框架 - 参数化读取文件路径优化

针对小伙伴提出参数化时读取外部文件&#xff0c;在项目根路径运行没问题&#xff0c;但是进入到项目下子文件夹运行用例&#xff0c;就会找不到文件问题做了优化。 关于参数化读取外部文件相关内容参考前面这篇pytest yaml 框架 -25.参数化数据支持读取外部文件txt/csv/json/…...

C++:多态-重写和重载

重写&#xff08;Override&#xff09;和重载&#xff08;Overload&#xff09;是面向对象编程中常用的两个概念&#xff0c;它们虽然都涉及到方法的定义&#xff0c;但是在实现和使用上有着不同的特点。 重写&#xff08;Override&#xff09;&#xff1a; 重写是指在子类中重…...

element ui的table多选

使用el-table的selection-change事件来获取选中的值&#xff1b; 例&#xff1a; html代码&#xff1a; <el-button type"primary" click"openTableSet">列表设置</el-button><!-- 列表设置弹框 --> <el-dialog :close-on-click-mo…...

python基础---基础运算

基础运算 可以使用type获取一个变量的类型 常见的数据类型 整形, 可以存储任意大小的整数, 支持二进制&#xff08;如0b100&#xff0c;换算成十进制是4&#xff09;、八进制&#xff08;如0o100&#xff0c;换算成十进制是64&#xff09;、十进制&#xff08;100&#xff09;…...

【数学】泰勒公式

目录 引言 一、泰勒公式 1.泰勒公式及推导 &#xff08;1&#xff09;推导 &#xff08;2&#xff09;公式 2.泰勒中值定理 &#xff08;1&#xff09;定理1&#xff08;佩亚诺余项&#xff09; &#xff08;2&#xff09;定理2&#xff08;拉格朗日余项&#xff09; …...

C++基础-编程练习题及答案

文章目录 前言一、查找“支撑数”二、数组元素的查找三、爬楼梯四、数字交换五、找高于平均分的人 前言 C基础-编程练习题和答案 一、查找“支撑数” 【试题描述】 在已知一组整数中&#xff0c; 有这样一种数非常怪&#xff0c; 它们不在第一个&#xff0c; 也不在最后一个&…...

eNSP-抓包解析HTTP、FTP、DNS协议

一、环境搭建 1.http服务器搭建 2.FTP服务器搭建 3.DNS服务器搭建 二、抓包 三、http协议 1.HTTP协议&#xff0c;建立在TCP协议之上 2.http请求 3.http响应 请求响应报文参考&#xff1a;https://it-chengzi.blog.csdn.net/article/details/113809803 4.浏览器开发者工具抓包…...

【栈】Leetcode 验证栈序列

题目讲解 946. 验证栈序列 算法讲解 在这里就只需要模拟一下这个栈的出栈顺序即可&#xff1a;使用一个stack&#xff0c;每次让pushed里面的元素入栈&#xff0c;如果当前栈顶的元素等于poped容器中的当前元素&#xff0c;因此就需要让栈顶元素出栈&#xff0c;poped的遍历…...

【数据库原理及应用】期末复习汇总高校期末真题试卷08

试卷 一、选择题(每题 2 分&#xff0c;共 30 分)    1. ___ ____是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 2. 数据库类型是按照 来划分…...

每天五分钟深度学习:数学中的极值

本文重点 在数学领域中,极值是一个极其重要的概念,它不仅在纯数学理论研究中占据核心地位,而且在工程、物理、经济等实际应用领域也发挥着不可替代的作用。极值问题涉及函数的最大值和最小值,是微积分学中的一个基本问题。本文旨在详细介绍数学中的极值概念、性质、求解方…...

【Linux】Linux——Centos7安装Tomcat

1.下载Tomcat 安装包 官网地址&#xff1a;Apache Tomcat - Apache Tomcat 9 Software Downloadshttps://tomcat.apache.org/download-90.cgi 2.将下载的安装包上传到 Xftp 上&#xff0c;我是直接放到 usr 下了 3.将安装包解压到 /usr/local/ tar -zxvf apache-tomcat-9.0.8…...

SpringBoot+vue实现右侧登录昵称展示

目录 1. 定义User数据 1.1.在created方法获取数据 1.2.头部导航栏绑定User数据 1.3.在data中定义User数据 2. 获取数据 2.1.接收父组件传递的值 2.2.展示数据 3. 页面效果 在SpringBoot和 Vue.js 结合的项目中实现右侧登录昵称展示&#xff0c;通常涉及到前端的用户界面…...

【网络原理】UDP协议 | UDP报文格式 | 校验和 | UDP的特点 | 应用层的自定义格式

文章目录 一、UDP协议1.UDP的传输流程发送方接收方 2.UDP协议报文格式&#xff1a;长度受限校验和如何校验&#xff1a;CRC算法&#xff1a;循环冗余算法md5算法&#xff1a; 2.UDP的特点 二、开发中常见的自定义格式1.xml&#xff08;古老&#xff09;2.json&#xff08;最流行…...

NodeJs入门知识

**************************************************************************************************************************************************************************** 1、配置Node.js与npm下载&#xff08;精力所致&#xff0c;必有精品&#xff09; …...

代码随想录学习Day 34

62.不同路径 题目链接 讲解链接 动归五部曲&#xff1a; 1.确定dp数组及其下标的含义&#xff1a;dp[i][j]的含义是从(0, 0)走到(i, j)所需的步数&#xff1b; 2.确定递推公式&#xff1a;因为只能往右或者往下&#xff0c;所以dp[i][j] dp[i - 1][j] dp[i][j - 1]。 3.…...

由于找不到MSVCP120D.dll,无法继续执行代码。重新安装程序可能会解决此问题

由于找不到MSVCP120D.dll,无法继续执行代码。重新安装程序可能会解决此问题 一、问题详细描述二、问题产生背景三、问题原因四、解决办法1、安装缺少的库2、直接更换更高版本的opencv 五、vs版本对应vc1、版本对应2、vs对应vc查看方法 一、问题详细描述 同样可能会报 &#xff…...

【前端】输入时字符跳动动画实现

输入时字符跳动动画实现 在前端开发中&#xff0c;为了提升用户体验&#xff0c;我们经常需要为用户的交互行为提供即时的反馈。这不仅让用户知道他们的操作有了响应&#xff0c;还可以让整个界面看起来更加生动、有趣。本文将通过一个简单的例子讲解如何实现在用户输入字符时…...

C语言面试重点问题

1. 冒泡排序法 2. strlen、strcpy、strcat、strcmp的用法和原理 3. 大小端的区分 3.1 主函数区分大小端 #include <stdio.h>int main(void) {int num 0x11223344;char *p (char *)&num;if (0x11 *p){printf("大端!\n");}else if (0x44 *p){printf(…...

antlr4略解

文章目录 1. antlr4是用来干什么的&#xff1f;2. 什么是lexer和parser&#xff1f;3. 使用antlr4生成某语言的lexer和parser的具体过程4. 其他 1. antlr4是用来干什么的&#xff1f; 是用来生成某语言lexer和parser的。 通俗点说&#xff0c;就是输入一个语言的规则描述文件&…...

超级好用的C++实用库之文件目录操作

&#x1f4a1; 需要该C实用库源码的大佬们&#xff0c;可扫码关注文章末尾的微信公众号二维码&#xff0c;或搜索微信公众号“希望睿智”。添加关注后&#xff0c;输入消息“超级好用的C实用库”&#xff0c;即可获得源码的下载链接。 概述 文件和目录操作是操作系统层面上的基…...

结合kimi chat的爬虫实战思路

背景 想钻研一下项目组件&#xff0c;找找之后的学习方向。不能自以为是&#xff0c;所以借着网开源项目网站上公布的项目内容看一下&#xff0c;那些是我可以努力去学习的&#xff08;入门的&#xff09;。首先需要获取相关内容&#xff0c;于是爬取整理。 任务1&#xff1a…...

UnsupportedClassVersionError异常如何解决?

下面是异常报错的详细描述 java -version java version "17.0.11" 2024-04-16 LTS Java(TM) SE Runtime Environment (build 17.0.117-LTS-207) Java HotSpot(TM) 64-Bit Server VM (build 17.0.117-LTS-207, mixed mode, sharing) 环境变量已经是jdk17&#xff0c;但…...

LeetCode热题100|动态规划Part.1|70.爬楼梯、118.杨辉三角、198.打家劫舍

70.爬楼梯 代码随想录原题&#xff0c;看这篇文章&#xff1a;C动态规划Part.1|动态规划理论基础、509.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯 118.杨辉三角 题目链接&#xff1a;118.杨辉三角 一刷代码 时间复杂度和空间复杂度都造到 O ( n u m R o w s 2 ) O(num…...

python 根据网址和关键词批量下载影像

最近用到了GLASS的LAI产品&#xff0c;但这个产品的文件夹分得很细&#xff0c;我需要的影像又有8个瓦片&#xff0c;一个一个点击很麻烦&#xff0c;于是探索了批量下载的方法 一、下载1幅 import requests import re import os import requests import re# 网页URLurl &…...