MySQL 的意向锁(Intention Locks)原理详解
1. 背景:为什么需要意向锁?
MySQL 中意向锁的主要作用是用于支持行级锁与表级锁的并存,特别是在 InnoDB 存储引擎中。InnoDB 提供了行级锁,而在某些场景下,数据库系统仍需要对整张表加锁,例如 LOCK TABLES 或 ALTER TABLE 操作。在这些场景中,如果没有意向锁机制,系统需要扫描所有行级锁来判断是否可以安全地加表锁,这会严重影响性能。
为了解决这一问题,意向锁应运而生。意向锁是一种表级锁,用于指示事务将要或已经在某些行上加锁。它通过提供表级的锁定信息,避免了系统去逐行检查是否可以加表锁。
2. 意向锁的类型
InnoDB 支持两种类型的意向锁:
- 意向共享锁(IS, Intention Shared):事务想要在表中加共享锁之前,必须先获得意向共享锁。
- 意向独占锁(IX, Intention Exclusive):事务想要在表中加排他锁之前,必须先获得意向独占锁。
共享锁(S 锁):允许读取但不允许修改数据。
排他锁(X 锁):允许读取和修改数据,并阻止其他事务加任何锁。
3. 意向锁的工作机制
意向锁的工作机制体现在事务与行级锁以及表级锁的协作上:
- 当事务对表的某些行加行级锁时,它会先申请表级的意向锁(IS 或 IX),以告知其他事务该表上有行级锁存在。
- 如果一个事务想要加表级的锁,它首先需要确认没有其他事务持有相冲突的意向锁或行锁。
例如:
- 一个事务在表的某行上加了行级排他锁(X 锁),则必须先获得意向独占锁(IX)。如果另一个事务尝试给整张表加共享锁(S 锁),这个操作将会失败,因为 IX 锁与 S 锁冲突。
- 反之,如果某事务只想对表的某些行加共享锁(S 锁),则它会申请意向共享锁(IS)。如果没有其他事务持有排他锁(如 X 锁),操作即可执行。
通过意向锁,MySQL 在表级别快速判断是否可以加锁,而无需遍历行锁,极大提高了加表锁的效率。
4. 意向锁与其他锁的兼容矩阵
InnoDB 中各种锁之间的兼容性决定了锁冲突的可能性。下表展示了意向锁与其他锁之间的兼容性关系:
| IS | IX | S | X | |
|---|---|---|---|---|
| IS | ✔ | ✔ | ✔ | ✖ |
| IX | ✔ | ✔ | ✖ | ✖ |
| S | ✔ | ✖ | ✔ | ✖ |
| X | ✖ | ✖ | ✖ | ✖ |
- ✔ 表示兼容,允许同时存在。
- ✖ 表示不兼容,不能同时存在。
5. 源代码层面的实现
在 MySQL 的 InnoDB 存储引擎中,意向锁的实现主要体现在锁管理和事务管理模块中。我们从源码中进行分析:
5.1 锁管理模块
InnoDB 的锁管理模块位于 lock0lock.cc 文件中,主要函数有:
lock_rec_lock():负责加行级锁,包括排他锁(X 锁)和共享锁(S 锁)。在加锁之前,会先判断是否需要获取意向锁。lock_table():负责加表级锁,其中也涉及到意向锁的获取过程。
5.2 意向锁的加锁过程
在加行级锁时,MySQL 首先会根据事务需要加的锁类型来决定是否需要意向锁。假如事务需要在某行上加 X 锁(排他锁),系统会首先调用 lock_table() 来尝试给对应表加 IX 锁(意向排他锁)。如果意向锁冲突,则表明另一个事务已经持有冲突的锁(例如,另一个事务持有 S 锁),加锁失败。
相关源码逻辑如下:
bool lock_table(dict_table_t* table, // 要加锁的表ulint type, // 锁的类型(X 锁、S 锁、IX 锁、IS 锁等)trx_t* trx // 当前事务
) {// 加锁过程,判断当前表是否已持有冲突的锁if (type == LOCK_IX || type == LOCK_IS) {// 检查是否存在冲突的锁,涉及到 IX 和 IS 的兼容性// 如果可以加锁,则加锁成功}return success;
}
5.3 锁兼容性检查
意向锁与其他锁的兼容性通过 lock_mode_compat() 函数进行判断。该函数用于确定两种锁类型是否兼容,是否可以同时存在。
例如,IX 锁与 S 锁之间是互斥的,因此在加锁时会检查 IX 锁是否与现有的锁冲突:
bool lock_mode_compat(ulint mode1, // 第一个锁的类型ulint mode2 // 第二个锁的类型
) {if ((mode1 == LOCK_IX && mode2 == LOCK_S) || (mode1 == LOCK_S && mode2 == LOCK_IX)) {// IX 锁与 S 锁冲突,返回不兼容return false;}// 其他兼容性检查逻辑return true;
}
5.4 表级锁与行级锁的协作
当事务对某行进行加锁操作时,会先调用表级的意向锁机制,表级的意向锁通过 lock_table() 函数处理,而行级锁则通过 lock_rec_lock() 实现。加锁顺序为:
- 检查是否已经持有相应的意向锁,如果没有,则先申请意向锁。
- 然后再申请具体行的锁。
bool lock_rec_lock(ulint type, // 锁的类型dict_index_t* index, // 行所在的索引const buf_block_t* block,// 行所在的块ulint heap_no, // 行的索引号trx_t* trx // 当前事务
) {// 如果需要意向锁,则首先调用 lock_table() 加表锁if (need_intention_lock(type)) {if (!lock_table(index->table, LOCK_IX, trx)) {return false; // 加表意向锁失败}}// 接下来加行级锁// 锁管理器会检查是否与现有的行锁冲突return lock_rec_add_to_queue(type, block, heap_no, trx);
}
6. 意向锁在事务中的表现
事务在获取行级锁时,首先获取表级的意向锁,只有在表级意向锁不与其他事务冲突时,行级锁才能继续加上。这种机制保证了行级锁与表级锁之间的有效协调,从而避免了事务之间的冲突。
总结:
- 意向锁是为了提高 MySQL 锁管理效率而设计的,允许 MySQL 在表级快速判断是否可以加锁。
- 两种意向锁类型:意向共享锁(IS)和意向独占锁(IX),用于表示事务想要加的行级锁类型。
- 源码实现表现在
lock_table()和lock_rec_lock()等函数中,意向锁通过检查锁的兼容性确保事务在行级和表级加锁的正确性。 - 意向锁的作用是避免在加表锁时遍历所有行锁,从而大幅提高系统性能。
通过意向锁,MySQL 能有效地管理复杂的锁冲突场景,特别是在行级锁和表级锁同时存在时提供了明确的锁定层次,防止冲突并保持高效的锁操作。
相关文章:
MySQL 的意向锁(Intention Locks)原理详解
1. 背景:为什么需要意向锁? MySQL 中意向锁的主要作用是用于支持行级锁与表级锁的并存,特别是在 InnoDB 存储引擎中。InnoDB 提供了行级锁,而在某些场景下,数据库系统仍需要对整张表加锁,例如 LOCK TABLES …...
31个省份农业科技水平(农业技术创新或农业科技专利数据)2010-2022年
一、测算方式:参考C刊《湖北大学学报(哲学社会科学版)》张金鑫(2020)老师的做法,采用农业( 农林牧渔业) 三类专利总和来衡量农业技术创新 二、资料范围:31个省份,403个观测值,已经整理成面板数…...
Python代码执行失败问题及解决方案
目录 一、Python代码执行失败的原因 二、常见的Python错误类型 1. 语法错误(SyntaxError) 2. 运行时错误(RuntimeError) 3. 类型错误(TypeError) 4. 导入错误(ImportError) 5…...
Java 遗传算法
遗传算法(Genetic Algorithm, GA)是一种基于自然选择和遗传学原理的优化算法,用于求解复杂的搜索和优化问题。在Java中实现遗传算法通常包括以下几个步骤: 初始化种群:生成一组随机解作为初始种群。适应度评估&#x…...
C++ (一) 基础语法
基础语法:C的开胃小菜 欢迎来到C的世界,这里是编程的盛宴,也是逻辑的迷宫。别担心,我们不会一开始就让你啃硬骨头,而是从基础语法开始,让你慢慢品尝编程的美味。准备好了吗?让我们开始这场编程…...
Qt/C++路径轨迹回放/回放每个点信号/回放结束信号/拿到移动的坐标点经纬度
一、前言说明 在使用百度地图的路书功能中,并没有提供移动的信号以及移动结束的信号,但是很多时候都期望拿到移动的哪里了以及移动结束的信号,以便做出对应的处理,比如结束后需要触发一些对应的操作。经过搜索发现很多人都有这个…...
C 语言介绍及操作案例
C 语言是一种广泛使用的通用编程语言,具有高效、灵活和可移植性强等特点。 一、C 语言的基本特点 简洁高效 C 语言语法简洁,表达能力强。它提供了丰富的数据类型和运算符,可以方便地进行各种计算和操作。C 语言的代码执行效率高,能够直接访问硬件资源,适用于对性能要求较…...
Ivanti云服务被攻击事件深度解析:安全策略构建与未来反思
攻击事件背景 近期,威胁情报和研究机构Fortinet FortiGuard Labs发布了一份关于针对IT解决方案提供商Ivanti云服务设备(Ivanti Cloud Services Appliance,CSA)的复杂网络攻击的详细分析。 该攻击被怀疑是由国家级对手发起…...
如何做出正确选择编程语言:关于Delphi 与 C# 编程语言的优缺点对比
概述 为您的项目选择正确的技术可能是一项相当棘手的任务,尤其是当您以前从未需要做出这样的选择时。如今可用的选项范围非常广泛。虽然一些编程语言和工具有着相当悠久的历史,但其他一些则是刚刚开始赢得开发人员青睐的新手。 在这篇博文中࿰…...
39.3K Star,一个现代的数据库ORM工具,专为Node.js和TypeScript设计
大家好,今天给大家分享一个现代的数据库对象关系映射(Object-Relational Mapping,ORM)工具Prisma ORM,它旨在简化数据库操作,提高开发效率,并确保类型安全。 项目介绍 Prisma ORM适用于各种需要…...
Nginx和Mysql的基础命令
1.安装nginx brew install nginx 2.启动nginx brew services start nginx 3.查看nginx文件默认路径 brew info nginx 重装要先关闭nginx 4.nginx.conf 地址 nginx -t 5.nginx重启 brew services restart nginx 6.关闭nginx brew services stop nginx 7.卸载nginx brew uninstal…...
Docker之容器常见操作
docker 命令介绍 docker --help 管理命令: container 管理容器image 管理镜像network 管理网络命令: attach 介入到一个正在运行的容器build 根据 Dockerfile 构建一个镜像commit 根据容器的更改创建一个新的镜像cp 在本地文…...
猜数游戏(Fortran)
背景 学了两个月Fortran还没来一次正式练习 于是—— 代码 program gessnum! implicit none 不取消IN规则。integer::num,areal::Ncall random_seed()call random_number(N)aint(N*10)print*,"请输入您猜的数字:"read(*,*)numdo i1,3if (numa)thenpri…...
代码随想录 -- 贪心 -- 单调递增的数字
738. 单调递增的数字 - 力扣(LeetCode) 思路: 首先将正数n转化为字符串类型;定义一个flag:标记flag以及之后的位数都是9;从后向前遍历字符串n,如果当前的位数小于他上一位,将上一位…...
【小洛的VLOG】Web 服务器高并发压力测试(Reactor模型测试)
目录 引言 工具介绍 环境介绍 测试结果 个人主页:东洛的克莱斯韦克-CSDN博客 引言 大部分的网络通信都是支持TCP/IP协议栈,为了保证通信的可靠性,客户端和服务端之间需要建立链接。服务端能并发处理多少个链接,平均每秒钟能处理…...
Window:下载与安装triton==2.0.0
triton2.0.0谷仓下载 创建python3.10的工作环境: conda create -n anti-dreambooth python3.10然后在下载目录下执行代码: pip install triton-2.0.0-cp310-cp310-win_amd64.whl...
零,报错日志 2002-Can‘t connect to server on‘106.54.209.77‘(1006x)
零,报错日志 2002-Can’t connect to server on’106.54.209.77’(1006x) 今天差点被这个报错给折磨疯掉 尝试一:对腾讯云服务器进行更改 尝试二:针对配置文件处理 step1 //确保注释 /etc/mysql/mysql.conf.d/mysqld.cnf 下# bind-addres…...
R语言笔记(一)
文章目录 一、R objects二、Types of data三、Operators1、Operators2、Comparison operators3、Logical operators 四、Check types of data objects五、Convertion between data objects六、R workspace 一、R objects Two basic types of things/objects: data and functio…...
MusePose模型部署指南
一、模型介绍 MusePose是一个基于扩散和姿势引导的虚拟人视频生成框架。 主要贡献可以概括如下: 发布的模型能够根据给定的姿势序列,生成参考图中人物的舞蹈视频,生成的结果质量超越了同一主题中几乎所有当前开源的模型。发布该 pose alig…...
又一次升级:字节在用大模型在做推荐啦!
原文链接 字节前几天2024年9年19日公开发布的论文《HLLM:通过分层大型语言模型增强基于物品和用户模型的序列推荐效果》。 文字、图片、音频、视频这四大类信息载体,在生产端都已被AI生成赋能助力,再往前一步,一定需要一个更强势…...
告别盲目搜索!Unity大版本升级时,系统化处理API变更的5个步骤
Unity大版本升级的系统化实践:从API变更管理到团队协作优化 当Unity 2023 LTS发布时,某中型游戏团队在升级过程中发现超过40%的脚本因API变更而报错,导致项目停滞两周。这种场景在技术迭代中并不罕见,但大多数团队仍采用"遇到…...
STP安全特性实战:如何用bpduguard和bpdufilter防止网络攻击(附真实案例)
STP安全特性实战:如何用bpduguard和bpdufilter防止网络攻击(附真实案例) 在企业网络架构中,生成树协议(STP)的安全防护常常被忽视,直到某天凌晨2点,值班工程师突然接到全网瘫痪的告警…...
造相-Z-Image-Turbo亚洲美女LoRA创作实战:三个案例教你玩转AI绘画
造相-Z-Image-Turbo亚洲美女LoRA创作实战:三个案例教你玩转AI绘画 1. 认识造相-Z-Image-Turbo与亚洲美女LoRA 造相-Z-Image-Turbo是一款强大的AI图片生成模型,而亚洲美女LoRA则是专门针对亚洲人物特征优化的风格适配器。这个组合让普通用户也能轻松创作…...
从“炼丹”到“调参”:聊聊反向传播里那些容易被忽略的梯度细节(以PyTorch为例)
从“炼丹”到“调参”:聊聊反向传播里那些容易被忽略的梯度细节(以PyTorch为例) 在深度学习的世界里,反向传播算法就像炼金术士的魔法书,而梯度则是那些隐藏在公式背后的神秘力量。许多开发者能够熟练地调用.backward(…...
Gradio项目快速公网演示:除了share=True,你还有这几种轻量级内网穿透方案
Gradio项目快速公网演示:5种轻量级内网穿透方案横向评测 当你开发了一个酷炫的机器学习模型演示,或是精心设计的数据可视化界面,最迫切的需求往往是如何快速分享给同事或客户。Gradio的shareTrue参数可能是大多数开发者首先想到的方案&#x…...
ChatBI 开源产品实战解析:从语义层到Agent,如何选择你的AI数据助手?
1. 为什么企业需要AI数据助手? 想象一下这个场景:市场部的小王需要统计上季度各区域的销售数据,他对着Excel表格里密密麻麻的数字发愁,不得不找IT部门帮忙写SQL查询。三天后拿到数据时,业务窗口期已经错过——这是很多…...
5个强力优化步骤:Win11Debloat让Windows系统性能提升显著
5个强力优化步骤:Win11Debloat让Windows系统性能提升显著 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本,用于从Windows中移除预装的无用软件,禁用遥测,从Windows搜索中移除Bing,以及执行各种其他更改以简化…...
YOLOv8工业缺陷检测推理延迟骤降63%:基于TensorRT量化+ONNX Runtime定制化内核的完整链路
第一章:YOLOv8工业缺陷检测推理延迟骤降63%:基于TensorRT量化ONNX Runtime定制化内核的完整链路在高吞吐产线场景下,YOLOv8原生PyTorch模型在Jetson AGX Orin上单帧推理延迟达84.2ms(输入尺寸640640),严重制…...
OpCore-Simplify:智能配置驱动的OpenCore EFI自动化构建工具
OpCore-Simplify:智能配置驱动的OpenCore EFI自动化构建工具 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 🤔 配置黑苹果的痛…...
保姆级教程:在Windows 11上为PyTorch配置CUDA 12.x和cuDNN(含环境变量疑难杂症排查)
Windows 11深度学习环境配置全攻略:从CUDA安装到PyTorch GPU加速实战 每次打开PyCharm准备大展身手时,看到那个令人心碎的False——torch.cuda.is_available()的输出结果,是不是感觉整个深度学习梦想都被泼了冷水?别担心…...
