mysql数据库中的错误日志与慢查询日志分析

来源:这里教程网 时间:2026-02-28 20:45:10 作者:

如何确认 MySQL 是否启用了错误日志和慢查询日志

MySQL 默认不一定开启这两类日志,尤其慢查询日志默认是关闭的。直接查

SHOW VARIABLES LIKE '%log%'
可能返回一堆配置,但关键就看这几个:

log_error
:显示错误日志路径(如
/var/log/mysql/error.log
),若为空或为
NULL
,说明错误日志未启用(常见于 MySQL 8.0+ 的 systemd 管理模式,日志可能走系统 journal)
slow_query_log
:值为
OFF
表示慢查询日志关闭;
ON
才启用
slow_query_log_file
:慢日志文件路径,若未显式设置,MySQL 会按数据目录 + 主机名生成默认路径(如
/var/lib/mysql/hostname-slow.log
long_query_time
:判定“慢”的阈值(单位秒),默认是
10.000000
,生产环境建议调低到
1.0
0.5

注意:

log_output
决定日志输出方式,
FILE
写文件,
TABLE
写入
mysql.slow_log
表(需同时启用
slow_query_log
),
TABLE
方式方便 SQL 查询分析,但有性能开销且不记录非查询语句(如
SET
DELIMITER
)。

错误日志里哪些内容必须立刻关注

错误日志不是用来“定期翻阅”的,而是出问题时第一排查入口。以下几类信息出现即需人工介入:

Aborted connection
:频繁出现说明客户端异常断连,可能是网络抖动、超时设置不合理(如
wait_timeout
太小),或应用未正确 close 连接
Out of memory
Cannot allocate memory
:不是 MySQL 内存配额超了,很可能是系统级 OOM killer 杀掉了 mysqld 进程,要查
dmesg -T | grep -i "killed process"
InnoDB: Database page corruption
Failed to read from the .ibd file
:物理页损坏,立即停止写入,用
innodb_force_recovery
尝试导出数据
Plugin 'validate_password' is disabled
类提示:不是错误,但说明插件加载失败,若依赖该插件做密码策略,实际策略并未生效

不要被大量

Starting crash recovery
Shutdown completed
刷屏干扰——只要不是高频重启,这些属于正常启停日志。

慢查询日志分析的实用命令与过滤技巧

直接

cat
tail -f
看原始日志效率极低。优先用官方工具
mysqldumpslow
或结构化处理:

统计最慢的 10 条语句:
mysqldumpslow -s t -t 10 /var/lib/mysql/hostname-slow.log
统计访问次数最多的 10 条:
mysqldumpslow -s c -t 10 /var/lib/mysql/hostname-slow.log
只看锁定时间超过 2 秒的:
mysqldumpslow -s l -t 10 -g "Lock_time: [2-9]" /var/lib/mysql/hostname-slow.log
如果日志是
TABLE
方式存储,可直接 SQL 分析:
SELECT query_time, lock_time, rows_sent, rows_examined, sql_text FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;

注意:

mysqldumpslow
会自动归并带不同参数的相同语句(如
WHERE id = 1
WHERE id = 2
都算作
WHERE id = N
),但无法识别函数或子查询变化,真实场景中仍需结合
pt-query-digest
做深度分析。

为什么开了慢日志却没记录明显慢的查询

常见原因不是配置漏了,而是语义或执行路径不符合记录条件:

查询在从库执行,但
log_slow_slave_statements
OFF
(MySQL 5.7+ 默认关)
语句被优化器重写后实际执行很快(如命中覆盖索引,
rows_examined
很小),但
query_time
仍超阈值——此时
long_query_time
是按实际执行耗时判断的,不受扫描行数影响
使用了
SQL_NO_CACHE
SQL_CACHE
提示,但 MySQL 8.0 已移除查询缓存,这类语句会被跳过日志记录
客户端连接设置了
long_query_time=0
(会话级覆盖全局),但该会话后续又执行了
SET long_query_time=10
,导致部分查询漏记

最隐蔽的一点:如果查询触发了隐式类型转换(比如

WHERE phone = 13800138000
,而
phone
VARCHAR
),优化器可能放弃索引,但
query_time
未必超限——这类问题不会出现在慢日志里,得靠
EXPLAIN
或 Performance Schema 抓。

相关推荐