意向共享锁(is)和意向排他锁(ix)是innodb自动添加的表级锁,分别表示事务将对表中某些行加共享锁或排他锁,起预告作用以避免全表扫描判断行锁状态,协调行锁与表锁共存。

什么是意向共享锁(IS)和意向排他锁(IX)
IS 和 IX 是 InnoDB 自动加的表级锁,你无法手动 LOCK TABLES 或显式声明它们,也不该在业务 SQL 中试图绕过或“避开”它们——它们是行锁与表锁共存的基础设施。简单说:IS 表示“我接下来要对某些行加 S 锁”,IX 表示“我接下来要对某些行加 X 锁”。它们不直接保护数据,只起“预告”作用,让其他事务快速判断“这张表里是否已有行被读/写”,避免全表扫描检查每行锁状态。
为什么必须先加 IS/IX 才能加行锁
InnoDB 采用多粒度锁机制,锁可以同时存在于表、页、行多个层级。加行锁前必须先在表级申请对应意向锁,否则会出现逻辑断层。比如事务 T1 正在对某行加 X 锁,但没加 IX,此时另一个事务 T2 想对该表加 S 表锁(全表读),它无法知道表内是否有行正被修改,只能阻塞或错误放行——这会破坏隔离性。
- 执行
SELECT ... LOCK IN SHARE MODE→ 自动申请IS+ 行级S锁 - 执行
SELECT ... FOR UPDATE或UPDATE/DELETE→ 自动申请IX+ 行级X锁 - 没有对应意向锁,行锁根本不会被允许加成功(你会看到锁等待或超时)
IS/IX 与其他锁的兼容性怎么查
看 SHOW ENGINE INNODB STATUS\G 输出里的 TRANSACTIONS 和 LATEST DETECTED DEADLOCK 部分,里面明确列出当前各事务持有的锁类型及等待关系。但更直接的方式是记住这个核心兼容矩阵(仅针对同一张表):
IS IX S X IS ✓ ✓ ✓ ✗ IX ✓ ✓ ✗ ✗ S ✓ ✗ ✓ ✗ X ✗ ✗ ✗ ✗
关键点:
-
IS和IX彼此兼容,多个事务可同时持有 -
IS与表级S兼容,但与表级X不兼容(意味着有人想锁整张表写入,你就不能在表里读行) -
IX与任何表级锁都不兼容——一旦有事务在表里改行,整张表就不再允许被加S或X表锁 - 行锁兼容性(
S/X)和意向锁兼容性是两套规则,不能混为一谈
容易被忽略的实战陷阱
很多死锁或长时间锁等待不是因为行锁冲突,而是表级意向锁卡住了。典型场景:
- 长事务中执行了
SELECT ... FOR UPDATE但没提交,它持着IX锁,此时另一个事务想ALTER TABLE——会被IX阻塞,因为ALTER需要表级X锁,而IX与X不兼容 - 误用
LOCK TABLES t1 WRITE(MyISAM 风格)在 InnoDB 表上,会直接报错或隐式升级为表级X锁,立刻与所有IX冲突 - 监控时只看
Innodb_row_lock_waits,却忽略Table_locks_waited,其实等待源是意向锁引发的表锁排队
真正难排查的,从来不是“哪一行被锁了”,而是“谁在表级层面卡住了别人加意向锁的路”。











