MySQL进阶:全局锁、表级锁、行级锁总结
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:MySQL进阶:MySQL事务、并发事务问题及隔离级别
📚订阅专栏:MySQL进阶
希望文章对你们有所帮助
全局锁、表级锁、行级锁总结
- 概述
- 全局锁
- 介绍
- 语法
- 特点
- 表级锁
- 介绍
- 表锁
- 表共享读锁(read lock)
- 表独占写锁(write lock)
- 元数据锁
- 意向锁
- 行级锁
- 介绍
- 行锁
- 间隙锁/临键锁
概述
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。
MySQL中的锁,按照锁的粒度分,分为以下三类:
- 全局锁:锁定数据库中的所有表
- 表级锁:每次操作锁住整张表
- 行级锁:每次操作锁住对应的行数据
全局锁
介绍
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,以及更新操作的事务提交语句都将被阻塞。
典型的使用场景是做全库的逻辑备份
,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
分析一下若不加全局锁,会发生的问题:
假设在数据库中存在这样三张表: tb_stock 库存表,tb_order 订单表,tb_orderlog 订单日志表。
若发生了上图所示的流程:
1、在进行数据备份时,先备份了tb_stock库存表(给tb_stock加锁,备份完解锁)
2、在业务系统中,执行了下单操作,扣减库存,生成订单(更新tb_stock表,插入tb_order表)
3、再备份tb_order表的逻辑(给tb_order加锁)
4、执行插入订单日志操作
5、最后再备份tb_orderlog表(给tb_orderlog加锁)
这时候会出现数据不一致的情况
,tb_stock被锁住了,执行下单业务后没办法修改tb_stock,但却修改了tb_order,同理,tb_order和tb_orderlog也会出现类似情况。
此时就需要借助MySQL的全局锁来解决:
对数据库进行进行逻辑备份之前,先对整个数据库加上全局锁,一旦加了全局锁之后,其他的DDL、DML全部都处于阻塞状态,但是可以执行DQL语句,也就是处于只读状态,而数据备份就是查询操作。
只要数据在进行逻辑备份的过程中,数据库中的数据就是不会发生变化的,这样就保证了数据的一致性和完整性。
语法
1、加全局锁
flush tables with read lock;
2、数据备份
-- mysqldump指令加的是全局锁,-u后指定用户名,-p后指定密码,wxj表示数据库名称,wxj.sql表示保存出来的文件名
mysqldump -uroot –p123456 wxj>/路径名.wxj.sql
需要注意mysqldump不是MySQL指令,需要在非MySQL命令行中执行
3、释放锁
unlock tables ;
特点
数据库中加全局锁,是一个比较重的操作,存在以下问题:
- 如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。
- 如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。
在InnoDB引擎中,我们可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致性数据备份:
mysqldump --single-transaction -uroot –p123456 itcast > itcast.sql
表级锁
介绍
表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。
主要分为以下三类:
- 表锁
- 元数据锁
- 意向锁
表锁
语法:
- 加锁:lock tables 表名… read/write。
- 释放锁:unlock tables / 客户端断开连接 。
表共享读锁(read lock)
当某一个客户端对指定表加了读锁,那么所有的客户端都无法再对表进行写操作(包括自己),但是所有的客户端都可以进行读操作(读共享)。
表独占写锁(write lock)
当某一客户端对指定表加了写锁,那么就会产生独占
的效果,即只有自己可以对该表进行读和写的操作,但不允许其他客户端对该表进行任何读或写的操作。
元数据锁
meta data lock , 元数据锁,简写MDL。
MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。
为了避免DML与DDL冲突,保证读写的正确性。
注意,这里的元数据可以直接理解成一个表的表结构,也就是说,某一张表涉及到未提交的事务时,不能修改这张表的表结构。
当对一张表进行增删改查(DML)时,加MDL读锁(共享);当对表结构进行变更(DDL),加MDL写锁(排他)。
常见的SQL操作,所添加的元数据锁:
SQL | 锁类型 | 说明 |
---|---|---|
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 | 与其他的MDL都互斥 |
总之,当某一客户端对表进行增删改查操作时,其他客户端也可以进行增删改查的操作,但是其他客户端无法对表结构进行修改,反过来亦是如此。
我们可以通过下面的SQL,来查看数据库中的元数据锁的情况:
意向锁
我们可以先分析没有意向锁的时候会发生的情况。
可以先看之前写过的文章,有关于SQL优化中的update优化,提到了优化策略是防止行锁升级成表锁,也就是通过主键索引来做update:
MySQL进阶:大厂高频面试——各类SQL语句性能调优经验
也就是说,当我们根据主键索引进行update时,会对这一条数据增加行锁。此时若有其他的客户端要对该表加表锁,它需要扫描整张表,查看这张表是否包含行锁,若包含,则无法加这个表锁,容易发现,这种全表扫描的效率过于低下了。
1、介绍
为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
假设加了意向锁,上面的加锁流程可以大大简化:
(1)客户端一,在执行DML操作时,会对涉及的行加行锁,同时也会对该表加上意向锁。
(2)其他客户端,在对这张表加表锁的时候,会根据该表上所加的意向锁来判定是否可以成功加表锁,而不用逐行判断行锁情况了。
2、分类
- 意向共享锁(IS):由select … lock in share mode添加,与表锁共享锁(read)兼容,与表锁排他锁(write)互斥
- 意向排他锁(IX):由insert、update、delete、select…for update添加,与表锁共享锁(read)和表锁排他锁(write)都互斥,但意向锁之间是不会互斥的。
总结:读读兼容,读写互斥,写写互斥
一旦事务提交,意向共享锁、意向排他锁都会自动释放。
行级锁
介绍
行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁,主要分为以下三类:
- 行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC、RR隔离级别下都支持。
- 间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事
务在这个间隙进行insert,产生幻读。在RR隔离级别下都支持。
- 临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
行锁
InnoDB实现了以下两种类型的行锁:
- 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
- 排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
两种行锁兼容情况:共享锁和共享锁之间兼容,其它情况都冲突。
常见的SQL语句在执行时所加的行锁:
SQL | 行锁类型 | 说明 |
---|---|---|
INSERT | 排他锁 | 自动加锁 |
UPDATE | 排他锁 | 自动加锁 |
DELETE | 排他锁 | 自动加锁 |
SELECT(正常) | 不加任何锁 | |
SELECT … LOCK IN SHARE MODE | 共享锁 | 需要手动在SELECT之后加LOCK IN SHARE MODE |
SELECT … FOR UPDATE | 排他锁 | 需要在SELECT之后加FOR UPDATE |
- 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
- InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。
可以通过下列SQL语句查看意向锁以及行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from
performance_schema.data_locks;
间隙锁/临键锁
默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读
(MySQL事务、并发事务问题及隔离级别)
有三种非常重要的情况:
- 索引上的等值查询(唯一索引),给不存在的记录加锁时, 优化为间隙锁
- 索引上的等值查询(非唯一普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁
- 索引上的范围查询(唯一索引)会访问到不满足条件的第一个值为止
解析:
1、索引上的等值查询(唯一索引),给不存在的记录加锁时, 优化为间隙锁
右边事务一定不可以insert,否则左边事务的update操作就能操作成功了,然而在这个间隙内的id根本都不存在,这就是幻读。
2、索引上的等值查询(非唯一普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
我们知道InnoDB的B+树索引,叶子节点是有序的双向链表。 假如,我们要根据这个二级索引查询值为18的数据,并加上共享锁,我们是只锁定18这一行就可以了吗? 并不是,因为这是非唯一索引,这个结构中可能有多个18的存在,所以,在加锁时会继续往后找,找到一个不满足条件的值(案例中为29)。此时会对18加临键锁,并对29之前的间隙加锁。
3、索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止
查询的条件为id>=19,并添加共享锁。 此时我们可以根据数据库表中现有的数据,将数据分为三个部分:[19]、(19,25]、(25,+∞]
所以数据库数据在加锁是,就是将19加了行锁,25的临键锁(包含25及25之前的间隙),正无穷的临键锁(正无穷及之前的间隙)。
相关文章:

MySQL进阶:全局锁、表级锁、行级锁总结
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:MySQL进阶:MySQL事务、并发事务问题及隔离级别 📚订阅专栏:MySQL进阶 希望文章对你们有所帮助…...

Python用函数实现代码复用
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言📝 生命对某些人来说是美丽的,…...

2024年腾讯云优惠代金券领取入口整理汇总,收藏级笔记
腾讯云优惠代金券领取入口共三个渠道,腾讯云新用户和老用户均可领取8888元代金券,可用于云服务器等产品购买、续费和升级使用,阿腾云atengyun.com整理腾讯云优惠券(代金券)领取入口、代金券查询、优惠券兑换码使用方法…...

nn.Linear() 使用提醒
原本以为它是和nn.Conv2d()一样,就看第二个维度的数值,今天才知道,它是只看最后一个维度的数值!!! 例子1 Descripttion: Result: Author: Philo Date: 2024-02-27 14:33:50 LastEditors: Philo LastEditT…...
python difflib --- 计算差异的辅助工具
此模块提供用于比较序列的类和函数。 例如,它可被用于比较文件,并可产生多种格式的不同文件差异信息,包括 HTML 和上下文以及统一的 diff 数据。 有关比较目录和文件,另请参阅 filecmp 模块。 class difflib.SequenceMatcher 这…...
HTML5浮动
1.标准文档流组成 块级元素(block) 内联元素(inline) 2.display属性 作用:指定HTML标签的显示方式 常用属性 值 说明 block 块级元素的默认值,元素会被显示为块级元素,该元素前后会带有换行…...

Unity 向量计算、欧拉角与四元数转换、输出文本、告警、错误、修改时间、定时器、路径、
using System.Collections; using System.Collections.Generic; using UnityEngine;public class c2 : MonoBehaviour {// 定时器float t1 0;void Start(){// 向量Vector3 v1 new Vector3(0, 0, 2);Vector3 v2 new Vector3(0, 0, 3);// 计算两个向量的夹角Debug.Log(Vector3…...
前端实现浏览器打印
浏览器的print方法直接调用会打印当前页面的所有元素,使用iframe可以实现局部打印所需要的模块。 组件printView,将传入的信息放入iframe中,调用浏览器的打印功能 <template><div class"print"><iframeid"if…...

iOS卡顿原因与优化
iOS卡顿原因与优化 1. 卡顿简介 卡顿: 指用户在使用过程中出现了一段时间的阻塞,使得用户在这一段时间内无法进行操作,屏幕上的内容也没有任何的变化。 卡顿作为App的重要性能指标,不仅影响着用户体验,更关系到用户留…...

关于synchronized介绍
synchronized的特性 1. 乐观锁/悲观锁自适应,开始时是乐观锁,如果锁冲突频繁,就转换为悲观锁 2.轻量级/重量级锁自适应 开始是轻量级锁实现,如果锁被持有的时间较长,就转换成重量级锁 3.自旋/挂起等待锁自适应 4.不是读写锁 5.非公平锁 6,可重入锁 synchronized的使用 1&#…...

NCDA设计大赛获奖作品剖析:UI设计如何脱颖而出?
第十二届大赛简介 - 未来设计师全国高校数字艺术设计大赛(NCDA)开始啦!视觉传达设计命题之一: ui 设计,你想知道的都在这里。为了让大家更好的参加这次比赛,本文特别为大家整理了以往NCDA大赛 UI 设计的优秀获奖作品&a…...

软考中级 软件设计师备考经验
考试介绍 软考中级的软件设计师需要考两个部分,选择题和大题,每科满分75,需要在同一次考试中两科同时大于等于45分才算通过。考试的内容包括计算机组成原理、数据结构、数据库、专业英语、信息安全、计算机网络等,范围比较广但考…...
Python猜数字小游戏
下面这段代码是一个简单的数字猜测游戏,其中计算机已经提前计算出了414 // 23的结果并存储在变量num中。然后,程序会提示用户来猜测这个结果。 以下是代码的主要步骤和功能: 初始化: num 414 // 23:计算414除以23的整…...

SQL面试题(2)
第一题 创建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…...
python常用pandas函数nlargest 和 nsmallest及其手动实现
pandas是Python数据分析的重要工具之一,提供了大量便捷的数据操作方法。nlargest和nsmallest是pandas中两个非常实用的函数,它们可以帮助我们快速找出Series或DataFrame中最大或最小的n个值。 ### pandas中的nlargest和nsmallest函数 - nlargest(n, colu…...

第六课:NIO简介
一、传统BIO的缺点 BIO属于同步阻塞行IO,在服务器的实现模型为,每一个连接都要对应一个线程。当客户端有连接请求的时候,服务器端需要启动一个新的线程与之对应处理,这个模型有很多缺陷。当客户端不做出进一步IO请求的时候,服务器…...

在vue2中使用饼状图
1.引入vue2和echarts <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> <script src"https://cdn.jsdelivr.net/npm/echarts5.4.0/dist/echarts.min.js"></script> 2.1 补充基本的body内容 <div id…...
面经(五)南京 软通动力 一面
注:已经有了接近一年的工作经验 总体评价 不完全是技术面,面试经过还行,但可能是期望岗位和对方需求不太一致,感觉不太好过 面试经过 HR找你,发简历入库,然后商量面试时间,发腾讯会议链接腾…...

线段树模型及例题整理
线段树的应用范围非常广,可以处理很多与区间有关的题目。 将区间抽象成一个节点,在这个节点中储存这个区间的一些值,那么如果看成节点的话,这就很像一棵满二叉树,所以我们可以用一维数组来储存节点。那么就要考虑父子节…...

揭秘Java性能调优的层次 | 综合多方向提升应用程序性能与系统高可用的关键(架构层次规划)
揭秘性能调优的层次 | 综合多方向提升应用程序性能与系统的高可用 前言介绍调优层次调优 — 设计案例说明 - 操作轮询控制事件驱动 调优 — 代码案例说明 - ArrayList和LinkedList性能对比案例说明 - 文件读写实现方式的性能对比 调优 — JVMJVM架构分布JVM调优方向**JVM垃圾回…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...