【MySQL数据库】锁机制
概述
锁:是计算机协调多个进程或者线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、IO)的争用以外。数据也是一种供多用户共享的资源。如何保证数据的并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。在MySQL中,事务的隔离级别可以由锁来模拟实现。根据锁的粒度来分,分为以下三类:
全局锁:锁定数据库中的所有表
表级锁:每次操作锁住整张表
行级锁:每次操作锁住对应的行数据
全局锁
何为全局锁?
锁的粒度最大。全局锁就是对整个数据库实例加锁,加锁后,整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞住。
我们呢,先说场景,你自己想一想是不是应该这样做,然后再去看解释:
典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
为什么要加全局锁?
分析:

假如我们不加全局锁,现在数据库中有三张表,我们想要去备份数据库的这三张表数据,但是在我们备份的过程中,我们的业务系统还在不断地向数据库中写入数据,那么此时可能会产生这样的一种情况:当我们备份表的时候,它是一个一个备份的,我们备份完库存表,然后业务系统修改了库存表的库存数据,形成了一个订单数据写入到订单表中,然后插入订单日志,此时我们备份出来的数据,将无法对应上,这就违背了数据的一致性。
如何加全局锁?

首先我们将整个数据库锁上,执行mysqldump进行数据备份,在此过程中,DML、DDL语句无法执行,但是我们可以进行查询(DQL),备份完成得到xxx.sql文件,备份完成,再进行解锁。
-- 加全局锁
flush tables with read lock;--备份过程mysqldump -uroot -p123456 mydb_name > mydb_name.sql;-- 解锁
unlock tables;
虽然全局锁能够保证数据一致性,但是也会带来一些弊端。加全局锁是一个粒度比较大的操作,存在的问题有:
1.如果在主库上备份,那么在备份期间,不能执行更新,业务基本上就得停摆
2.如果在从库上备份,那么在备份期间,从库不能执行主库同步过来的二进制文件(binlog),会导致主从延迟
在InnoDB引擎中,我们可以在备份时加上--single-transaction参数来完成不加锁的一致性数据备份
命令行语句:(是bash命令行的语句,不是在mysql命令行内执行)
mysqldump --single-transaction -uroot -p123456 mydb > mydb.sql;
表级锁
表级锁的介绍
表级锁:每次操作都会锁住数据所在的整张表。锁的粒度大,发生锁冲突的概率最高,并发度最低。在MyISAM、InnoDB、BDB等存储引擎中都支持。并发度比较低。
表级锁也有细化的分类:表锁、元数据锁(MDL - meta data lock)、意向锁。
TYPE1:表锁
表共享读锁(read lock):S-共享
表独占写锁(write lock):X-排他/独占
-- 加锁
lock tables 表名... read/write;-- 解锁
unlock tables; -- 客户端断开连接也会解锁
读锁的特点:

客户端A 将 表T 加了一个读锁,这张表就锁住了。
此时:
客户端A 可以对 表T 进行DQL读这张表的数据,但是不能进行DDL/DML等写入操作
客户端B 可以对 表T 进行DQL读这张表的数据,但是不能进行DDL/DML等写入操作
Tips:读锁共享,指的是多个客户端可以在加锁期间共享读的权力,但谁都没有写的权力

在左侧客户端进行加锁操作,然后我们在两个客户端分别执行select查询语句,我们发现都执行成功了。但是加锁客户端进行update操作时,被报错:“table was locked with a read lock and can't be updated”:表被读锁锁住了,不能被修改。而右侧客户端直接阻塞在了这里。
当左侧解锁之后,右侧被阻塞的语句才能继续执行。
写锁的特点:

客户端A 将 表T 加了一个写锁,这张表就被锁住了。
此时:
客户端A 可以对表T 进行DQL读、DML/DDL写。
客户端B 不能对表T 进行DQL读、DML/DDL写。
Tips:写锁独占,指的是加锁客户端独占表的使用权,其它客户端无法使用。

当我们加了写锁之后,加锁客户端可以执行任何操作,另外的客户端什么操作都不能执行,直接阻塞(使用ctrl+c强制结束阻塞直接退出执行)。
TYPE2:元数据锁
MDL加锁过程是系统自动控制的,无需显示的使用,在访问一张表的时候会自动加上,MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务时,不可以对元数据进行写入操作。
元数据:是指表的结构,也就是表的字段等内容。元数据锁无需我们手动操作,但是我们需要知道当我们有事务未提交时,事务DML操作的表,我们无法对其使用DDL(数据定义语言,如alter、drop、create等)。事务DDL操作的表,其它事务无法对其使用DDL、DML操作。总的来说就是避免的是DDL与DML(数据的增删改查)的冲突,保证读写的正确性。
meta data lock 在MySQL5.5中引入。当对一张表进行增删改查时,加MDL读锁(共享);当对表结构进行变更操作时,加MDL写锁(排他)。

