4.2.1 慢查询⽇志配置

慢查询日志的配置是开启性能诊断的第一步。合理配置不仅能捕获问题 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 可设为 FILETABLEFILE,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_idRows_examinedBytes_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_indexesmin_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_timemin_examined_row_limit、节流机制和 log_slow_extra,能让你在不影响系统性能的前提下,持续收集到真正有价值的慢 SQL,为后续索引优化和 SQL 改写提供坚实依据。