MySQL意向锁(Intention Lock)的作用是什么?
MySQL 中的意向锁(Intention Lock)是 InnoDB 存储引擎实现的一种表级锁(Table-level Lock)。
简单来说,意向锁的核心作用是:快速判断表中有没有记录被加锁,从而提高表级锁和行级锁之间冲突检测的效率。
为了让你彻底理解,我们可以从“它解决了什么问题”、“它的工作原理”以及“生活中的打比方”三个方面来拆解。
1. 意向锁解决了什么问题?(为什么需要它?)
在没有意向锁的情况下,假设有这样一个场景:
- 事务 A 给表
users中的第 10 行数据加了一个排他锁(行锁,X锁),正在修改这行数据。 - 此时,事务 B 想要修改表结构(或者执行
LOCK TABLES users WRITE),这需要给整个users表加一个表级排他锁(表级 X锁)。
冲突检查的难题:
事务 B 在加表锁之前,必须确保这整张表中没有任何一行数据被其他事务锁定。
如果没有意向锁,数据库就只能从头到尾遍历全表(全表扫描),去检查是不是某一行有行锁。如果表里有上千万条数据,这种遍历检查的效率会极低,严重影响性能。
引入意向锁后的解决方式:
有了意向锁之后,流程变成了这样:
- 事务 A 在给第 10 行加行锁之前,必须先给
users表加上一个意向排他锁(IX)。 - 事务 B 想要给表加锁时,发现表上已经存在一个 意向排他锁(IX),立刻就知道“表里肯定有某一行正在被修改”,于是直接阻塞等待,不需要再去遍历全表了。
结论:意向锁的本质是一个“标志”,用于在表级别宣告表内存在行级锁,将时间复杂度从 O(N) 的全表扫描降到了 O(1) 的状态检查。
2. 意向锁的工作原理与分类
意向锁分为两种类型(都是表级锁):
- 意向共享锁(IS - Intention Shared Lock): 事务有意向对表中的某些行加共享锁(S锁)。
- 触发场景: 执行
SELECT ... LOCK IN SHARE MODE之前,InnoDB 会自动先加 IS 锁。
- 触发场景: 执行
- 意向排他锁(IX - Intention Exclusive Lock): 事务有意向对表中的某些行加排他锁(X锁)。
- 触发场景: 执行
INSERT、UPDATE、DELETE或SELECT ... FOR UPDATE之前,InnoDB 会自动先加 IX 锁。
- 触发场景: 执行
兼容性矩阵(核心重点)
理解意向锁,必须要看懂它的兼容性。这里有两个维度的兼容性:
① 意向锁与意向锁之间(完全兼容)
- 表级 IS 和 表级 IX 之间是互不冲突的。
- 因为它们只是“意向”,并不代表真的锁住了同一行。事务 A 打算改第 1 行(加IX),事务 B 打算改第 2 行(加IX),两者互不干扰。
② 意向锁与普通的表级锁(S/X)之间(按需互斥)
- 这才是意向锁真正发挥作用的地方!
| 锁类型 | 意向共享锁(IS) | 意向排他锁(IX) |
|---|---|---|
| 表级共享锁(S) | 兼容 | 冲突 |
| 表级排他锁(X) | 冲突 | 冲突 |
解释:
- 如果表里有 IX 锁(说明有人在改行),你想加表级 S 锁(全表只读)或表级 X 锁(全表修改),都会被拒绝/阻塞。
- 如果表里有 IS 锁(说明有人在读行),你想加表级 X 锁(全表修改),也会被阻塞。
(注:这里的 S 和 X 指的是*表锁,如果是行锁,依然是只看具体的行冲突不冲突)*
3. 意向锁的 3 个重要特性
- 自动获取,无需人工干预: InnoDB 会在执行 DML 语句前自动加上意向锁,开发者不需要(也无法)在代码中手动声明意向锁。
- 它是表锁,但不阻塞行锁: 意向锁只会阻塞表级别的锁(如
LOCK TABLES,或者 DDL 语句引起的表锁),它绝对不会阻塞行级锁。 - 解决锁冲突的高效手段: 它纯粹是为了协调“行锁”与“表锁”的关系而诞生的。
4. 通俗的比喻(大楼与房间)
- 表(Table) = 一栋大楼
- 行(Row) = 大楼里的某个房间
- 行级锁(Row Lock) = 锁住某个房间在里面办公
- 表级锁(Table Lock) = 把整栋大楼封锁起来(比如做整栋楼的消防改造)
- 意向锁(Intention Lock) = 大楼门口的电子显示屏
没有电子屏(无意向锁)时:
你想封锁整栋大楼,你必须去敲每一个房间的门(遍历全表),看看里面有没有人。非常浪费时间。
有电子屏(有意向锁)时:
任何人只要想进某个特定的房间办公(加行锁),必须先在大楼门口的电子屏上亮起一盏灯(加意向锁,声明“楼里有人”)。
当你想要封锁整栋大楼时,只需看一眼门口的电子屏,如果灯亮着(有意向锁),你就乖乖在门口等(阻塞)。你不用再去挨个房间检查了。同时,A 在 101 房间亮灯,并不妨碍 B 去 102 房间亮灯(意向锁之间兼容)。