用mysqlslow配合Python提取慢查最稳:指定完整路径调用,用--sort=at--top=50-v获取排序后前50条,清理换行和空格;不可用时再正则逐行状态机解析,pandas聚合分析P95、SQL摘要和分钟级趋势,inode+偏移防轮转重复。

如何用 mysqlslow 配合 Python 做基础慢查提取
直接调用 MySQL 自带的 mysqlslow 工具比从头解析日志更稳——它已处理好时间戳格式、SQL 截断、参数归一化等细节。Python 只需用 subprocess.run 调起并捕获输出,避免自己写正则去匹配不规范的日志行。
常见错误是忽略 mysqlslow 的路径和权限:它通常不在 $PATH 中,需指定完整路径(如 /usr/bin/mysqlslow);且日志文件需对运行用户可读。
- 用
--sort=at按平均查询时间排序,--top=50取前 50 条高频慢查 - 加
-v参数输出详细 SQL,但注意会包含注释和换行,后续需用strip()和replace('\n', ' ')清理 - 若日志含微秒级时间(MySQL 8.0+ 默认),
mysqlslow可能报错Invalid date format,此时加--verbose或降级用mysqldumpslow(兼容性更好)
如何用正则从原始 slow log 文件中提取关键字段
当 mysqlslow 不可用或需定制字段(比如提取客户端 IP、线程 ID),就得手动解析。MySQL 慢日志格式不统一:5.7 用 # 开头的注释行标记元信息,8.0+ 支持 JSON 格式,但默认仍是传统文本。别用单一大正则匹配整条记录,容易漏掉跨行 SQL。
正确做法是逐行扫描,用状态机方式识别段落:
立即学习“Python免费学习笔记(深入)”;
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
- 遇到
# Time:行,提取后 6 字段为timestamp(注意时区,日志里是服务器本地时间) - 遇到
# User@Host:行,用re.search(r'User@Host: (\w+)\[\w+\] @ (\S+) \[(\S+)\]', line)提取用户名、主机名、IP - 遇到
# Query_time:行,用re.findall(r'(\w+): ([\d.]+)', line)批量提取Query_time、Lock_time、Rows_sent等 - SQL 体从下一个非
#行开始,持续到下一个# Time:或 EOF —— 这里最容易丢数据,务必用while循环累积,而非只取下一行
如何用 pandas 快速聚合分析慢查模式
原始日志条目数动辄上万,人工翻页无效。把关键字段(时间、耗时、行数、SQL 摘要)载入 pandas.DataFrame 后,几行代码就能定位问题:
- 用
df['Query_time'].quantile(0.95)看 P95 耗时,比平均值更能反映长尾问题 - 对
sql_digest(可用sqlparse.format(sql, strip_comments=True, reindent=True).split()[0:10]粗略生成)做value_counts(),快速发现重复高频慢查 - 加列
df['minute'] = pd.to_datetime(df['timestamp']).dt.floor('T'),再按分钟分组统计数量,能识别突发性慢查潮 - 注意:SQL 文本含特殊字符(如反斜杠、引号)时,
pd.read_csv(..., engine='python')比默认 C 引擎更容错
如何避免定时任务中日志轮转导致的重复分析
MySQL 的 log_rotation(如 mysqladmin flush-logs 或 logrotate)会让慢日志文件被重命名或清空。脚本若每次全量读取,可能重复告警或漏掉刚轮转走的日志。
可靠方案是记录分析位点,而非依赖文件名:
- 用
os.stat(log_path).st_ino记录 inode 号,配合上次读取的字节偏移(last_offset),下次从该位置继续读 —— 即使文件被重命名,只要没删,inode 不变 - 若日志被截断(truncate),
st_size会变小,此时需重置偏移为 0 并告警,不能静默跳过 - 把
{'inode': xxx, 'offset': yyy}存进本地 JSON 文件(如/var/run/mysql_slow_analyzer.state),注意加flock防止并发脚本冲突
真正难的不是解析 SQL,而是区分“偶发抖动”和“稳定劣化”——比如某条语句 P95 耗时从 200ms 慢慢爬到 800ms,但每天峰值都不同,需要至少 3 天连续数据才能确认趋势。别省略时间维度校准。

















