mysql--核心日志文件详解

引言:

mysql中日志文件是非常重要,mysql的各种特性和功能都是基于日志文件实现的,本文将详细介绍mysql的日志文件

一、日志类型(仅介绍重要的)

1.Undo Log

(1)作用

  • 实现事务的原子性(Atomicity)
  • 用于事务回滚(ROLLBACK),当事务执行失败或显式回滚时,可以通过 Undo Log 恢复到事务开始前的状态。
  • 支持多版本并发控制(MVCC),实现非锁定读(如 SELECT 不加锁也能读到历史版本)。

(2)存储位置

  • 存储在 InnoDB 存储引擎的表空间中(可以是系统表空间或独立的 Undo 表空间)。
  • 从 MySQL 5.6 开始支持独立的 Undo 表空间(通过 innodb_undo_tablespaces 配置)。

(3)工作机制

  • 当一条记录被修改时,InnoDB 会先将修改前的旧值(旧版本)写入 Undo Log。
  • 每个事务有自己的 Undo Log 记录,形成一个链表(Undo Log Chain)。
  • 当事务提交后,Undo Log 并不会立即删除,而是标记为"可清理"状态,供 MVCC 使用。
  • 后台线程(Purge Thread)在确认没有事务需要这些旧版本后,才会真正删除 Undo 日志

(4)示例

sql 复制代码
BEGIN;
UPDATE users SET age = 25 WHERE id = 1;
-- 此时,原 age 值(比如20)被写入 Undo Log
ROLLBACK;
-- 使用 Undo Log 回滚,age 恢复为 20

2. Redo Log

1. 作用

  • 保证事务的持久性(Durability)
  • 确保即使在数据库崩溃后,已提交的事务修改也不会丢失。
  • 通过 WAL(Write-Ahead Logging,预写日志)机制,先写日志再写数据页。

2. 存储位置

  • 物理文件,位于 MySQL 数据目录下,通常为 ib_logfile0ib_logfile1
  • 文件大小固定(由 innodb_log_file_size 控制),循环写入。

3. 工作机制

  • 事务执行过程中,对数据页的修改会先记录到 Redo Log Buffer(内存中)。
  • 当满足一定条件(如事务提交、Buffer满、每秒刷新等),Redo Log Buffer 会被刷新到磁盘的 Redo Log 文件中。
  • 数据页的真正修改可以异步写入磁盘(由后台线程完成),提高性能。
  • 数据库崩溃恢复时,通过 Redo Log 重放(replay)已提交但未落盘的事务操作,恢复数据。

4. 关键参数

  • innodb_log_file_size:单个日志文件大小(建议设置为 1~2GB)。
  • innodb_log_files_in_group:日志文件数量(默认2)。
  • innodb_flush_log_at_trx_commit:控制日志刷盘策略:
    • 1:每次事务提交都刷盘(最安全,性能略低)。
    • 0:每秒刷一次,事务提交不刷盘(性能高,可能丢失1秒数据)。
    • 2:事务提交写入 OS 缓存,每秒刷盘(折中方案)。

5. 示例

sql 复制代码
BEGIN;
UPDATE users SET age = 30 WHERE id = 1;
COMMIT;
-- 提交时,Redo Log 写入磁盘,即使此时数据页未写入磁盘,崩溃后也能恢复

sql

BEGIN; UPDATE users SET age = 30 WHERE id = 1; COMMIT; -- 提交时,Redo Log 写入磁盘,即使此时数据页未写入磁盘,崩溃后也能恢复

3.Binlog(二进制文件)

(1)作用

  • 记录所有修改数据的 SQL 语句或行变更(取决于格式)。
  • 用于数据库的主从复制(Replication)数据恢复(Point-in-Time Recovery)
  • 由 MySQL Server 层维护,与存储引擎无关(所有引擎都能记录 Binlog)。

(2)存储位置

  • 文件形式,位于 MySQL 数据目录下,如 mysql-bin.000001mysql-bin.000002 等。
  • 可以配置自动删除过期日志(通过 expire_logs_daysbinlog_expire_logs_seconds)。

(3)日志格式(三种模式)

全屏复制

格式 说明 优缺点
STATEMENT 记录 SQL 语句本身 日志量小,但可能在从库产生不一致(如使用 NOW() 函数)
ROW 记录每一行数据的变更(推荐) 安全、精确,适合复制,但日志量大
MIXED 混合模式,MySQL 自动选择 一般默认使用,兼顾安全与性能

(4)写入时机

  • 事务提交时,由 MySQL Server 层将变更写入 Binlog(在存储引擎提交之前或之后,取决于参数)。
  • 通过 sync_binlog 控制刷盘频率:
    • 0:由操作系统决定(性能高,风险高)。
    • 1:每次事务提交都刷盘(最安全,性能稍低)。
    • N:每 N 个事务提交刷一次。

(5)使用场景

  • 主从复制:主库 Binlog 发送给从库,从库通过 SQL Thread 回放日志。
  • 数据恢复 :通过 mysqlbinlog 工具解析 Binlog,恢复到某个时间点。

4.Doublewrite Buffer(双写缓冲)

✅ 是否属于"日志"?

严格来说不是日志文件,但它是 一种保障数据页写入一致性的机制,常与 Redo Log 配合使用,防止"部分写问题"(partial page write)。

