<p>应使用grep -A 50 -B 5 "RECORD LOCKS.space id"从error.log提取死锁记录,因其以** (1) TRANSACTION:开头、含RECORD LOCKS描述且末尾有WE ROLL BACK TRANSACTION (1),而DEADLOCK关键字在错误日志中不存在。</p>

直接看错误日志里的死锁块,必须用 RECORD LOCKS 当关键字去匹配,而不是搜 DEADLOCK 或 LATEST DETECTED DEADLOCK——后者只存在于 SHOW ENGINE INNODB STATUS 输出中,错误日志里压根不出现。
怎么从 error.log 里准确提取一次死锁记录
MySQL 8.0 开启 innodb_print_all_deadlocks = ON 后,每次死锁都会往 log_error 文件追加一段完整日志,以 *** (1) TRANSACTION: 开头、含多行 RECORD LOCKS 描述。但这段内容不是独立文件,也不带时间戳前缀,容易漏抓。
- 正确命令:
grep -A 50 -B 5 "RECORD LOCKS.*space id" /var/log/mysql/error.log(Linux)或findstr /n "RECORD LOCKS" C:\mysql\data\hostname.err(Windows) - 错误做法:
grep "DEADLOCK" /var/log/mysql/error.log——几乎一定为空 - 如果日志量大,建议加时间范围过滤:先用
grep -n "2026-09-02" /var/log/mysql/error.log定位行号,再结合上下文提取 - 注意:每段死锁日志末尾通常有
WE ROLL BACK TRANSACTION (1),可辅助确认是否为完整块
怎么看懂死锁日志里的 lock_mode 和锁类型
关键不是记术语,而是区分「谁真占着资源」和「谁在瞎等」。MySQL 8.0 日志里同一事务可能同时出现 HOLDS THE LOCK(S) 和 WAITING FOR THIS LOCK,但这不一定是矛盾——它可能是在等自己没拿到的另一把锁,或因间隙锁(GAP)与插入意向锁(INSERT_INTENTION)冲突导致的伪循环。
-
lock_mode X locks rec but not gap:精准行锁,只锁索引记录本身,冲突面小 -
lock_mode S locks gap before rec:间隙锁,锁住 (a,b) 区间,极易与其他事务的插入/更新交叉 -
lock_mode X locks gap before rec:更危险,常见于WHERE ... ORDER BY ... LIMIT 1 FOR UPDATE类语句,会锁住排序范围 - 看到
lock_trx_id对应的事务在information_schema.INNODB_TRX中已trx_state = RUNNING但trx_started很早,大概率是长事务拖累了别人
为什么 transaction ID 对不上业务日志
TRANSACTION 123456789 这种 ID 是 InnoDB 内部编号,和你代码里打点的 trace_id、request_id 完全无关。想对齐,唯一可靠方式是结合 mysql thread id(日志里叫 OS thread handle 或 mysql thread id)查 information_schema.PROCESSLIST,再比对 INFO 列里的 SQL 片段和执行时间。
- 执行:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM information_schema.PROCESSLIST WHERE ID = 111;(111 来自日志中的mysql thread id 111) - 重点看
INFO是否含UPDATE/DELETE+ 关键 WHERE 条件(如order_id = 'ORDER10001'),这是最短路径定位代码位置 - 如果
INFO为空或为NULL,说明该线程当前没在执行 SQL,可能是事务已开始但还没发查询——得回溯应用层连接池日志 - 别依赖
trx_id去查 Binlog,InnoDB 的trx_id和 Binlog event 的original_commit_timestamp没映射关系
真正难的不是读出「哪两行 SQL 卡住了」,而是判断「为什么这两行会走到同一个索引页、同一个间隙区间」——这往往藏在隐式类型转换、函数索引失效或 OR 条件未走联合索引的细节里,日志不会告诉你,得拿 EXPLAIN 和 performance_schema.data_locks 交叉验证。


















