
很多做后端开发、运维或者数据库管理的人遇到MySQL 出问题了时第一反应往往是重启试试或者翻代码。但真正定位问题最快的方式其实是先看日志。我自己的习惯是任何数据库异常先花 5 分钟翻日志通常就能确定七八成的方向。别说你从没看过很多人所谓的看日志其实就是打开错误日志文件拖到最后看两眼这完全不够。这篇我系统梳理一下 MySQL 日志体系的完整查看方法从错误日志、通用查询日志、慢查询日志到 binlog把在哪里看、怎么看、看完怎么用讲清楚。文章覆盖 MySQL 5.7 和 8.0 两个主流版本面向从没碰过日志的新手也面向想看深一点的进阶者。内容全部基于我实际踩过的坑和日常运维经验直接照着操作就行。1. MySQL 日志体系全景先搞清楚到底有哪些日志很多人觉得 MySQL 日志就是日志两个字其实 MySQL 的日志体系有五大类职责完全不同。不看日志可能还好一旦需要排查问题搞混日志类型是最大的坑。1.1 五大日志类型及职责划分错误日志error log记录 MySQL 启动、运行、停止过程中的关键事件和错误信息。比如配置文件加载失败、InnoDB 崩溃恢复、权限问题、端口被占用。排查启动失败和严重故障时最先看。通用查询日志general query log记录客户端所有的 SQL 语句和连接/断开事件。信息最全但性能开销巨大生产环境默认关闭只有在调试特定应用问题或追踪恶意 SQL 时才临时开启。慢查询日志slow query log记录执行时间超过阈值的 SQL 语句以及未使用索引的查询。这是优化 SQL 性能的第一利器也是排查接口响应慢、数据库 CPU 飙升的重要依据。二进制日志binlog记录所有引起数据变更的事件INSERT、UPDATE、DELETE 等用于主从复制和数据恢复。这是数据安全的重要保障。事务日志redo log undo log这两个属于 InnoDB 存储引擎内部日志redo log 保证崩溃后数据不丢crash recoveryundo log 用于事务回滚和 MVCC 多版本控制。平时主要通过SHOW ENGINE INNODB STATUS和性能监控间接查看很少直接读文件。1.2 各日志类型快速对比表日志类型主要用途默认状态查看难度对性能影响错误日志启动故障、运行错误开启容易极小通用查询日志完整 SQL 审计跟踪关闭容易极大生产慎开慢查询日志SQL 性能优化关闭5.7 后部分默认开较易低二进制日志复制、恢复取决于配置中等中等redo/undoInnoDB 内部机制自动管理困难间接查看无额外影响我的建议很简单错误日志时刻都要看慢查询日志一定要开binlog 必须配好通用查询日志只在紧急排查时临时用。搞清楚每类日志的定位后面查问题就不会抓瞎。2. 核心查看方法实战命令与文件操作详解先说说日志文件在哪里。我用过的生产环境里日志路径五花八门——有人放在/var/log/mysql/有人放在 MySQL 数据目录下还有人自定义路径。与其猜不如先用 SQL 查。进入 MySQL 命令行客户端执行SHOW VARIABLES LIKE log_error; SHOW VARIABLES LIKE general_log_file; SHOW VARIABLES LIKE slow_query_log_file;这是一个非常核心的思路用一个统一的查变量的方式去确认当前实例所有日志的真实路径比记忆默认路径可靠得多。我之前接手一个项目前一个 DBA 把日志目录指到了/home/mysql/logs如果按照默认路径去找永远看不到任何日志。2.1 错误日志启动异常和运行故障的第一现场错误日志是排查一切问题的基础。当 MySQL 启动失败、出现未知异常、主从切换失败等突发情况时第一件事必须是看错误日志。查看方式一SQL 查询变量确认路径-- 查看错误日志路径 SHOW VARIABLES LIKE log_error; -- 查看错误日志是否开启MySQL 5.7 后 SHOW GLOBAL VARIABLES LIKE log_error_verbosity;log_error_verbosity参数控制日志的详细程度值有 1、2、3。1 只记录错误信息2 记录错误和警告3 最详细还会记录一些注意级信息。排查问题期间建议临时调到 3能获得更多线索排查完记得调回 2因为最详细级别在极端情况下也会刷大量日志占用磁盘。查看方式二直接用系统命令读取文件日志文件本质就是文本文件Linux 下用习惯的tail命令# 查看最后 50 行错误日志 tail -n 50 /var/log/mysql/error.log # 持续跟踪输出最新日志类似实时滚动 tail -f /var/log/mysql/error.log # 按关键字过滤 grep -i error /var/log/mysql/error.log # 分页查看完整内容 less /var/log/mysql/error.log我是一个特别爱用tail -f的人。比如启动 MySQL 遇到问题我会开一个终端窗口先执行tail -f /var/log/mysql/error.log然后另一个终端执行systemctl start mysqld启动过程中的所有失败原因都会实时滚动出来。这样排查启动问题效率极高一次就能看到报错的前因后果比反复重启反复翻日志强太多了。注意生产环境执行tail -f之前先确认你的 SSH 终端不会断连。如果连接不稳定建议用screen或tmux工具开一个会话防止断连导致终端卡死特别是长时间观察日志的场景。2.2 通用查询日志什么 SQL 都逃不过的眼睛通用查询日志会把每一个连接上来的客户端执行的每一条 SQL 原样记录下来包括只读的 SELECT、事务的 BEGIN 和 COMMIT甚至连接和断开本身也被记录。它的作用是已知问题需要复现、捕获应用发出的具体 SQL 语句时很有价值代价是写入量大。开启方法临时开启排查完务必关闭-- 查看当前状态 SHOW VARIABLES LIKE general_log; -- 开启通用查询日志动态生效不需重启 SET GLOBAL general_log ON; -- 查看输出文件路径 SHOW VARIABLES LIKE general_log_file;开启后应用产生的所有 SQL 都会实时写入general_log_file指定的文件。我之前排查过一个诡异问题线上有个接口偶发超时代码里明明没写慢 SQL但就是偶发卡顿。后来临时开启通用查询日志才发现某个定时任务每 5 分钟会执行一次全表扫描的SELECT COUNT(*) FROM huge_table跟正常业务的 SQL 挤在一起导致偶发锁竞争。不开通用日志这种会话级别的偶发问题几乎不可能定位。查看方式# 实时跟踪通用查询日志 tail -f /path/to/general.log # 查看某个客户端 IP 的相关 SQL grep 192.168.1.100 /path/to/general.log # 查看包含特定表名的查询 grep SELECT \* FROM orders /path/to/general.log使用禁忌生产环境不要长时间开启。通用查询日志的写入开销远超想象我之前测试过一个 MySQL 8.0 实例开启后 TPS 直接下降 20% 左右在低配机器上更严重。用完立刻关闭SET GLOBAL general_log OFF;千万别忘了清空日志文件。如果文件已经变得特别大先SET GLOBAL general_log OFF再清空文件或删除重建最后重新开启。2.3 慢查询日志SQL 性能优化最实用的日志慢查询日志是 DBA 和开发者日常接触最多的性能日志。它的核心价值在于直接告诉