MySql中Binlog,Redolog,Undolog的应用场景及作用的时机

这是一个非常核心的MySQL(特别是InnoDB)问题。binlog, redo log, 和 undo log 是构成MySQL数据安全和高可用基石的三类日志,它们各自有不同的职责和应用场景。

为了更直观地理解,我们先通过一个流程图来看一条更新语句UPDATE t SET c=c+1 WHERE id=1;是如何与这三种日志交互的:
最终数据落盘
日志写入与刷盘
InnoDB引擎内部
请求数据
找到id=1的数据行
旧值写入
设置新值
记录物理修改
记录逻辑操作
提交时刷盘
提交时刷盘
定期或日志满时
客户端发送UPDATE语句
Executor执行器
Buffer Pool
返回旧值
Undo Log

(用于回滚和MVCC)
Redo Log Buffer

(用于崩溃恢复)
Binlog Cache

(用于主从复制)
事务提交
将Redo Log Buffer

刷盘(Write-Ahead Logging)
根据sync_binlog设置

将Binlog刷盘
写入Binlog后

通知存储引擎提交
Checkpoint机制
将Buffer Pool中

脏页刷回磁盘

上图展示了三种日志产生的核心时机,下面是它们各自作用的详细解释。


1. Redo Log (重做日志)

  • 所属:InnoDB存储引擎层特有的日志。
  • 物理性质 :记录的是物理日志,即"在某个数据页上做了什么修改"。比如"将第5号表空间的第100号页面的偏移量为10的位置的值更新为xxx"。
  • 作用
    1. 崩溃恢复 (Crash Recovery) :这是它的核心作用。确保事务的持久性(Durability)。即使发生宕机,已经提交的事务所做的修改也不会丢失。
    2. Write-Ahead Logging (WAL) :为了实现崩溃恢复,InnoDB采用了WAL技术,即所有对数据页的修改,都必须先写入Redo Log,然后再写入内存中的Buffer Pool。这样即使修改后的数据页(脏页)还没来得及刷盘就宕机了,重启后也能通过重放Redo Log来重新应用这些修改。
  • 作用时机
    • 事务执行过程中:SQL语句修改数据时,会先写到重做日志缓冲区(Redo Log Buffer)。
    • 事务提交时 :为了保证持久性,事务提交时必须将对应的Redo Log记录刷盘 (具体刷盘策略由innodb_flush_log_at_trx_commit参数控制,可权衡性能与安全)。
    • 后台线程定期:Redo Log Buffer中的内容也会由后台主线程定期刷盘。
  • 应用场景
    • 数据库宕机重启后,自动恢复所有已提交的事务。
    • 作为WAL机制的核心 ,它将随机写磁盘 (数据页)转换为了顺序写磁盘(Redo Log),大大提升了数据库的写入性能。

2. Undo Log (回滚日志)

  • 所属:InnoDB存储引擎层特有的日志。
  • 逻辑性质 :记录的是逻辑日志 。当一条记录被修改时,Undo Log会记录一条与当前操作相反的逻辑操作 。例如:
    • 如果是INSERT,则记录一条DELETE
    • 如果是DELETE,则记录一条INSERT(包含所有列的值)。
    • 如果是UPDATE,则记录一个反向的UPDATE(将更新后的值改回更新前的值)。
  • 作用
    1. 事务回滚 (Transaction Rollback) :确保事务的原子性(Atomicity)。如果事务需要回滚,InnoDB引擎就会使用Undo Log中的信息将数据恢复到事务开始前的状态。
    2. 多版本并发控制 (MVCC) :这是它的另一个极其重要的作用。当某个事务需要读取一行记录时,如果该记录正在被其他事务修改或已被修改但未提交,InnoDB会通过Undo Log来构建该行记录的一个早期版本(快照) ,供其他事务读取。这实现了非锁定读,是READ COMMITTEDREPEATABLE READ隔离级别的基础。
  • 作用时机
    • 事务进行中 :在任何数据修改操作(INSERT/DELETE/UPDATE)发生之前,都会先记录对应的Undo Log。
    • 事务回滚时:利用Undo Log执行反向操作。
    • 一致性读时:当其他会话需要读取旧版本数据以实现MVCC时。
  • 应用场景
    • 执行ROLLBACK语句时。
    • 支撑READ COMMITTEDREPEATABLE READ隔离级别下的快照读。
    • 系统自动回滚(如事务执行过程中发生死锁或被KILL)。

