mysql 8.0升级后mysqldumpslow解析失败,因log_slow_extra开启导致日志新增rows_examined、lock_time等键值对字段,而旧版工具无法识别,直接跳过整条记录;必须使用8.0+自带mysqldumpslow或pt-query-digest(≥3.5.0)解析。

MySQL 8.0 升级后,mysqldumpslow 直接解析慢日志大概率失效——不是你命令写错了,是日志格式本身变了,老工具压根不认识新字段。
为什么 mysqldumpslow 会跳过整条记录
MySQL 8.0 默认开启 log_slow_extra 后,慢日志新增了 # Rows_examined: 12345、# Lock_time: 0.000123 这类键值对行。而传统 mysqldumpslow(来自 MySQL 5.x 或早期包)只认旧格式,一碰到以 # 开头的非 # Time / # User@Host 行,就直接跳过当前语句块,甚至提前终止解析。
- 验证是否中招:
head -n 20 /var/log/mysql/mysql-slow.log | grep -E '^(# Rows_examined|# Lock_time)'—— 有输出就是已踩坑 - 别去关
log_slow_extra来“兼容”:这等于主动丢掉Rows_examined和锁等待时间,失去判断是否走索引、是否被锁拖慢的关键依据 - MySQL 8.0.22+ 自带的
mysqldumpslow才支持 extra 字段,但功能仍弱于pt-query-digest,比如不支持 P95 延迟统计或 JSON 导出
必须用 pt-query-digest 解析 8.0 日志
pt-query-digest 是目前唯一能正确处理 MySQL 8.0 微秒级 Query_time 和所有 log_slow_extra 字段的主流工具,但版本不能低。
- 最低要求:
pt-query-digest版本 ≥ 3.5.0;老版本(如 3.2.x)会把Query_time: 123456(微秒)当 0 处理,延迟统计全崩 - 基础解析命令:
pt-query-digest /var/log/mysql/8.0-slow.log—— 它自动识别格式,无需额外参数 - 若路径含空格或特殊字符,务必用引号包裹:
pt-query-digest "/var/log/mysql/production slow.log" - 想导出结构化数据用于比对(比如升级前后 P95 对比),加
--report-format=json或--output=profile,再用jq或 Python 脚本提取Query_time中位数、Rows_examinedP95 等字段
如何提取真正可比的慢查询样本
直接比“升级前 7 天 1200 行 vs 升级后 7 天 800 行”毫无意义——流量、缓存、业务节奏全不同。关键是要锁定同一业务上下文下的代表性语句。
- 优先从
mysql.slow_log表查(如果启用了log_output = TABLE):SELECT * FROM mysql.slow_log WHERE user_host LIKE '%order-service%' AND sql_text LIKE '%archive_order%'; - 用
pt-query-digest --filter '$event->{db} && $event->{db} eq "order_db"'限定数据库,避免跨库噪声 - 禁用
log_queries_not_using_indexes:否则升级后索引优化导致“未走索引”查询减少,会污染慢查基数,让对比失真 - 同一 SQL 模板下,重点看
Query_time的 P95(不是平均值)——长尾延迟恶化最易被均值掩盖
最常被忽略的一点:MySQL 8.0 的 long_query_time 是按微秒精度判断的,而 5.7 只支持秒级小数。设 long_query_time = 0.5 在 5.7 会被截断为 0,导致日志爆炸;在 8.0 则精确生效。升级后务必用 SELECT @@long_query_time; 确认实际值,别只信配置文件里的数字。











