错误日志只记录mysql启动、运行、关闭中的严重问题(如启动失败、innodb恢复异常),不记录sql执行过程;查询日志全量记录所有客户端请求(含连接、sql、断开),用于审计但性能代价高;慢查询日志专为性能优化设计,仅记录执行超时语句,需重点关注lock_time和rows_examined;binlog是逻辑变更日志,用于复制和恢复,与诊断类日志无重叠。

错误日志只记“出事了”,不记正常操作
错误日志(error log)是 MySQL 启动、运行、关闭过程中发生严重问题时的“事故报告”,比如 mysqld 启动失败、InnoDB 恢复异常、权限校验崩溃、磁盘满写入失败等。它**不记录任何 SQL 语句执行过程**,哪怕一条 SELECT 1 执行出错(如因 OOM 被 kill),也只会记成类似 Got an error reading communication packets 这类底层通信异常,而非你写的那条 SQL。
关键点:
-
log_error控制路径,默认常为/var/log/mysqld.log或/var/lib/mysql/hostname.err,必须有 MySQL 进程可写权限 - 它是唯一默认开启的日志,且无法关闭(仅能重定向或丢弃到
/dev/null,但不推荐) -
log_error_verbosity决定记录级别(1=ERROR,2=WARNING+ERROR,3=INFO+WARNING+ERROR),生产环境建议设为 2,避免 INFO 级别刷屏 - 时间戳默认不开启(
log_error_includes_timestamp=OFF),务必打开,否则排查多条错误时会抓瞎
查询日志记“所有请求”,连连接断开都写进去
查询日志(general query log)是全量审计型日志:客户端连上来、发了什么 SQL(包括 SELECT、SHOW、SET)、甚至断开连接,全部原样记录。它不是为了查错,而是为了“还原现场”——比如开发说“我明明没改数据”,你翻日志发现他执行了 UPDATE ... WHERE id=1 却忘了加条件。
但它代价极高:
- 每条语句触发一次磁盘 I/O(即使
log_output=TABLE,写入mysql.general_log表仍需刷盘) - 默认关闭,开启后 QPS 下降明显,高并发场景可能直接拖垮性能
- 日志体积爆炸快,
general_log_file若不配轮转或定期清理,几天就能占满磁盘 - 敏感信息裸露:密码若在
SET PASSWORD里、token 若在注释中,全都会明文记下
慢查询日志才是性能优化的“真眼”
很多人误把查询日志当性能分析工具,其实它太重又太杂;真正该盯的是慢查询日志(slow query log)。它只记录执行时间 ≥ long_query_time 的语句(默认 10 秒),且可精确到微秒(MySQL 5.7+ 支持 long_query_time=0.1)。
实操注意:
- 必须手动开启:
slow_query_log=1,否则永远为空 -
long_query_time是**语句实际执行耗时**,不含排队、网络延迟;想抓锁等待高的语句,得配合log_queries_not_using_indexes=ON - 存储方式选
FILE还是TABLE?文件更轻量,但SELECT * FROM mysql.slow_log查起来方便;不过表模式默认不带索引,查历史得先ALTER TABLE mysql.slow_log ADD INDEX (start_time) - 别只看
Query_time,重点看Lock_time(锁等待)和Rows_examined(扫描行数),前者高说明有锁争用,后者高说明缺索引或写了SELECT *
二进制日志(binlog)根本不在一个维度上
binlog 不是“诊断日志”,而是“变更流水账”:它只记 DDL(CREATE、ALTER)和 DML(INSERT、UPDATE、DELETE),且是逻辑日志(SQL 或行变更事件),用于主从复制和基于时间点的恢复。它和错误日志、查询日志完全不重叠——错误日志不会告诉你 binlog 写失败了哪一行,查询日志也不会显示 binlog 记了什么。
容易混淆的点:
- binlog 默认 MySQL 8.0+ 开启,但错误日志里若出现
Failed to open log file,八成是log_bin路径磁盘满或权限不对,而不是 error log 本身出问题 -
binlog_format=ROW时,binlog 体积远大于STATEMENT,但能规避函数不确定性问题;而错误日志里若频繁报Could not execute Write_rows event,大概率是主从表结构不一致 - 清 binlog 用
PURGE BINARY LOGS,千万别用rm -f直删文件,否则 MySQL 会卡死或复制中断
真正要动手配日志时,先问自己:是要定位启动失败(只看 log_error),还是要审计谁删了数据(开 general_log 但限定时间窗口),还是想压测后找瓶颈(开 slow_query_log 并调低 long_query_time)——日志不是越多越好,是刚好够用,且留痕可控。











