超全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> <!-- 本地视频元素,用于显示本地视频 --><video ref"r…...
IndyTcpServer使用详解
1、IndyTCPserver的创建 IdTCPServer1.DefaultPort:= 8000; IdTCPServer1.ListenQueue:= 1024; //同时处理请求队列数限制 IdTCPServer1.MaxConnections:= 1024; //同时连接数量限制,为0不限制连接数 IdTCPServer1.ContextClass:= TNewIdServerContext; //设置为自定义TIdSe…...

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

C++:多态-重写和重载
重写(Override)和重载(Overload)是面向对象编程中常用的两个概念,它们虽然都涉及到方法的定义,但是在实现和使用上有着不同的特点。 重写(Override): 重写是指在子类中重…...

element ui的table多选
使用el-table的selection-change事件来获取选中的值; 例: html代码: <el-button type"primary" click"openTableSet">列表设置</el-button><!-- 列表设置弹框 --> <el-dialog :close-on-click-mo…...
python基础---基础运算
基础运算 可以使用type获取一个变量的类型 常见的数据类型 整形, 可以存储任意大小的整数, 支持二进制(如0b100,换算成十进制是4)、八进制(如0o100,换算成十进制是64)、十进制(100)…...
【数学】泰勒公式
目录 引言 一、泰勒公式 1.泰勒公式及推导 (1)推导 (2)公式 2.泰勒中值定理 (1)定理1(佩亚诺余项) (2)定理2(拉格朗日余项) …...
C++基础-编程练习题及答案
文章目录 前言一、查找“支撑数”二、数组元素的查找三、爬楼梯四、数字交换五、找高于平均分的人 前言 C基础-编程练习题和答案 一、查找“支撑数” 【试题描述】 在已知一组整数中, 有这样一种数非常怪, 它们不在第一个, 也不在最后一个&…...

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

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

【数据库原理及应用】期末复习汇总高校期末真题试卷08
试卷 一、选择题(每题 2 分,共 30 分) 1. ___ ____是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 2. 数据库类型是按照 来划分…...

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

【Linux】Linux——Centos7安装Tomcat
1.下载Tomcat 安装包 官网地址:Apache Tomcat - Apache Tomcat 9 Software Downloadshttps://tomcat.apache.org/download-90.cgi 2.将下载的安装包上传到 Xftp 上,我是直接放到 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 结合的项目中实现右侧登录昵称展示,通常涉及到前端的用户界面…...

【网络原理】UDP协议 | UDP报文格式 | 校验和 | UDP的特点 | 应用层的自定义格式
文章目录 一、UDP协议1.UDP的传输流程发送方接收方 2.UDP协议报文格式:长度受限校验和如何校验:CRC算法:循环冗余算法md5算法: 2.UDP的特点 二、开发中常见的自定义格式1.xml(古老)2.json(最流行…...
NodeJs入门知识
**************************************************************************************************************************************************************************** 1、配置Node.js与npm下载(精力所致,必有精品) …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...

CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...

C++--string的模拟实现
一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量,…...