表的第一行:我们手动加表锁时,会自动地加上 相应的 元数据锁(SHARED_READ_ONLY / SHARED_NO_READ_WRITE)
表的第二行:我们执行select、select ... lock in share mode时,会自动地加上 元数据读锁(SHARED_READ)
表的第三行:我们执行insert、update、delete、select .. for update,会自动地加上 元数据读锁(SHARED_WRITE)
表的第四行:该行对应的操作/锁,与上面三个都互斥(上面三个互相共享)。当我们执行alter table时,自动地加上了元数据写锁(EXCLUSIVE),不仅与其它共享锁互斥,排他锁之间也互相互斥。
查看元数据锁:
select object_type,object_schema,object_name,lock_type,lock_duration
from performance_schema.metadata_locks;
TYPE3:意向锁
在具体介绍意向锁之前,我们先来分析一个现象:

首先,线程A对表的一条记录上了写锁。然后,线程B想要对这个表上锁,那么能说上锁就上锁嘛,显然不可以,他会依次遍历每一个记录,看看是不是所有记录都没上锁。
嗯,乍一看,一想,确实没问题。但是当记录多的时候,再看一眼,不得了,线程B需要访问所有记录,这不合适啊,浪费时间。
为了解决这个问题,我们只需要指定一个共同的约定,谁有上锁的可能性的话,谁就创建一个意向锁,代表有锁这个表的意向,其它线程想要上锁的话,只需要检查这一个内容就可以了。这就是意向锁的设计起源。
定义:意向锁是为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
同样的,线程A操作表中某一条数据时,首先加上行锁,然后会给这个表加上一个意向锁。对于想要访问这个表的线程B,如果B想要加的锁与A的意向锁兼容,那么B就可以加上锁,否则会阻塞等到A将锁释放掉。
意向共享锁(IS):由语句select ... lock in share mode添加。
意向排他锁(IX):由insert、update、delete、select ... for update添加。
既然有分类,那么就会有兼容互斥情况。下面我们就来分析一下。
IS:与表锁共享锁(read)兼容,与表锁排他锁(write)互斥。
IX:与表锁互斥,意向锁之间兼容。
查看意向锁以及行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data
from performance_schema.data_locks;
行级锁
在上面的意向锁中,我们已经提到了行锁。行级锁,顾名思义,每次操作锁住对应的行数据。锁的粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。
MySQL的存储引擎中,MyISAM与InnoDB有三大区别:事务、外键、行级锁。
InnoDB能够确保事务完整,而前者不能
InnoDB具有外键,而前者没有
InnoDB支持行级锁,而前者不支持
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录家的锁。
对于“对索引上的索引项加锁”怎么理解呢?我们回想一下索引的基本结构,InnoDB的索引分为聚簇索引和二级索引,聚簇索引的叶子节点下面挂的是这一行的行数据,二级索引叶子节点下面挂的是对应的主键值。那么行数据是根据聚簇索引存储的,所以InnoDB的数据是基于索引组织的,并且在InnoDB中B+树的叶子结点是有序的。
对于行级锁,主要分为三类:
行锁(Record Lock):锁定单个行记录的锁,防止其它事务对此行进行update和delete。在RC,RR隔离级别下都支持。【RC-read_committed | RR-repeatable_read】

