跳转至

📝 4-Redo日志

引言

MySQL作为关系型数据库的代表,其事务机制是保障数据一致性的核心。本章节聚焦**Redo Log**的实现原理,结合Undo Log、事务提交流程、崩溃恢复等关键环节,完整解析MySQL如何通过日志机制实现ACID特性。Redo Log通过“先写日志,再写磁盘”的策略,在性能与可靠性之间取得平衡,是理解数据库事务机制的重要基石。


1. Redo Log的作用与核心原理

目标:保障事务的**原子性**和**持久性**。

  • 日志先行(WAL): 事务执行时,先将数据变更记录到Redo Log缓冲区(内存),而非直接修改磁盘。事务提交时,强制将缓冲区数据刷入磁盘,确保即使数据库崩溃,已提交事务的修改仍可通过日志恢复。
  • 减少磁盘IO: 避免频繁直接写入磁盘,通过批量刷盘(如每隔1秒或缓冲区满时)提升性能。
  • 数据页版本管理: 记录数据页的修改操作(如页号、偏移量、旧值/新值),而非完整数据页,降低日志体积。

2. 事务执行流程中的Redo Log

步骤拆解

  1. 事务开始:

  2. 在内存中分配Redo Log缓冲区和Undo Log缓冲区。

  3. 生成唯一的事务ID(如XID)。

  4. 数据修改:

  5. 修改内存中的数据页(如更新某行记录)。

  6. 同步生成Redo Log记录(记录修改操作的逆向信息,用于崩溃恢复)。

事务提交:

  • 将Redo Log缓冲区的数据**强制刷入磁盘**(通过fsync等机制)。
  • 仅在Redo Log持久化成功后,事务才视为提交成功。

脏页处理:

  • 修改后的数据页(脏页)暂存内存,由后台线程异步刷入磁盘。

关键机制

  • Checkpoint: 定期将内存中的脏页刷入磁盘,并记录当前Redo Log的刷盘位置(LSN)。崩溃恢复时,从Checkpoint之后的Redo Log开始重放。
  • 双写缓冲区(Double Write Buffer): 防止部分页写入失败导致数据损坏。脏页先写入双写缓冲区,再批量写入数据文件。

3. 崩溃恢复机制

场景:数据库异常宕机后,如何恢复数据一致性?

  • Redo Log重放:
  • 根据Checkpoint信息,确定Redo Log中已提交但未刷盘的操作范围。
  • 从Checkpoint的LSN开始,按顺序重放Redo Log中的修改操作,将脏页变更应用到磁盘。
  • Undo Log回滚: 未提交事务的修改通过Undo Log回滚,恢复到事务开始前的状态。
  • MVCC协同: 通过Undo Log保存历史版本数据,支持非阻塞读(如Read Committed、Repeatable Read隔离级别)。

4. Redo Log与Undo Log的协同

  • Redo Log:
  • 用途:保障已提交事务的持久化。
  • 内容:记录数据页的修改操作(如INSERT、UPDATE、DELETE)。
  • Undo Log:
  • 用途:支持事务回滚和MVCC。
  • 内容:保存数据的旧版本(如行记录的删除标记、更新前的值)。
  • 日志管理:
  • Redo Log采用**循环写入**机制,需定期清理(通过Checkpoint)。
  • Undo Log随事务生命周期管理,事务结束后可被清理或保留供MVCC使用。

5. XA事务与分布式一致性扩展

XA事务特性

  • 强一致性:通过两阶段提交(2PC)协调多个资源管理器(如多个数据库实例),确保分布式事务的原子性。
  • 隔离级别:需设置为SERIALIZABLE以避免脏读、不可重复读问题。
  • Redo Log的作用: 在分布式事务中,每个分支事务的Redo Log需独立记录,并在全局提交时同步刷盘。若分支事务失败,通过Redo Log回滚本地操作。

总结

Redo Log是MySQL事务机制的核心组件,通过“日志先行”策略平衡性能与可靠性。其协同Undo Log、Checkpoint、MVCC等机制,共同保障了事务的ACID特性。在分布式场景下,Redo Log进一步支撑XA事务的强一致性需求。理解Redo Log的实现原理,是掌握数据库事务与分布式事务设计的关键一步。