Skip to main content

QA 监控死锁并实现自动报警

监控死锁并实现自动报警,通常有自建轻量级脚本借助Percona/pəˈrɑːnə/专业工具使用Prometheus+Grafana这几种主流方法。

⚙️ 方法一:自建轻量级脚本(灵活定制)

如果不想引入额外工具,可以通过Shell或Python脚本,轮询捕获死锁信息并触发告警。关键是监控MySQL错误日志,因为InnoDB会将死锁信息写入这里。

  1. 开启死锁日志 修改MySQL配置文件(my.cnf),开启 innodb_print_all_deadlocks。这样,每次发生死锁都会被完整记录在错误日志中(通常位于 /var/log/mysql/error.log)。

    [mysqld]
    innodb_print_all_deadlocks = ON
  2. 脚本逻辑与要点 脚本需要具备轮询、防重复和去噪的能力。

    • 实时监听 (tail -F):持续跟踪日志文件,用awk等命令提取完整的死锁信息块。
    • 去重防刷:为避免告警疲劳,应对死锁信息进行哈希(如md5sum)并记录,确保短时间内相同的死锁不重复告警。
    • 关键上下文:告警时必须提取并包含死锁中的SQL语句,否则DBA无法快速定位问题。

🛠️ 方法二:使用Percona Toolkit专业工具(稳定可靠)

pt-deadlock-logger 是Percona Toolkit中的利器,专门用于捕获和记录MySQL死锁。它持续轮询 SHOW ENGINE INNODB STATUS,解析出死锁信息,并提供输出到终端或保存到数据库表等多种展示方式。

使用示例

# 基本用法:监控本地MySQL,死锁时输出到终端
pt-deadlock-logger h=localhost,u=monitor_user,p='your_password'

# 高级用法:死锁记录持久化
pt-deadlock-logger h=localhost,u=monitor_user,p='your_password' \
--dest h=alert_host,D=deadlock_db,t=deadlock_log

在此基础上,你可以通过轮询--dest中指定的目标表,或解析STDOUT输出来触发告警。

📊 方法三:使用Prometheus+Grafana(现代化可观测)

构建现代化监控体系能够从指标、日志、链路等多个维度全面观测死锁。

  1. Prometheus指标:MySQL Exporter不会直接暴露死锁指标。你可以自定义Exporter(如通过文本文件收集pt-deadlock-logger的计数,再让Prometheus拉取),或使用pt-deadlock-logger --dest将死锁直接写入数据库表的方案。
  2. Loki日志告警:在Grafana Loki中配置告警规则,实时扫描MySQL错误日志,一旦发现"Deadlock found"等关键字就触发通知。
  3. 可视化与告警:在Grafana中构建仪表盘,关联Prometheus(死锁发生次数)和Loki(详细死锁日志),实现从“有无”到“根源”的全链路追踪。

🚨 如何通知相关人员?

一旦脚本发现死锁,必须立即通知相应人员。

  • 即时通讯(钉钉/企业微信/飞书):通过调用Webhook API,将包含死锁SQL、时间、数据库等信息的告警发送到群聊。
  • 邮件:传统但可靠,通过mail命令或SMTP库将格式化后的内容批量发送至指定邮箱列表。
  • 运维平台(PagerDuty/云监控):集成运维平台,利用其值班表和升级策略,确保告警能被及时响应。

💎 总结与实践建议

方法核心机制适用场景
轻量级脚本轮询解析日志 / pt-deadlock-logger,触发Webhook/邮件中小团队,希望快速、免费、灵活部署
专业工具pt-deadlock-logger 精准采集,对接监控平台标准化的运维环境,Percona用户
Prometheus+Grafana指标(计数)+ 日志(Loki)联合分析已构建Prometheus生态,追求统一可观测性

对于大多数团队而言,从方法一(轻量级脚本) 开始是最高效的选择。你可以将pt-deadlock-logger集成进简单的Python脚本,设置一个crontab任务每分钟执行一次来触发告警。当团队和监控体系成熟后,再逐步演进到方法三。

在完成了监控与报警的搭建后,死锁问题就进入了“可观测”和“可管理”的阶段。接下来,你是想进一步了解如何分析这些捕获到的死锁日志以定位根本原因,还是想针对具体业务场景优化SQL和索引?告诉我你的下一步需求,我可以继续为你深入拆解。