🔍 作用

  • 防止在数据库崩溃时出现"页断裂"(Page Corruption)。
  • 当 InnoDB 将脏页刷新到磁盘时,如果写入过程中断电,可能导致页面只写了一半(512字节 out of 16KB),造成数据损坏。
  • Doublewrite Buffer 先将页面写入一个连续的、安全的区域(系统表空间中的双写缓冲区),再写入实际的数据文件位置。

📍 工作流程:

  1. 脏页从 Buffer Pool 刷出时,先批量写入 Doublewrite Buffer 区域(物理上连续)。
  2. 再将这些页写入各自在 .ibd 文件中的目标位置。
  3. 崩溃恢复时,如果发现某页校验失败,可以从 Doublewrite Buffer 中恢复完整的副本。

5.Change Buffer(变更缓冲)

✅ 是否属于"日志"?

不是传统日志,但它记录的是对二级索引页的延迟修改操作,具有"延迟写 + 缓冲"的特性,类似轻量级日志。

🔍 作用

  • 提高 DML 操作(INSERT/UPDATE/DELETE)性能,尤其是在大量随机写入场景下。
  • 对于非唯一二级索引的更新,如果不影响主键索引,InnoDB 会将修改暂存到 Change Buffer,而不是立即读取并修改对应的索引页(避免随机 I/O)。
  • 后续当该页被加载到内存时,再进行合并(merge)。

🔄 合并时机:

  • 查询访问该页时。
  • 后台线程定期合并。
  • 系统空闲或刷新脏页时。

6.Error Log(错误日志)

属于 MySQL Server 层,但 InnoDB 的严重错误也会写入其中

🔍 作用

  • 记录 InnoDB 初始化、崩溃、恢复、死锁、表空间异常等关键事件。
  • 是排查 InnoDB 故障的重要依据。

7. InnoDB Recovery Logs(恢复日志信息)

这不是独立文件,而是指 InnoDB 在启动时通过 Redo Log 自动执行恢复过程的日志输出,通常打印在 Error Log 中。

8.Slow Query Log(慢查询日志)

用来分析 InnoDB 表的锁等待、长事务、全表扫描等问题。

二、sql语句执行过程中日志写入顺序和触发时机

示例 SQL

sql 复制代码
BEGIN;
UPDATE users SET age = 30 WHERE id = 1;
COMMIT;

1.整体流程概览

阶段 操作 写入日志
1. 开始事务 BEGIN 无日志写入
2. 执行 UPDATE 修改数据页 写 Undo Log + Redo Log(内存)
3. 提交事务 COMMIT Redo Log 刷盘 → 写 Binlog → Binlog 刷盘 → InnoDB 提交

2.详细时间线:

时间点 操作 写入内容 写入位置 是否刷盘(持久化)
T0 BEGIN; -
T1 UPDATE ... 旧值写入 Undo Log Undo Log Buffer(内存)
T1 UPDATE ... 修改数据页 Buffer Pool(内存)
T1 UPDATE ... 生成 Redo Log 记录 Redo Log Buffer(内存)
T2 (Prepare) COMMIT 开始 事务状态 → PREPARED Redo Log Buffer ✅ (fsync)
T2 (Prepare) COMMIT 开始 所有 Redo Log 刷盘 ib_logfile*
T2 (Commit) 写 Binlog 更新事件写入 Binlog Binlog Cache → .binlog ✅ (fsync, sync_binlog=1)
T2 (Commit) 最终提交 事务状态 → COMMITTED InnoDB 内部结构 ✅(通过 Redo Log)

3.💥 崩溃恢复场景分析

假设在不同阶段发生崩溃,MySQL 如何恢复?

崩溃时间点 恢复行为
UPDATE 后,未 COMMIT 重启后回滚该事务(通过 Undo Log)
Prepare 阶段后,未写 Binlog 重启后发现 PREPARED 事务,但无对应 Binlog → 回滚
Binlog 写完后,未最终提交 重启后发现 PREPARED 事务且有 Binlog → 提交(保证一致性)
成功提交后崩溃 数据已持久化,正常启动

三、总结:

名称 类型 所属层级 主要用途 是否持久化
Undo Log 日志 InnoDB 回滚、MVCC
Redo Log 日志 InnoDB 崩溃恢复、持久性
Doublewrite Buffer 安全机制 InnoDB 防止页断裂
Change Buffer 缓冲结构 InnoDB 延迟二级索引更新 ❌(数据最终落盘)
Error Log 日志 Server 层 记录 InnoDB 错误
Transaction System / Rollback Segments 内部结构 InnoDB 事务管理元数据
相关推荐
电商API_180079052472 小时前
电商数据分析之自动获取数据的技术手段分享
大数据·数据库·数据挖掘·数据分析
MilesShi2 小时前
RAG:解锁大语言模型新能力的关键钥匙
数据库·人工智能·语言模型
gsfl4 小时前
Redis 缓存
数据库·redis·缓存
恒悦sunsite10 小时前
Ubuntu之apt安装ClickHouse数据库
数据库·clickhouse·ubuntu·列式存储·8123
奥尔特星云大使11 小时前
MySQL 慢查询日志slow query log
android·数据库·mysql·adb·慢日志·slow query log
来自宇宙的曹先生11 小时前
MySQL 存储引擎 API
数据库·mysql
间彧11 小时前
MySQL Performance Schema详解与实战应用
数据库
间彧11 小时前
MySQL Exporter采集的关键指标有哪些,如何解读这些指标?
数据库
weixin_4462608511 小时前
Django - 让开发变得简单高效的Web框架
前端·数据库·django