确认慢查询日志是否启用,需执行select @@global.slow_query_log返回1才真正开启;同时检查@@global.log_output是否含file或table,以及@@global.long_query_time阈值是否合理。

如何确认慢查询日志是否已启用
MySQL 8.0 默认关闭慢查询日志,直接查 slow_query_log 变量可能返回 OFF,不代表配置无效,只是没开。先执行:
SELECT @@slow_query_log, @@long_query_time, @@log_output;注意
@@log_output 的值——它决定日志写到哪,常见是 FILE(写入文件)或 TABLE(写入 mysql.slow_log 表),两者可同时启用,但不能只设为空。
设置 slow_query_log 和 long_query_time 的正确方式
这两个变量必须显式开启并赋值,仅改配置文件不生效(尤其在 Docker 或云数据库中常被忽略)。推荐用 SQL 动态设置(立即生效):
SET GLOBAL slow_query_log = ON;<br>SET GLOBAL long_query_time = 1.0;<br>SET GLOBAL log_output = 'FILE,TABLE';
-
long_query_time单位是秒,支持小数(如0.5),但精度受系统时钟限制,低于 0.1 秒实际意义不大 - 如果用
SET SESSION设置,只对当前连接生效,无实际价值 - 某些托管服务(如阿里云 RDS)禁止修改
GLOBAL变量,需走控制台参数模板
指定慢查询日志输出路径和格式
MySQL 8.0 不提供“自定义日志格式”选项,所谓“格式”实际由输出目标决定:
- 写入文件(
log_output = 'FILE')时,固定为文本格式,字段顺序固定:时间戳、用户、IP、线程ID、执行时长、锁等待时长、扫描行数、返回行数、SQL语句(末尾带换行) - 写入表(
log_output = 'TABLE')时,数据存进mysql.slow_log,字段含start_time、user_host、query_time、lock_time、rows_sent、rows_examined、sql_text等,可直接用 SQL 查询过滤 - 想导出结构化数据(如 JSON/CSV),必须后续用脚本解析文本日志或从
slow_log表 SELECT 导出
slow_query_log_file 控制,默认在数据目录下,如 /var/lib/mysql/hostname-slow.log;修改需 SET GLOBAL slow_query_log_file = '/path/to/slow.log';,且 MySQL 进程需有该路径写权限。
为什么开了日志却看不到新记录
常见原因不是配置错,而是条件不满足:
- SQL 执行时间未超过
long_query_time(注意:这个阈值对SELECT生效,但对INSERT/UPDATE/DELETE同样生效,只要执行久) - 客户端连接使用了
SQL_NO_CACHE或启用了 query cache(MySQL 8.0 已移除 query cache,这点可忽略) - 日志文件权限问题:MySQL 进程用户(如
mysql)无法写入指定路径,错误通常静默丢弃,检查mysqld.err日志里是否有Could not write to slow log类提示 - 使用了
log_output = 'TABLE'但忘了给mysql.slow_log表授权,或者该表被手动清空且未开启log_output回写
SLEEP(2) 强制触发:SELECT SLEEP(2);再查
mysql.slow_log 或翻日志文件末尾。
真正麻烦的是日志轮转和归档——MySQL 不自带 rotate 功能,slow_query_log_file 一旦指定就一直追加,文件会越来越大。生产环境务必配合外部工具(如 logrotate)做切割,并在 postrotate 脚本里执行 FLUSH SLOW LOGS 让 MySQL 换新文件句柄。