3. Binlog (二进制日志)

  • 所属:MySQL Server层记录的日志,所有存储引擎都可以使用。
  • 逻辑性质 :记录的是逻辑日志 ,即SQL语句本身(STATEMENT格式)或行更改后的值(ROW格式,默认),或者是两者的混合(MIXED格式)。
  • 作用
    1. 主从复制 (Replication):这是它的核心作用。Master将Binlog发送给Slave,Slave重放(Replay)这些日志,从而实现数据同步。
    2. 数据恢复 (Point-in-Time Recovery):由于Binlog记录了所有更改数据库的操作,可以通过重放Binlog来恢复某个时间点之后的数据。例如,每天凌晨有一个全量备份,那么可以用全量备份 + 从凌晨到故障前的Binlog来进行完整恢复。
  • 作用时机
    • 事务提交时 :在事务提交完成后,才会将整个事务的Binlog按顺序写入到二进制日志文件中(这保证了从库上事务执行的顺序与主库一致)。
    • 刷盘时机由参数sync_binlog控制,权衡性能与数据安全。
  • 应用场景
    • 搭建MySQL主从集群读写分离
    • 基于时间点的数据恢复和增量备份。

三者的协同工作:两阶段提交 (2PC)

从流程图可以看到,在事务提交时,Redo Log和Binlog必须保持一致性,否则会导致主从数据不一致或恢复后数据错误。为此,InnoDB使用了内部的两阶段提交(2-Phase Commit, 2PC)协议。

  1. Prepare阶段 :InnoDB将事务的Redo Log写入并刷盘,然后将Redo Log标记为PREPARE状态。
  2. Commit阶段 :MySQL Server将事务的Binlog写入并刷盘。刷盘成功后,InnoDB才会将Redo Log标记为COMMIT状态,事务才算真正提交完成。

这种机制保证了:

  • 如果Binlog写失败,事务会回滚(因为Redo Log是Prepare状态,但找不到对应的Binlog)。
  • 如果Binlog写成功,但Redo Log的Commit标记写失败,在崩溃恢复时,发现Redo Log是Prepare状态且存在对应的Binlog,则会自动提交事务,保证数据一致。

总结对比表

特性 Redo Log Undo Log Binlog
所属层级 InnoDB引擎层 InnoDB引擎层 MySQL Server层
日志性质 物理日志,记录对页的修改 逻辑日志,记录反向SQL 逻辑日志,记录SQL或行更改
主要作用 崩溃恢复 ,保证持久性 事务回滚MVCC ,保证原子性隔离性 主从复制数据恢复
写入时机 事务过程中、提交时(WAL) 数据修改前 事务提交后(按顺序)
生命周期 事务提交后,被覆盖循环使用 事务提交后,放入删除链表,由purge线程清理(当无快照读需要时) 事务提交后,可长期保留(取决于expire_logs_days)
是否可删 循环写入,固定大小 可被purge线程清理 可手动或自动 purge
相关推荐
振宇i2 小时前
MySQL数据库修改表结构语句
数据库·mysql
czlczl200209252 小时前
MySQL InnoDB 加锁全解析
数据库·mysql
lifewange2 小时前
SQL Server、MySQL、Oracle 核心区别对比
数据库·mysql·oracle
重生之小比特3 小时前
【MySQL 数据库】内外连接
数据库·mysql
weixin_704266053 小时前
MySQL到ES
数据库·mysql·elasticsearch
YL200404263 小时前
MySQL-进阶篇-存储引擎
数据库·mysql
lzh200409193 小时前
MySQL零基础入门:从建库到增删改查
数据库·mysql
Irene19914 小时前
MySQL、Oracle 数据库:唯一索引、普通索引、NUM_ROWS(行数)、ROW_NUM / ROWNUM(行号)
mysql·oracle
空空潍4 小时前
MySQL存储引擎与索引深度解析
后端·sql·mysql·innodb