意向锁本身不阻塞操作,仅作表级快速冲突检测:is由select ... lock in share mode触发,ix由select ... for update、update、delete、insert自动触发;二者彼此兼容,但is阻塞write表锁、允许read表锁,ix则阻塞所有表锁。

意向锁本身不阻塞任何操作,但它是表级锁能否快速通过的关键开关——没它,加个 LOCK TABLES t WRITE 就得扫全表行锁;有它,一次查 data_locks 就能拒绝或放行。
IS 和 IX 锁到底由什么语句触发?
你写不出 LOCK TABLE t INTENTION SHARE 这种语法,因为 IS/IX 是 InnoDB 自动加的,只取决于你执行的语句类型:
-
SELECT ... LOCK IN SHARE MODE→ 自动加IS锁(同时对命中行加 S 行锁) -
SELECT ... FOR UPDATE、UPDATE、DELETE、INSERT→ 自动加IX锁(即使INSERT没显式锁,也可能因唯一约束检查触发) - 没走索引的
UPDATE或DELETE(如WHERE non_indexed_col = 'x')→ 仍加IX,但会为每行加 X 行锁,效果接近“伪表锁”
为什么表锁要查意向锁,而不是直接扫行?
一张千万行的表,如果每次加 LOCK TABLES t WRITE 都得遍历所有行判断是否被 SELECT FOR UPDATE 锁住,光锁检测就可能卡几秒。意向锁就是这个瓶颈的解法:
-
IS表示“我准备对某些行加 S 锁”,不锁数据,只打标记 -
IX表示“我准备对某些行加 X 锁”,同样不锁数据,只打标记 - 其他事务申请表锁时,只看表上有没有
IS或IX:有,就说明底下可能有行锁冲突,立刻决策;没有,直接通过
IS/IX 与表锁的兼容性怎么判断?
别记整张矩阵表,核心就两条规则:
-
IS允许LOCK TABLES t READ(读锁),但拒绝LOCK TABLES t WRITE(写锁) -
IX拒绝所有表锁:READ和WRITE都会被阻塞 -
IS和IX彼此兼容——多个事务可同时持有,这是高并发的基础
验证方式:执行 SELECT object_schema,object_name,lock_type,lock_mode FROM performance_schema.data_locks WHERE lock_type = 'TABLE' AND lock_mode LIKE '%INTENTION%';,能看到 IS 或 IX 记录。
监控时只看到 IS/IX 锁,问题真出在它身上吗?
几乎从不。意向锁生命周期极短,只要行锁释放,它就跟着释放。看到长期存在的 IX 锁,真正该查的是:
- 对应事务是否没
COMMIT或ROLLBACK(查INFORMATION_SCHEMA.INNODB_TRX) - 事务是否卡在慢查询、网络超时或应用层未提交
- 是否因没走索引导致锁了全表行(此时
IX是表象,根源是 SQL 写法)
意向锁只是信标,不是病因;盯着它不放,等于听见警报就修喇叭。











