首页/数据/数据库速查/InnoDB 锁类型总览(行锁/表锁/意向锁/MDL)
性能与调优57 条

InnoDB 锁类型总览(行锁/表锁/意向锁/MDL)

锁家谱:行级(记录锁/间隙锁/临键锁)、表级(意向锁 IS/IX、AUTO-INC)、元数据锁(MDL);业务感知的锁等待 90% 来自行锁与 MDL。

数据库速查数据更新于 2026-10-13

锁类型总览

InnoDB 的锁按粒度分成几层:行级锁包含记录锁、间隙锁与临键锁,表级锁包含意向锁与自增锁,另外还有一类元数据锁作用在表结构上。业务里感知到的锁等待绝大多数来自行锁与元数据锁。更关键的一点是:行锁锁的并不是物理行,而是索引记录——条件列没有索引时,扫描到的所有记录都会被锁住,看起来就像锁了整张表。

基本信息

行级锁记录锁、间隙锁、临键锁
表级锁意向锁、自增锁
元数据锁作用在表结构上,改表与数据访问互相阻塞
默认隔离级别可重复读下会使用间隙锁与临键锁
加锁对象索引记录,而不是物理行
查看手段锁信息视图、锁等待视图、引擎状态输出

典型使用场景

  • 并发写入互相阻塞,确认是不是锁范围过大
  • 在线改表被阻塞,确认是否存在长时间未提交的事务
  • 批量更新锁住大量行,评估是否需要补索引
  • 死锁复盘:确认事务的加锁顺序
  • 巡检输出锁等待与长事务清单

查看锁现状

查看锁现状
SELECT * FROM performance_schema.data_locks\G   # 当前持有的锁明细
SELECT * FROM sys.innodb_lock_waits\G   # 等待关系与阻塞方
SHOW ENGINE INNODB STATUS\G   # 查看事务段与最近的死锁信息

锁类型速查

锁粒度触发条件
记录锁行等值条件命中索引记录
间隙锁索引区间可重复读下的范围条件
临键锁记录加间隙可重复读下的默认加锁方式
意向锁表行锁存在时自动加,不阻塞读取
自增锁表自增列的并发插入
元数据锁表结构改表与数据访问互相阻塞
条件列没有索引时会退化成扫描全表并锁住大量记录:锁问题的根因常常是索引缺失,而不是并发太高。
元数据锁容易被忽略:一个长事务没有提交,改表语句就会一直排队,表现为改表卡住而不是数据行锁等待。

减少锁冲突清单

  • 条件列补索引,缩小加锁范围
  • 事务尽量短,避免长事务持有锁
  • 批量更新分批提交,降低单次锁范围
  • 统一业务侧的加锁顺序,减少死锁
  • 监控锁等待时长并配置告警
死锁由数据库自动检测并回滚其中一个事务:看到报错不用慌,要做的是顺着两个事务的加锁顺序去调整业务逻辑,让它按同一顺序访问资源。

易错点

  • 以为只锁了一行:条件列没有索引时实际锁住扫描到的全部记录,并发写入被大面积阻塞
  • 忽略元数据锁:长事务没提交导致改表一直排队,却被当成数据行锁问题排查
  • 批量更新不控制范围:一次改动过多行,锁持有时间变长,其他业务同时被堵
  • 事务里夹带等待操作:锁一直不释放,等待链条越拉越长

数据来源与参考

  • MySQL 8.0 Reference Manual: InnoDB Locking

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