mysql慢查询日志需动态开启(set global slow_query_log = on)并设long_query_time(如1.0秒),指定slow_query_log_file路径,且默认不记录update/delete;解析推荐pt-query-digest而非mysqldumpslow;日志轮转须先关闭再重命名或用flush slow logs。

slow_query_log 怎么打开才真正生效
MySQL 的慢查询日志默认是关闭的,光改配置文件不重启或不动态启用,slow_query_log 就只是个摆设。很多线上环境配了但查不到慢 SQL,根本原因是没确认它是否真在写入。
- 动态开启(无需重启):
SET GLOBAL slow_query_log = ON;,但要注意:该命令只对新连接生效,当前会话不会记录自己执行的语句 - 必须同时设置
long_query_time,例如SET GLOBAL long_query_time = 1.0;(单位秒,支持小数),否则默认是 10 秒,大部分“慢”都漏掉了 - 日志路径由
slow_query_log_file控制,建议显式指定绝对路径(如/var/log/mysql/mysql-slow.log),避免 MySQL 自行拼接出错或权限不足 - 检查是否生效最直接的方式:
SHOW VARIABLES LIKE 'slow_query_log%';和SHOW VARIABLES LIKE 'long_query_time';
为什么开了 slow_query_log 却没记录 UPDATE/DELETE
默认情况下,MySQL 只记录 SELECT 语句到慢查询日志,UPDATE、DELETE、INSERT 等写操作不会被收录——这是很多人排查 DML 性能问题时踩的第一个坑。
- 要捕获所有慢语句,必须开启
log_queries_not_using_indexes并配合min_examined_row_limit,但这俩不是为 DML 设计的,仍不可靠 - 真正可行的办法是启用
general_log+ 过滤,但开销大,仅限临时诊断;生产环境更推荐用performance_schema.events_statements_summary_by_digest查聚合后的慢执行摘要 - 如果非要用慢日志抓写操作,5.7+ 可设置
log_output = 'TABLE'并查mysql.slow_log表,但注意该表默认是 CSV 引擎,插入性能差,且不自动清理
mysqldumpslow 解析慢日志总报错或结果不准
mysqldumpslow 是 MySQL 自带的分析工具,但对现代慢日志格式兼容性差,尤其遇到带毫秒精度的 long_query_time(如 0.1)、带注释的 SQL 或多行语句时,解析极易出错或合并失败。
- 常见错误信息:
Use of uninitialized value $arg in pattern match或统计数量明显少于实际行数 - 原因:它依赖正则硬匹配,无法处理反引号包裹的库表名、参数化后的占位符(如
WHERE id = ?)、以及新版日志中新增的Rows_examined字段位置偏移 - 替代方案:用
pt-query-digest(Percona Toolkit),它能准确解析各类格式,支持按指纹聚合、生成报告、输出到表,命令示例:pt-query-digest /var/log/mysql/mysql-slow.log - 注意:运行
pt-query-digest时,确保日志文件无并发写入(最好先FLUSH LOGS切一份副本再分析)
慢查询日志太大导致磁盘爆满怎么办
慢查询日志不会自动轮转,长期运行的服务可能几天就写满几十 GB,而 logrotate 直接切文件会导致 MySQL 继续往旧 fd 写,磁盘空间并不会释放。
- 正确做法是先让 MySQL 关闭当前句柄:
SET GLOBAL slow_query_log = OFF;,再用mv重命名日志,然后SET GLOBAL slow_query_log = ON;,它会新建文件 - 更稳妥的是用
FLUSH SLOW LOGS;(8.0.14+)或FLUSH LOGS;(全量刷新),但后者会影响其他日志,慎用 - 预防性配置:在 my.cnf 中加
log_error_verbosity = 2(减少冗余信息)、限制单条日志长度(max_long_query_time不可用,得靠应用层控制 SQL 长度),并定期用pt-query-digest --since做增量分析
真正的难点不在开关日志,而在于区分“哪些慢是偶发抖动、哪些是索引缺失、哪些是业务逻辑缺陷”。日志只是线索,不是答案。分析时别只盯 Query_time,Lock_time 和 Rows_examined 的比值往往更能说明问题。











