当前位置: 首页 > 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; …...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...