分析 InnoDB 死锁并记录所有死锁
MySQL性能命令
-- Latest deadlock: LATEST DETECTED DEADLOCK section (only the most recent is kept)
SHOW ENGINE INNODB STATUS\G
-- Total deadlock counter
SELECT NAME, COUNT FROM information_schema.INNODB_METRICS WHERE NAME = 'lock_deadlocks';
-- Write every deadlock to the error log (logged at Note level, needs verbosity 3)
SET PERSIST innodb_print_all_deadlocks = ON;
SET PERSIST log_error_verbosity = 3;作用
显示死锁中的两个事务、各自持有和等待的锁(索引、lock_mode、记录)以及 InnoDB 回滚了哪一个;计数器跟踪发生频率,错误日志保留历史死锁。
适用场景
应用收到错误 1213 'Deadlock found when trying to get lock' 或死锁告警增多时。
注意
LATEST DETECTED DEADLOCK 只保留最后一次事件,重启后丢失。'HOLDS THE LOCK(S)' / 'WAITING FOR THIS LOCK TO BE GRANTED' 行中的索引名和 lock_mode(X、S、gap、insert intention)说明了原因;'WE ROLL BACK TRANSACTION (n)' 显示牺牲者。遇到 1213 时应用必须重试整个事务。根本解决办法:以一致的顺序访问行、保持事务简短、使用合适的索引减少间隙锁,并在合适场景使用 READ COMMITTED。log_error_verbosity=3 也会启用所有 Note 消息;注意错误日志的增长。MySQL Community 中不存在 Innodb_deadlocks 状态变量;计数器请使用 INNODB_METRICS。