应通过自增id游标轮询mysql.slow_log表,结合钉钉markdown聚合告警,并确保MySQL权限、PyMySQL依赖及慢日志实际有数据。

如何从 MySQL 的 slow_log 表中实时提取慢查询记录
MySQL 5.7+ 默认将慢查询日志写入 mysql.slow_log 表(需开启 log_output = 'TABLE'),比文件解析更稳定、易权限控制。直接查表比 tail -f 日志文件更适合脚本长期运行。
关键配置检查项:
- 确认已执行
SET GLOBAL log_output = 'TABLE';,且long_query_time已设为合理阈值(如1.0) -
slow_log表默认无索引,需手动为start_time加索引提升查询效率:ALTER TABLE mysql.slow_log ADD INDEX idx_start_time (start_time); - 脚本首次运行时,用
SELECT MAX(start_time) FROM mysql.slow_log记录初始水位,后续轮询只查大于该时间的记录
Python 脚本如何避免重复告警和漏报
轮询查表时,仅靠 start_time > last_check_time 仍可能漏掉同一秒内多条记录(MySQL 时间精度为秒),或因脚本重启导致水位丢失。必须引入唯一性锚点。
推荐做法:
- 用
SELECT id, start_time, sql_text, query_time FROM mysql.slow_log WHERE start_time >= %s ORDER BY id ASC,以自增id为主键游标 - 每次成功处理后,将本次最大
id写入本地文件(如/tmp/slowlog_cursor),而非依赖时间戳 - 若某次查询返回空,不更新 cursor;若非空,取结果末尾的
id更新 cursor —— 这能保证每条记录只被消费一次
钉钉机器人发送告警时怎么带格式又不被限流
钉钉 Webhook 对同一机器人 1 秒内最多接收 20 条消息,且纯文本易被忽略。用 markdown 类型 + 关键字段高亮更有效,但要注意转义和长度限制。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
实操要点:
- POST 到钉钉地址时,
Content-Type必须为application/json,body 中msgtype设为"markdown" -
sql_text含换行和特殊字符,发送前需用re.sub(r'([\`*_])', r'\', sql)简单转义,再截断前 500 字符(钉钉 markdown 正文上限约 2000 字符,但过长会折叠) - 每条告警附上
query_time和lock_time,用**耗时:{q}s**加粗显示;超过 5s 的自动加❗前缀 - 不要每条慢查都发一条消息 —— 可聚合 30 秒内所有记录,合并为单条 markdown 消息发送,降低频率又保信息密度
脚本部署后为什么没反应?几个硬性依赖要手动确认
常见静默失败原因不是代码逻辑,而是环境权限和配置缺失:
- MySQL 用户必须有
SELECT权限在mysql.slow_log表,且不能是localhost限定 —— 容器或远程部署时要用'user'@'%'或具体 IP - Python 需安装
PyMySQL(非mysql-connector,后者对mysql系统库支持不稳定),命令是pip install PyMySQL - 钉钉机器人必须在群设置中开启「自定义机器人」并勾选「我已阅读并同意…」,否则返回
errcode: 310000 - 脚本建议用
nohup python3 monitor_slowlog.py &启动,并重定向 stdout/stderr 到日志文件,否则终端关闭即退出
最易被忽略的是 slow_log 表本身是否真有数据 —— 执行 SELECT COUNT(*) FROM mysql.slow_log LIMIT 1 看返回是否 > 0,空表时脚本永远不触发告警,不是 bug 是预期行为。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










