MySQL 中有哪些锁类型
InnoDB锁可以按粒度、兼容性、实现、意向锁几个维度划分,面试重点:行锁、表锁、意向锁、间隙锁、临键锁、MDL元数据锁。
一、按锁粒度划分
1. 表级锁:锁住整张表
lock table xxx read,多个事务可以同时加读锁;有读锁时,其他事务不能写。
lock table xxx write,只有一个事务持有,其他事务读写都阻塞。
MyISAM默认使用表锁;InnoDB一般不会手动用表锁,粒度大,并发差。
2. 行级锁(InnoDB特有,只锁行记录)
只锁被操作的数据行,并发高。
- 行共享读锁 S(共享锁):select … lock in share mode
多个事务可以同时加S锁;如果有S锁,其他事务不能加X锁做修改。 - 行排他写锁 X(排他锁):update / delete / select … for update
当前事务独占,其他事务不能加S、X锁,读写阻塞。
行锁只有走索引才会生效;如果没用到索引,InnoDB会退化成表锁。
意向锁(意向共享IS、意向排他IX)
意向锁是表级锁,InnoDB自动加,不需要手动操作。
- 意向共享 IS:事务准备给表中某些行加S锁,先给表加IS
- 意向排他 IX:事务准备给表中某些行加X锁,先给表加IX
作用:快速判断表锁和行锁之间是否冲突,避免遍历每一行锁做判断。
意向锁之间互相兼容;意向锁和普通S/X表锁互斥。
二、RR可重复读隔离级别特有:解决幻读
1. 间隙锁 Gap Lock
锁住索引记录之间的间隙,不锁记录本身,防止其他事务在间隙插入新数据。
只存在于RR隔离级别;RC隔离级别没有间隙锁。
2. 临键锁 Next‑Key Lock
行锁 + 间隙锁的组合,InnoDB RR默认加的锁。
左开右闭区间,锁住当前记录,同时锁住前面的间隙,防止插入,以此解决幻读。
当查询命中唯一索引等值匹配,临键锁会退化为普通行锁。
三、MDL 元数据锁(Metadata Lock)
表结构锁,5.6之后引入,访问表自动获取。
- MDL读锁:增删改查DML,加MDL读锁,多个事务共享。
- MDL写锁:alter table 修改表结构DDL,加MDL写锁,排他。
经典坑:长事务持有MDL读锁,此时执行alter table会被阻塞,后续所有DML全部堵塞,库雪崩。
锁兼容矩阵
| S | 兼容 | 互斥 | 兼容 | 互斥 |
| X | 互斥 | 互斥 | 互斥 | 互斥 |
| IS | 兼容 | 互斥 | 兼容 | 兼容 |
| IX | 互斥 | 互斥 | 兼容 | 兼容 |
补充区分:乐观锁 & 悲观锁
update table set val=?,version=version+1 where id=? and version=old_version
面试高频小结
总结:
粒度上分表锁、行锁、意向锁;RR下有间隙锁、临键锁;还有MDL元数据锁;思想上分悲观锁、乐观锁。RC没有间隙锁,RR靠临键锁解决幻读。






