大家好,我是程序员二叉。


简介

MySQL InnoDB 引擎依靠 redo logundo log 实现事务特性与宕机恢复,binlog 负责数据备份与主从复制。三者各司其职、协同工作,是 MySQL 事务、高可用架构的核心。
本文依次讲解三大日志作用、WAL 机制、binlog 三种格式、两大日志区别、两阶段提交原理。

一、三大日志基本作用

1. redo log(重做日志)

InnoDB 存储引擎层独有,物理日志

  • 核心作用:实现崩溃恢复,保证事务持久性
  • 记录内容:数据页物理修改信息(页偏移、修改内容)
  • 写入时机:事务执行过程中持续写入

2. undo log(回滚日志)

InnoDB 存储引擎层独有,逻辑日志

  • 核心作用:
    1. 事务回滚:执行 ROLLBACK 时恢复数据到修改前状态
    2. 支撑 MVCC 多版本并发控制,实现读写不阻塞
  • 记录内容:数据修改前的旧版本数据

3. binlog(二进制日志)

MySQL 服务层日志,所有存储引擎通用,逻辑日志

  • 核心作用:
    1. 主从复制:主库向从库同步数据
    2. 数据备份 + 时间点恢复
  • 记录内容:执行的 SQL 语句 或 行数据变更记录

二、redo log、WAL 机制 与 崩溃恢复原理

1. WAL 预写日志机制

WAL(Write-Ahead Logging)核心规则:先写日志,后刷数据

  1. 只修改内存中的脏数据页,不直接刷磁盘数据
  2. 优先顺序写入 redo log 并持久化到磁盘
  3. 系统空闲 / redo log 写满后,后台线程批量将脏页刷入磁盘
    作用:规避随机磁盘 IO,大幅提升数据库写入性能。

2. redo log 如何保证事务崩溃恢复

  1. 事务执行:更新内存数据 + 持续写入 redo log
  2. 数据库意外宕机:内存脏数据未落盘,但 redo log 已持久化到磁盘
  3. MySQL 重启恢复流程:
  • 扫描 redo log 日志文件
  • 日志存在 prepare + commit 标记:重放日志,将数据落盘
  • 日志仅有 prepare、无 commit丢弃日志,回滚事务

结论:已提交的事务绝对不会丢失,严格保证事务持久性。

三、binlog 三种格式区别

binlog 是逻辑日志,提供三种记录格式,适用于不同业务场景:

  1. STATEMENT(语句模式)
  • 记录内容:原始执行的 SQL 语句
  • 优点:日志体积小,磁盘 IO 压力低
  • 缺点:存在主从数据不一致风险
  • 风险场景:now()rand()、自定义函数、limit 等非确定性 SQL
  1. ROW(行模式,MySQL 默认)
  • 记录内容:每行数据修改前后的完整字段内容
  • 优点:主从数据绝对一致,无不确定性问题
  • 缺点:日志文件体积大,磁盘 IO 开销高
  1. MIXED(混合模式)
  • 运行逻辑:MySQL 自动判断切换格式
    • 普通确定性 SQL:使用 STATEMENT
    • 非确定性 SQL:自动切换为 ROW
  • 定位:折中方案,兼顾日志体积与数据一致性

四、redo log 与 binlog 核心区别

对比维度 redo log binlog
所属层级 InnoDB 存储引擎层 MySQL 服务层
日志类型 物理日志(数据页修改) 逻辑日志(SQL / 行变更)
核心用途 崩溃恢复、事务持久化 主从复制、数据备份恢复
写入时机 事务执行中持续写入 事务提交时一次性写入
写入方式 循环覆盖(固定文件大小) 追加写入(不断新建文件)
引擎支持 仅 InnoDB 引擎 所有存储引擎通用

五、事务提交:redo log + binlog 两阶段提交(2PC)

1. 存在问题

如果两份日志写入顺序错乱,宕机会导致日志与数据不一致:

  1. 先写 binlog、后写 redo log:binlog 有记录,redo log 丢失 → 主从数据异常
  2. 先写 redo log、后写 binlog:redo log 已完成,binlog 丢失 → 备份、复制失效
    解决方案:两阶段提交,保证两份日志原子性(同时成功、同时回滚)

2. 完整执行流程

阶段一:Prepare 准备阶段

  1. 事务所有 SQL 执行完毕
  2. 将 redo log 刷入磁盘,并标记为 prepare
  3. 此时事务并未真正提交
    步骤:写入 binlog
  4. 将当前事务逻辑记录写入 binlog 并刷盘
  5. binlog 写入成功,代表外部日志记录完成
    阶段二:Commit 提交阶段
  6. 向 redo log 追加commit标记
  7. 事务正式提交,数据对外可见

3. 宕机恢复规则(高频考点)

  1. 宕机在 Prepare 之后、binlog 写入前
    redo log 只有 prepare,无完整 binlog → 事务回滚
    宕机在 binlog 写完、redo commit 之前
    binlog 完整存在,redo log 有 prepare 标记 → 数据库自动补 commit,提交事务
    最终效果:redo logbinlog 状态完全统一。

总结

1.三大日志分工

  • undo log:事务回滚 + 实现 MVCC;
  • redo log:基于 WAL 机制实现崩溃恢复,保障事务持久;
  • binlog:服务层通用日志,用于数据备份与主从复制。

2.binlog格式选型

STATEMENT 省空间但有数据不一致风险;ROW 安全性最高、日志量大;MIXED 为折中方案。

3.日志差异

redo log 是引擎层物理日志、循环覆盖写入;binlog 是服务层逻辑日志、追加写入。

4.两阶段提交

通过 Prepare + Commit 两阶段,保证 redo log 与 binlog 原子一致性,是 MySQL 事务与高可用的核心保障。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