错误日志是排障第一现场,记录mysql启动失败、连接被拒等关键错误;binlog用于主从复制和时间点恢复;慢日志捕获超时sql;redo log保障崩溃恢复;undo log支撑mvcc和事务回滚。

错误日志(error log)是排障第一现场
MySQL一启动失败、连接被拒、表损坏或磁盘写满,错误日志里立刻有记录。它不像其他日志可开关,只要MySQL在跑,就默认写入——这是你查“为什么连不上”“为什么服务起不来”的第一站。
常见错误现象:Can't start server: Bind on TCP/IP port(端口被占)、Table 'xxx' is marked as crashed(表损坏)、Out of memory(OOM)。这些不会出现在慢日志或binlog里,只在这里。
实操建议:
- 用
SHOW VARIABLES LIKE 'log_error';查日志路径,别猜/var/log/mysql/error.log或/var/lib/mysql/hostname.err - 日志不自动轮转,生产环境务必配
log_error_services = 'log_filter_dragnet; log_sink_syseventlog'(MySQL 8.0.30+)或用外部工具(如logrotate)切分,否则单文件可能涨到几十GB - 别依赖
tail -f实时盯屏——MySQL崩溃时可能来不及刷盘,要加sync_log=ON(仅限调试,性能敏感场景慎开)
二进制日志(binlog)不是备份,但没它就做不了时间点恢复
binlog 记的是“做了什么”,不是“数据长什么样”。它不记录 SELECT,只记 DML(INSERT/UPDATE/DELETE)和 DDL(CREATE/ALTER),是主从复制和基于位置的恢复(PITR)唯一依据。
容易踩的坑:
-
sql_log_bin=OFF会跳过当前会话的所有 binlog 写入——执行误删语句前关了它,等于自废恢复武功 - 格式选错:用
STATEMENT遇上NOW()、RAND()、UUID(),主从数据必然不一致;ROW安全但体积大,批量 UPDATE 百万行可能生成几百MB日志 - 过期配置
binlog_expire_logs_seconds是按写入时间算,不是按文件名序号——重启频繁的测试库,旧日志可能早被删光,别等出事才查
慢查询日志(slow query log)不是性能报告,而是SQL问题的原始证据链
它不分析原因,只忠实记录超时的语句+执行计划基础信息(如是否用了索引、扫描行数)。真正价值在于:把“这个接口变慢了”和“某条SQL执行了12.7秒”建立确定性关联。
使用场景与注意点:
- 阈值
long_query_time默认是10秒,线上建议调成1或0.5;设为0可捕获所有查询,但IO压力陡增,仅限短时诊断 - 日志输出方式影响排查效率:
log_output='FILE'适合 grep + mysqldumpslow 分析;log_output='TABLE'(写入mysql.slow_log)方便 SQL 统计,但表结构无索引,查历史数据极慢 - 记得开
log_queries_not_using_indexes=ON——很多“不慢”的SQL其实正在全表扫描,只是数据量小没暴露,这是隐形性能债
重做日志(redo log)和回滚日志(undo log)不在磁盘目录里,但决定你敢不敢关机
它们是InnoDB引擎私有日志,不归MySQL Server管,也不在 datadir 下以明文文件存在(ib_logfile0/1 是 redo,ibdata1 里混存 undo)。你感知不到它们,除非遇到崩溃恢复失败或长事务卡住 purge 线程。
关键事实:
- redo log 保证 crash-safe:事务提交时只要写入 redo(刷盘或仅进 OS cache),断电重启也能重放;但它不负责主从同步,那是 binlog 的事
- undo log 不是“用来回滚的快照”,而是MVCC多版本读的基础——
SELECT要读历史版本时,靠的就是它;长事务不提交,undo 日志不能回收,ibdata1就会持续膨胀 - 别手动删
ib_logfile*!MySQL 启动时校验 size 和 checkpoint,删了轻则拒绝启动,重则数据页损坏
真正复杂的从来不是“怎么开日志”,而是理解每种日志的职责边界——比如 binlog 能恢复到秒级,但救不了误 drop 的表;redo log 能保事务不丢,但救不了被覆盖的 binlog 文件。日志不是万能胶,是分工明确的齿轮组。










