📝 4-Redo日志
引言¶
MySQL作为关系型数据库的代表,其事务机制是保障数据一致性的核心。本章节聚焦**Redo Log**的实现原理,结合Undo Log、事务提交流程、崩溃恢复等关键环节,完整解析MySQL如何通过日志机制实现ACID特性。Redo Log通过“先写日志,再写磁盘”的策略,在性能与可靠性之间取得平衡,是理解数据库事务机制的重要基石。
1. Redo Log的作用与核心原理¶
目标:保障事务的**原子性**和**持久性**。
- 日志先行(WAL): 事务执行时,先将数据变更记录到Redo Log缓冲区(内存),而非直接修改磁盘。事务提交时,强制将缓冲区数据刷入磁盘,确保即使数据库崩溃,已提交事务的修改仍可通过日志恢复。
- 减少磁盘IO: 避免频繁直接写入磁盘,通过批量刷盘(如每隔1秒或缓冲区满时)提升性能。
- 数据页版本管理: 记录数据页的修改操作(如页号、偏移量、旧值/新值),而非完整数据页,降低日志体积。
2. 事务执行流程中的Redo Log¶
步骤拆解:
-
事务开始:
-
在内存中分配Redo Log缓冲区和Undo Log缓冲区。
-
生成唯一的事务ID(如XID)。
-
数据修改:
-
修改内存中的数据页(如更新某行记录)。
-
同步生成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的实现原理,是掌握数据库事务与分布式事务设计的关键一步。