上一篇 下一篇 分享链接 返回 返回顶部

MySQL死锁排查:日志抓取与诊断思路

发布人: 发布时间:1 天前 阅读量:2

死锁问题概述

MySQL死锁是指两个或多个事务相互等待对方释放锁资源,导致事务无法继续执行。在IDC高并发业务场景下,死锁虽常见但若处理不及时可能引发连锁故障。本文聚焦死锁日志的获取方法与排查流程,帮助运维人员快速定位根因。

开启死锁日志记录

默认情况下MySQL仅记录最后发生的死锁信息,建议通过以下配置记录所有死锁:

  • innodb_print_all_deadlocks=1:将每个死锁的详细信息输出到MySQL错误日志(error log)。
  • log_error:确认错误日志路径,例如 /var/log/mysql/error.log

配置生效后重启MySQL或使用 SET GLOBAL innodb_print_all_deadlocks=1;(MySQL 5.6+支持动态修改)。

抓取死锁日志的方法

方法1:从错误日志中提取

查看错误日志:tail -10000 /var/log/mysql/error.log,搜索关键字 "LATEST DETECTED DEADLOCK""DEADLOCK"。MySQL将输出每个死锁的事务ID、等待的锁、持有的锁以及事务的SQL语句。

方法2:使用SHOW ENGINE INNODB STATUS

执行 SHOW ENGINE INNODB STATUS\G,在输出中找到 LATEST DETECTED DEADLOCK 段。注意:该命令仅显示最近一次死锁,适合现场实时排查。配合 INNODB_TRXINNODB_LOCKS 等系统表可获取更全面的锁信息。

方法3:搭建死锁监控工具

使用 pt-deadlock-logger(Percona Toolkit)持续监控死锁并将记录写入表或文件:

  1. 安装Percona Toolkit
  2. 运行 pt-deadlock-logger --iterations=0 --dest D=test,t=fred u=root
  3. 分析记录的事务ID、等待时间、语句等。

排查死锁的通用思路

第一步:分析死锁日志

从日志中确定两个(或更多)事务,找出它们各自持有的锁等待的锁。重点关注:

  • 事务隔离级别:常见死锁在REPEATABLE READ下更易发生间隙锁冲突。
  • 索引使用情况:未使用索引的更新会导致全表扫描加锁,增加死锁概率。
  • SQL语句顺序:不同事务对同一组表的操作顺序不一致。

第二步:复现与验证

根据日志中的SQL和表结构,在测试环境构造类似并发请求。使用 SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; 监控事务状态。

第三步:优化方案

常见解决策略包括:

  • 统一访问顺序:所有事务按相同顺序操作表(如按主键升序)。
  • 减少锁范围:为高频更新字段建立索引,避免间隙锁。
  • 降低隔离级别:业务允许时使用READ COMMITTED以消除间隙锁。
  • 拆分长事务:缩短事务持有锁的时间。

总结

死锁排查的核心是抓全日志、分析锁冲突、反查SQL逻辑。推荐生产环境开启 innodb_print_all_deadlocks,并结合pt-deadlock-logger实现自动化监控。掌握以上思路可大幅缩短MTTR(平均修复时间),保障IDC数据库稳定性。

目录结构
全文
企业微信 企业微信
微信公众号 微信公众号
服务热线: 400-790-1688
电子邮箱: 3310008520@qq.com