间隙锁(Gap Lock):锁定索引记录间隙(不含该条记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读,在RR隔离级别下都支持。

临键锁(Next-Key Lock):行锁和间隙锁的组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。

行锁
细分为两类:
共享锁:S-允许一个事务去读一行,阻止其它事务获得相同数据集的排他锁。
排他锁:X-允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

默认情况下,InnoDB在RR隔离级别下运行,InnoDB使用next-key锁进行搜索和索引扫描,防止幻读。
1.针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
2.InnoDB的行锁是针对索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,此时就会升级为表锁。
查看意向锁以及行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data
from performance_schema.data_locks;
间隙锁/临键锁
1.索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
2.索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
3.索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。
注意:间隙锁唯一目的就是防止其它事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一个间隙采用间隙锁。
感谢大家!
相关文章:
【MySQL数据库】锁机制
概述 锁:是计算机协调多个进程或者线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、IO)的争用以外。数据也是一种供多用户共享的资源。如何保证数据的并发访问的一致性、有效性是所有数据库必须解决的一个…...
ASP.NET Core Web API 中 HTTP状态码的分类及对应的返回方法
文章目录 前言一、HTTP状态码分类及常用方法二、具体返回方法示例1) 2xx 成功类2)4xx 客户端错误3)5xx 服务器错误4)其他特殊状态码 三、高级返回方式1)使用 IActionResult 与 ActionResult<T>2)统一…...
react redux的学习,单个reducer
redux系列文章目录 一 什么redux? redux是一个专门用于做状态管理的JS库(不是react插件库)。它可以用在react, angular, vue等项目中, 但基本与react配合使用。集中式管理react应用中多个组件共享的状 简单来说,就是存储页面的状态值的一个库…...
C++20新增内容
C20 是 C 语言的一次重大更新,它引入了许多新特性,使代码更现代化、简洁且高效。以下是 C20 的主要新增内容: 1. 概念(Concepts) 概念用于约束模板参数,使模板编程更加直观和安全。 #include <concept…...
分布式控制技术赋能智慧工厂精准控制研究
摘要:本文聚焦于分布式控制技术在智慧工厂精准控制中的应用。详细阐述了分布式控制系统(DCS)、边缘计算机、边边协同技术以及分布式计算等关键要素在实现精准控制中的作用机制。同时,分析了云边协同模式存在占用带宽、单点故障、数…...
清明节里清明菜:软萩(拟人版介绍)
好像人们无论过任何节,总是离不开吃 清明节里吃清明菜,你采摘了吗? 姓名 软萩,也叫鼠麴草、清明菜、软雀,学名鼠曲草。 一些地方性小名(防止大家找不到组织,已知的都附上)…...
JavaWeb学习--MyBatis-Plus整合SpringBoot的ServiceImpl方法(增加,修改与删除部分)
接下来是常用的增加,修改以及删除部分 首先是增加部分,增加一个新的数据 Testpublic void testInsert() {// 添加一个新用户记录Student s new Student();s.setName("NewStudent");s.setAge(25);boolean saved studentService.save(s);//可以…...
AiCube 试用 - 创建流水灯工程
AiCube 试用 - 创建流水灯工程 本文介绍了 Aiapp-ISP 仿真调试平台软件的 AiCube 工具,实现流水灯工程的快速创建的主要流程。 下载运行 下载 最新版 AIapp-ISP 软件; 解压并打开该软件,右侧操作界面选择并进入 Keil 仿真设置 标签项&…...
【Kafka基础】Kafka工作原理解析
Apache Kafka作为当今最流行的分布式消息系统,以其高吞吐、低延迟和高可靠性的特点,成为大数据领域不可或缺的基础设施。本文将深入剖析Kafka的核心架构和工作原理,帮助开发者全面理解这一强大的消息引擎。 1 Kafka架构解析 Kafka采用分布式、…...
GISBox:核心功能免费的一站式三维GIS处理平台
大家好,今天为大家介绍的软件是GISBox:一款核心功能免费的一站式三维GIS处理平台,主要是适用于数字孪生。下面,我们将从软件的主要功能、支持的系统、软件官网等方面对其进行简单的介绍。 软件官网:http://www.gisbox.…...
【论文笔记】DeepSeek-R1 技术报告
最强开源LLM,性能和效果都很棒;在数学、代码这种有标准正确答案的场景,表现尤为突出;一些其他场景的效果,可能不如DeepSeek-V3和Qwen。 Deepseek-R1没有使用传统的有监督微调sft方法来优化模型,而使用了大规…...
基于javaweb的SSM羽毛球会员俱乐部系统场馆课程运动设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
[dp4_路径问题] 下降路径最小和 | 最小路径和 | 地下城游戏
目录 1.下降路径最小和 题解 2.最小路径和 题解 3.地下城游戏 题解 做算法题的时候,谨记图画得越详细越好,思路想的越清晰越好,然后再用代码实现一下就好啦 1.下降路径最小和 链接:931. 下降路径最小和 给你一个 n x n 的…...
EasyExcel 数据字典转换器实战:注解驱动设计
一、场景痛点与解决方案 1. 问题背景 在 Excel 导入导出场景中,开发者常面临以下问题: 数据可读性差:数据库存储的字典值(如 1、true)直接导出时难以理解双向转换复杂:导入时需将用户输入的标签反向解析…...
【蓝桥杯】算法笔记2
这篇文章主要记录动态规划方面的学习。 动态规划的核心思想: 把大问题分解成小问题,记住小问题的解,避免重复计算。 动态规划(DP)的三大特点: ①最优子结构:大问题的最优解可以由小问题的最优解推导出来 ②重叠子问题:在求解过程中会反复遇到相同的小问题 ③无后效…...
解决STM32CubeMX中文注释乱码
本人采用【修改系统环境变量】的方法 1. 使用快捷键 win X,打开【系统R】,点击【高级系统设置】 2. 点击【环境变量】 3. 点击【新建】 4.按图中输入【JAVA_TOOL_OPTIONS】和【-Dfile.encodingUTF-8】,新建环境变量后重启CubeMX即可。 解释…...
AI产品的上层建筑:提示词工程、RAG与Agent
上节课我们拆解了 AI 产品的基础设施建设,这节课我们聊聊上层建筑。这部分是产品经理日常工作的重头戏,包含提示词、RAG 和 Agent 构建。 用 AI 客服产品举例,这三者的作用是这样的: 提示词能让客服很有礼貌。比如它会说&#x…...
基于自定义注解+反射+AOP+Redis的通用开关设计:在投行交易与风控系统的落地实践
一句话总结🤣 一个注解让业务逻辑自动切换,Redis当起了隐形操盘手 业务痛点和需求场景 交易系统需支持毫秒级动态切换报价策略,如切换到备用流动性通道风控模型需支持灰度发布(10%流量测试新权重算法)和紧急熔断&am…...
RK3588使用笔记:ubuntu/麒麟系统功能测试程序
一、前言 本编文章记录在使用嵌入式系统中的一些功能测试demo程序,大部分都是AI写的,哈哈哈,确实很有帮助,但是得根据自身设备实际情况和知道如何问AI,才能得出你想要的结果,本文就记录一些ubuntu/麒麟系统…...
Unity中优化绘制调用整理
DrawCall 指的是 CPU 向 GPU 发送渲染指令的过程,在 Unity 中,每次渲染一个网格时,CPU 都需要向 GPU 发送一系列的渲染指令,这个过程被称为一次绘制调用(Draw Call)。 1.GPU实例化 使用: 2.绘…...
ubuntu开启黑屏现象解决
文章目录 前言一、问题描述二、解决方案1. 检查显卡驱动解决步骤: 2. 修复 GRUB 配置解决步骤: 3. 使用恢复模式解决步骤: 三、验证与总结 前言 在使用 Ubuntu 操作系统时,一些用户可能会遇到开机后屏幕黑屏的现象。这种问题可能…...
深度学习deeplearn3
# Jupyter Notebook魔法命令,用于在Notebook中内联显示图表 %matplotlib inline# 导入NumPy库,用于高效的数值计算 import numpy as np# 从matplotlib_inline库导入backend_inline模块,用于设置图表显示格式 from matplotlib_inline import b…...
Mac强制解锁APP或文件夹
当Mac安装过火绒企业版、云安全访问服务之类的APP需要卸载的时候,会发现需要管理员密码,正常的卸载流程走不下去,直接删除APP,会提示“不能完成此操作,xxx已锁定”的信息,此处就记录一下如何关闭锁定状态&a…...
android开发:zxing-android-embedded竖屏扫描功能
Android 点击按钮调用竖屏二维码扫描 提示:zxing-android-embedded插件已过时,建议更换别的。 场景:Home页面上有个扫描按钮,点击后打开摄像头完成扫描功能,扫描时要求竖屏。 方案:使用zxing-android-embe…...
SQL语句(二)—— DML
目录 一、添加数据 1、给指定字段添加数据 2、给全部字段添加数据 3、批量添加数据 二、修改数据 1、修改数据的具体语法 2、案例分析 3、注意事项 三、删除数据 1、删除数据的具体语法 2、案例 3、注意事项 DML全称是Data Manipulation Language,即数据…...
2.2 路径问题专题:LeetCode 63. 不同路径 II
动态规划解决LeetCode 63题:不同路径 II(含障碍物) 1. 题目链接 LeetCode 63. 不同路径 II 2. 题目描述 一个机器人位于 m x n 网格的左上角,每次只能向右或向下移动一步。网格中可能存在障碍物(标记为 1ÿ…...
Linux系统程序设计:从入门到高级Day02
这一篇 我带大家复习一下,C语言中的文件 那一部分 大家注意 这里的图并非原创 是当时我老师的图片 本片作用主要是 后续会有文件相关操作,这篇帮大家复习C语言文件中的内容 有助于大家后面的理解。 文章中代码大多是图片格式,是因为这是我…...
2025高频面试设计模型总结篇
文章目录 设计模型概念单例模式工厂模式策略模式责任链模式 设计模型概念 设计模式是前人总结的软件设计经验和解决问题的最佳方案,它们为我们提供了一套可复用、易维护、可扩展的设计思路。 (1)定义: 设计模式是一套经过验证的…...
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
🚀 力扣热题 208:实现 Trie (前缀树)(详细解析) 📌 题目描述 力扣 208. 实现 Trie (前缀树) Trie(发音类似 “try”)是一种树形数据结构,用于高效地存储和检索字符串集合中的键。实…...
CSS 父类元素的伪类 选择器
父元素的 :hover 状态可以影响子元素的样式。当父元素处于 :hover 状态时,可以通过 CSS 的选择器为子元素设置样式。 .parent:hover .child 这种选择器叫做 后代选择器(Descendant Selector) ,结合了 :hover 伪类。它的作用是&…...
