Skip to main content

锁的存储与检查

所说的锁是存在哪里的?检查时候是去哪里检查?

锁不是写在磁盘上的“文件”,而是事务在内存里申请、由 InnoDB 维护的数据结构。检查时也是查这些内存状态对外暴露的视图,而不是去翻某个表文件。

锁存在哪里?

可以分三层理解:

1. InnoDB 数据锁(先总后分)

这一类包括:行锁(record / gap / next-key)、意向锁(IS / IX)、以及 InnoDB 层的表级 S / X。下面先讲它们共同的存放与归属,再分别讲行锁和意向锁。

共性(以上锁都适用,不单指意向锁)

  • 放在哪里:MySQL 进程内存里的 InnoDB 锁系统(lock system),运行时结构,不写入磁盘
  • 由谁持有:归属于某个事务(trx);事务未结束前锁通常一直存在,COMMIT / ROLLBACK 后释放。

行锁(锁什么对象)

  • 加在索引记录上(B+ 树页上的记录,以及可能的间隙),不是抽象的“行对象”。
  • 没走索引时,扫描范围变大,可能锁住大量记录甚至接近“锁全表”。

意向锁(表级标记,做什么用)

  • 挂在表对象上的 IS / IX,表示“本事务准备或正在给某些索引记录加 S / X 行锁”。
  • 不直接锁住某一行数据,只用于表锁与行锁之间的快速兼容性判断(见 intention.md 里的矩阵)。
维度行锁意向锁
粒度索引记录 / 间隙整张表上的标记
是否挡住读写某行否(本身不锁行)
典型模式XGAPNEXT_KEYISIX

可用下面这个最小例子理解“归属 + 对象”:

BEGIN;
SELECT * FROM user WHERE id = 1 FOR UPDATE;
-- 这时事务会持有:
-- 1) 表 user 的 IX(意向排他锁)
-- 2) PRIMARY 索引中 id=1 对应记录的 X 行锁
-- 提交前,这两类锁都属于当前事务
COMMIT; -- 提交后释放
事务 A (内存)
└── 表 user:IX
└── 索引 idx_age:行锁 / 间隙锁
└── 索引 PRIMARY:行锁

2. MDL(元数据锁,DDL 相关)

  • 位置:Server 层的 MDL 哈希表(也在内存里)。
  • 作用:保护表结构(ALTER TABLEDROP 等),和 InnoDB 行锁是两套机制。
  • SHOW PROCESSLIST 里常见 Waiting for table metadata lock,查的就是这层。

3. 用户显式表锁(LOCK TABLES

  • 也是 Server + 存储引擎协作,逻辑上仍是当前会话/事务持有,同样在内存里维护,不会变成磁盘上的 .lock 文件。

检查时去哪里看?

按用途选入口(你 lock.md 里已经列了,这里按“查什么”归纳):

想查什么去哪里
当前有哪些 InnoDB 锁、锁在哪张表/哪个索引MySQL 8.0:performance_schema.data_locks
谁在等谁的锁MySQL 8.0:performance_schema.data_lock_waits
哪些事务还没提交、持锁多久information_schema.INNODB_TRX
连接是否在等锁(粗看)SHOW PROCESSLISTStateLocked
死锁、锁等待文字详情SHOW ENGINE INNODB STATUS\GTRANSACTIONSLATEST DETECTED DEADLOCK
是否在等 MDLSHOW PROCESSLIST + 8.0 可配合 performance_schema.metadata_locks

MySQL 8.0 排查时优先:

-- 当前所有 InnoDB 数据锁(含 IS/IX/S/X、行锁、间隙锁等)
SELECT * FROM performance_schema.data_locks\G

-- 等待关系:blocking → waiting
SELECT * FROM performance_schema.data_lock_waits\G

-- 未提交事务(常是“谁一直占着锁”)
SELECT * FROM information_schema.INNODB_TRX\G

data_locks 里能看到例如:

  • LOCK_MODEIS / IX / S / X / REC_NOT_GAP / GAP / NEXT_KEY
  • OBJECT_SCHEMA / OBJECT_NAME:哪张表
  • INDEX_NAME:锁在哪个索引上

这就是把内存里的锁结构导出成可读表,不是去磁盘找“锁文件”。

MySQL 5.7 用旧视图:information_schema.INNODB_LOCKSINNODB_LOCK_WAITS(8.0 已移除,改用 performance_schema)。


和兼容性矩阵的关系

  • 矩阵:静态规则,“两种锁能不能同时存在”。
  • data_locks:动态快照,“此刻到底有哪些锁、在谁的事务里”。
  • 检查流程:新请求要加锁 → InnoDB 在内存锁表里查同对象上已有锁 → 用兼容性矩阵判断 → 冲突则进入 data_lock_waits

一句话

锁存在 InnoDB/Server 的内存锁结构里,跟事务和索引/表对象绑定;排查时查 performance_schema.data_locks / data_lock_waitsINNODB_TRX,必要时用 SHOW ENGINE INNODB STATUS,而不是去数据目录或某张业务表里找。