MySQL中死锁问题常常导致事务回滚和接口超时,尤其在高并发场景下更容易反复出现。要确认死锁是否频繁发生,最直接的方式是分析InnoDB的运行状态日志。InnoDB引擎自带的状态输出中包含了最近检测到的死锁细节,通过定期获取并比对这些信息,就能掌握死锁的发生规律。

一、使用SHOW ENGINE INNODB STATUS获取死锁信息
在MySQL命令行或客户端中执行如下语句,可以查看InnoDB引擎的整体状态,其中LATEST DETECTED DEADLOCK部分记录了最近一次死锁的相关内容:
SHOW ENGINE INNODB STATUS;
该命令输出内容较多,我们重点关注以下片段:
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2023-xx-xx 10:00:00 0x7f... *** (1) TRANSACTION: TRANSACTION 12345, ACTIVE 2 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 58 page no 3 n bits 72 index PRIMARY of table `test`.`t_order` *** (2) TRANSACTION: TRANSACTION 12346, ACTIVE 1 sec ...
从这段日志中可以看到死锁发生的时间、涉及的事务ID、等待的锁类型以及具体的表和索引。如果每次查看都能看到新的死锁记录,说明死锁发生比较频繁。
二、通过脚本定时采集INNODB_STATUS日志
人工执行命令无法反映历史频率,我们可以编写一个简单的Shell脚本,定时将INNODB_STATUS中的死锁段落抽取出来并追加到文件:
#!/bin/bash
# 每5分钟采集一次死锁信息
MYSQL_USER="root"
MYSQL_PASS="your_password"
LOG_FILE="/var/log/mysql_deadlock.log"
while true; do
mysql -u$MYSQL_USER -p$MYSQL_PASS -e "SHOW ENGINE INNODB STATUSG" |
awk '/LATEST DETECTED DEADLOCK/{flag=1} flag{print} /TRANSACTIONS/{if(flag)exit}' >> $LOG_FILE
sleep 300
done
运行后,统计日志文件中的LATEST DETECTED DEADLOCK出现次数,即可估算单位时间内死锁的发生频次。
三、利用错误日志与系统变量辅助判断
当死锁频繁时,MySQL错误日志(hostname.err)中也会记录相关信息。另外,可以查询全局状态变量了解历史累计:
SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks';
该变量表示从服务启动以来发生的死锁总数。配合下述查询,可计算近期增长率:
| 变量名 | 含义 |
|---|---|
| Innodb_deadlocks | 累计死锁次数 |
| Innodb_row_lock_current_waits | 当前正在等待行锁的事务数 |
四、编写监控告警避免频繁死锁被忽略
在生产环境,建议将死锁监控接入告警系统。以下Python示例演示如何连接数据库并检测死锁增长:
import mysql.connector
conn = mysql.connector.connect(
host="127.0.0.1",
user="root",
password="your_password",
database="information_schema"
)
cursor = conn.cursor()
cursor.execute("SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks'")
result = cursor.fetchone()
deadlocks = int(result[1])
# 若deadlocks相比上次采集增长超过阈值则触发告警
print("当前累计死锁次数:", deadlocks)
cursor.close()
conn.close()
通过上述多种方式结合INNODB_STATUS日志,我们能够有效监控MySQL死锁是否频繁发生,并为后续优化事务顺序、调整索引提供可靠依据。
MySQL死锁监控INNODB_STATUS修改时间:2026-07-29 23:24:22