欢迎光临
我们一直在努力

【MySQL】 三大日志:redo log、undo log、binlog 全解

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


简介

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

一、三大日志基本作用

1. redo log(重做日志)

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

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

2. undo log(回滚日志)

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

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

3. binlog(二进制日志)

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

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

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

1. WAL 预写日志机制

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

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

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

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

    三、binlog 三种格式区别

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

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

    四、redo log 与 binlog 核心区别

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

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

    1. 存在问题

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

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

    阶段一:Prepare 准备阶段

  • 事务所有 SQL 执行完毕
  • 将 redo log 刷入磁盘,并标记为 prepare
  • 此时事务并未真正提交
    步骤:写入 binlog
  • 将当前事务逻辑记录写入 binlog 并刷盘
  • binlog 写入成功,代表外部日志记录完成
    阶段二:Commit 提交阶段
  • 向 redo log 追加commit标记
  • 事务正式提交,数据对外可见
  • 3. 宕机恢复规则(高频考点)

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

  • 总结

    1.三大日志分工

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

    2.binlog格式选型

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

    3.日志差异

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

    4.两阶段提交

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

    赞(0)
    未经允许不得转载:171主机测评 » 【MySQL】 三大日志:redo log、undo log、binlog 全解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址