慢查询日志的配置是开启性能诊断的第一步。合理配置不仅能捕获问题 SQL,还能避免日志爆炸拖累系统。下面从核心参数、输出目标、过滤规则、轮转策略以及 8.0 增强等维度,为你详细拆解。
⚙️ 一、核心配置参数详解
以下是 my.cnf 中 [mysqld] 段的主要慢查询参数,均支持动态修改(SET GLOBAL)。
| 参数 | 说明 | 默认值 | 推荐设置与备注 |
|---|---|---|---|
slow_query_log |
是否开启慢查询日志 | OFF |
生产必须 ON,开销极低 |
slow_query_log_file |
日志文件路径 | host_name-slow.log |
建议指定绝对路径,如 /var/log/mysql/slow.log,确保 MySQL 用户有写权限 |
long_query_time |
慢查询阈值(秒),执行时间超过此值的 SQL 会被记录 | 10 |
OLTP 可设 0.1 ~ 1.0,精确到微秒(支持小数)。设置为 0 记录所有查询(仅调试用) |
log_output |
日志输出目标 | FILE |
可设为 FILE、TABLE 或 FILE,TABLE。生产建议 FILE,分析时可临时改为 TABLE |
log_queries_not_using_indexes |
是否记录未使用索引的查询 | OFF |
开启后可能产生大量日志,建议配合 min_examined_row_limit 使用。仅用于优化阶段 |
log_throttle_queries_not_using_indexes |
限制每分钟记录"未使用索引"查询的最大条数 | 0(无限制) |
配合 log_queries_not_using_indexes=ON 防止日志风暴,例如设为 10 |
min_examined_row_limit |
扫描行数超过此值才记录 | 0 |
设为 1000 等,过滤掉扫描很少行但偶尔慢的查询,与 log_queries_not_using_indexes 协同 |
log_slow_admin_statements |
是否记录 DDL 语句(如 ALTER TABLE) |
OFF |
根据需要开启,DDL 通常较慢 |
log_slow_replica_statements |
(8.0.26+) 从库是否记录复制过来的慢 SQL | OFF |
旧版为 log_slow_slave_statements,排查从库延迟时开启 |
log_slow_extra |
(8.0.14+) 记录额外详细信息 | OFF |
强烈建议 ON ,会输出 Thread_id、Rows_examined、Bytes_sent 等关键字段 |
log_timestamps |
日志时间戳的时区 | UTC |
可选 SYSTEM,建议统一为 UTC 便于跨时区分析 |
🔧 二、如何设置:动态修改与配置文件持久化
1. 运行时动态设置(立即生效,重启失效)
sql
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 0.5;
SET GLOBAL log_slow_extra = ON;
SET GLOBAL log_output = 'FILE';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
注意 :
slow_query_log_file动态修改后,需要关闭再开启slow_query_log才会切换到新文件。
2. 配置文件持久化(重启后保留)
ini
[mysqld]
slow_query_log = ON
long_query_time = 0.5
slow_query_log_file = /var/log/mysql/slow.log
log_output = FILE
log_slow_extra = ON
min_examined_row_limit = 1000
log_queries_not_using_indexes = ON
log_throttle_queries_not_using_indexes = 10
📤 三、日志输出目标配置
通过 log_output 控制输出到哪里:
| 值 | 说明 | 适用场景 |
|---|---|---|
FILE |
写入文件系统,路径由 slow_query_log_file 指定 |
生产环境首选,性能开销极小 |
TABLE |
写入 mysql.slow_log 表 |
方便实时 SQL 查询分析,但会产生额外写入负载,高并发慎用 |
FILE,TABLE |
同时写入文件和表 | 调试期或仅短期开启表记录 |
当使用 TABLE 输出时,可以直接查询:
sql
SELECT * FROM mysql.slow_log WHERE query_time > 1 ORDER BY start_time DESC LIMIT 10;
但 slow_log 表默认使用 CSV 引擎,不支持索引,大量写入可能成为瓶颈。可将其转换为 MyISAM 或 InnoDB(但需承担相应锁风险)。
🧹 四、过滤规则:避免记录无价值的查询
1. min_examined_row_limit
- 目的:忽略那些扫描行数极少,却因锁等待等原因偶然变慢的查询。
- 示例 :
SET GLOBAL min_examined_row_limit = 1000;只有当Rows_examined >= 1000时,才可能被记录。 - 适用 :与
log_queries_not_using_indexes搭配,防止全表扫小表也被记入。
2. log_queries_not_using_indexes 与节流
- 开启后,任何未使用索引的查询即使执行时间低于
long_query_time也会被记录。 - 搭配
log_throttle_queries_not_using_indexes限制每分钟最多记录条数,避免日志爆炸。
3. 管理语句与复制过滤
log_slow_admin_statements = ON记录 DDL。log_slow_replica_statements = ON在从库上记录主库同步过来的慢 SQL,便于定位复制延迟中的慢查询。
📋 五、日志内容格式(8.0 增强)
开启 log_slow_extra=ON 后,每条慢查询会包含详细字段,示例:
text
# Time: 2025-06-27T08:15:23.456789Z
# User@Host: app_user[app_user] @ db1 [10.0.0.5]
# Thread_id: 45 Schema: ecommerce QC_hit: No
# Query_time: 2.234567 Lock_time: 0.000123 Rows_sent: 20 Rows_examined: 50000
# Rows_affected: 0 Bytes_sent: 2048
SET timestamp=1718470523;
SELECT * FROM orders WHERE user_id=10086 ORDER BY create_time DESC LIMIT 20;
关键字段解读:
Query_time:总耗时(秒),是索引优化的首要指标。Rows_examined:扫描行数,与Rows_sent比例悬殊时说明索引效率低。Thread_id:可关联 Performance Schema 分析线程状态。Lock_time:仅包含表锁和元数据锁时间 ,InnoDB 行锁等待时间包含在Query_time中但不单独显示。
🔄 六、日志轮转与管理
慢查询日志会持续增长,需要定期切分归档。
1. 手动刷新日志文件
bash
mysqladmin -u root -p flush-logs
或 SQL:
sql
FLUSH LOGS;
执行后 MySQL 会关闭当前日志文件并重命名为带序号的后缀,然后创建新文件。
2. 配合 logrotate
在 /etc/logrotate.d/mysql 中配置:
/var/log/mysql/slow.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
create 640 mysql mysql
postrotate
/usr/bin/mysqladmin -u root -p'your_password' flush-logs
endscript
}
实现每日轮转,压缩保留 7 天。
⚡ 七、性能影响评估
- 开启慢查询日志的 CPU 开销极小:每条语句执行完只需比对时间和判定条件,几乎无感。
- 文件写入:顺序追加,影响远低于错误日志。
- 表记录 :
TABLE方式会增加写入压力,建议高并发环境仅用FILE。 log_queries_not_using_indexes若不加节流,可能导致日志量激增,磁盘 I/O 上升,务必同时设置log_throttle_queries_not_using_indexes和min_examined_row_limit。
💎 八、生产环境推荐配置示例
ini
[mysqld]
# ===== 慢查询日志 =====
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0.5
log_output = FILE
log_slow_extra = ON
# 辅助过滤
min_examined_row_limit = 1000
log_queries_not_using_indexes = ON
log_throttle_queries_not_using_indexes = 10
# 记录管理语句和复制慢查询
log_slow_admin_statements = ON
log_slow_replica_statements = ON
# 时间戳时区
log_timestamps = UTC
重启 MySQL 后生效,同时结合 pt-query-digest 等工具定期分析日志文件,形成"配置 → 捕获 → 分析 → 优化"的闭环。
总结 :慢查询日志配置的精髓在于按需开启、精准过滤、安全存储 。合理使用 long_query_time、min_examined_row_limit、节流机制和 log_slow_extra,能让你在不影响系统性能的前提下,持续收集到真正有价值的慢 SQL,为后续索引优化和 SQL 改写提供坚实依据。