MySQL binlog、redolog 和 undolog 日志的区别是什么?

MySQL 中这三种日志各司其职,核心区别如下:

对比维度redo logundo logbinlog
归属层级 InnoDB 引擎层 InnoDB 引擎层 MySQL Server 层
核心作用 崩溃恢复,保证持久性 事务回滚、MVCC,保证原子性 主从复制、数据备份
写入方式 循环写,空间固定 按事务写入 追加写,文件可配置
内容形式 物理日志(在某某页修改了什么) 逻辑日志(反向 SQL) 逻辑日志(SQL 语句或行变更)
事务关联 事务提交时刷盘 事务执行中持续写 事务提交时一次性写入

一句话总结:redo log 是 "崩溃恢复的救命稻草",undo log 是 "后悔药的原料",binlog 是 "主从复制的信使"。

深度解析

一、三种日志的架构位置

 

 

上图展示了 MySQL 三种日志的架构层级关系:

  • binlog:位于 Server 层,所有存储引擎都可以使用。它是 MySQL 的 "归档日志",主要用于主从复制和数据备份恢复。以事件形式记录所有修改数据的 SQL 语句或行变更。

  • redo log 和 undo log:位于 InnoDB 引擎层,是 InnoDB 特有的。redo log 用于崩溃恢复,采用 WAL(Write-Ahead Logging)机制;undo log 用于事务回滚和 MVCC 实现。

  • 层级分离的意义:正因为 binlog 在 Server 层,redo log 在引擎层,才需要 "两阶段提交" 来保证两者的一致性。

二、redo log 详解

 

 

上图展示了 redo log 的循环写入机制:

  • 循环写入:redo log 不是无限追加的,而是固定大小(默认两个文件各 1GB)循环使用。write pos 记录当前写入位置,checkpoint 记录检查点位置。

  • WAL 机制:事务提交时,先写 redo log(顺序 I/O),再异步刷脏页到数据文件(随机 I/O)。这样即使数据库崩溃,也可以通过 redo log 恢复未刷盘的数据。

  • 刷盘时机:

    • 事务提交时(innodb_flush_log_at_trx_commit=1,最安全)
    • 后台线程定时刷
    • redo log 空间不足时

关键配置:

-- 查看 redo log 配置
SHOW VARIABLES LIKE 'innodb_log%';

-- innodb_log_file_size:单个日志文件大小(默认 48MB,建议 1-2GB)
-- innodb_log_files_in_group:日志文件数量(默认 2)
-- innodb_flush_log_at_trx_commit:刷盘策略(0/1/2,建议 1)

三、undo log 详解

 

 

上图展示了 undo log 的两大核心作用:

  • 事务回滚:记录数据的 "反向操作"。UPDATE 记录旧值,DELETE 记录整行,INSERT 记录主键。当事务回滚时,用 undo log 中的信息恢复数据。

  • MVCC 实现:每行数据都有隐藏列 trx_id(事务 ID)和 roll_pointer(回滚指针)。通过 roll_pointer 找到 undo log 中的旧版本,实现 "读已提交" 和 "可重复读" 隔离级别。

undo log 存储位置:

-- MySQL 5.6 之前:存储在共享表空间 ibdata1
-- MySQL 5.6+:可配置独立的 undo 表空间
SHOW VARIABLES LIKE 'innodb_undo%';

-- innodb_undo_tablespaces:undo 表空间数量
-- innodb_max_undo_log_size:undo 表空间最大值
-- innodb_undo_log_truncate:是否自动截断

四、binlog 详解

 

 

上图展示了 binlog 在主从复制中的作用:

  • 主库写入:事务提交时,将修改操作写入 binlog(追加写入,文件可配置滚动)

  • 从库同步:

    • I/O Thread:连接主库,读取 binlog,写入本地的 Relay Log(中继日志)
    • SQL Thread:读取 Relay Log,重放 SQL 语句,保持与主库数据一致

binlog 三种格式:

格式记录内容优点缺点
STATEMENT SQL 语句本身 日志量小 不确定函数可能导致不一致
ROW 行数据变更 数据一致性最好 日志量大
MIXED 混合模式 兼顾两者 复杂场景可能仍有问题
-- 查看 binlog 配置
SHOW VARIABLES LIKE '%binlog%';

-- binlog_format:日志格式(推荐 ROW)
-- binlog_cache_size:事务缓存大小
-- sync_binlog:刷盘策略(1 = 每次提交都刷盘,最安全)

五、两阶段提交

 

 

上图展示了 redo log 和 binlog 的两阶段提交流程:

  • 为什么需要两阶段提交:因为 redo log 和 binlog 是两个独立的日志系统,如果不协调,可能出现:

    • redo log 写了但 binlog 没写 → 主库恢复后数据丢失,从库没收到
    • binlog 写了但 redo log 没写 → 主库恢复后数据回滚,从库却收到了
  • 两阶段提交流程:

    1. Prepare 阶段:写 redo log,标记为 prepare 状态
    2. Commit 阶段:写 binlog,然后写 redo log 标记为 commit 状态
  • 崩溃恢复:如果崩溃时 redo log 处于 prepare 状态,通过检查 binlog 是否完整来决定提交还是回滚。

posted on 2026-06-12 10:32  数据派  阅读(6)  评论(0)    收藏  举报