MySQL日志专项整理之redo log和undo log

MySQL日志专项整理之redo log和undo log
最新回答
诗雨伊意

2021-04-04 14:13:34

Redo Log与Undo Log是MySQL中保障事务特性的核心日志机制,其设计原理与协作流程如下

Redo Log(重做日志)
核心作用:确保事务的持久性(Durability),通过物理日志记录数据页的修改,避免系统崩溃时内存数据丢失。
实现原理

  1. 双层结构:由内存中的redo log buffer(默认16MB)和磁盘上的redo log file(默认2个48MB文件ib_logfile0/1)组成。
  2. 写入流程:事务修改数据时,先修改内存中的Buffer Pool生成脏页,同时生成redo log记录“哪个页的哪个偏移量被修改为何值”,日志先写入redo log buffer,事务提交时通过刷盘策略(由innodb_flush_log_at_trx_commit控制)持久化到磁盘。
  3. 刷盘策略

    0:后台线程每秒刷盘,可能丢失1秒数据(高性能但风险高)。

    1(默认):事务提交时同步刷盘,保证持久性但性能较低。

    2:提交时写入操作系统内核缓冲区,由OS决定刷盘时机,性能与安全性折中。

  4. 优势:通过顺序IO追加写入日志,减少随机IO对磁盘的频繁访问,提升吞吐量。

Undo Log(回滚日志)
核心作用:保障事务的原子性(Atomicity)和实现多版本并发控制(MVCC)
实现原理

  1. 存储结构:使用回滚段(Rollback Segment)组织,每个回滚段包含1024个Undo Log Segment,MySQL 5.5后共有128个回滚段。
  2. 记录内容

    INSERT操作:记录主键值,回滚时直接删除对应行。

    UPDATE/DELETE操作:记录修改前的旧值,回滚时恢复旧值或重新插入数据。

  3. 生命周期

    Insert Undo Log:事务提交后直接删除(无需MVCC支持)。

    Update Undo Log:提交后放入版本链,由Purge线程判断是否删除(可能被其他事务的快照读引用)。

  4. MVCC支持:每行数据包含隐藏字段DB_TRX_ID(事务ID)和DB_ROLL_PTR(回滚指针),指向Undo Log中的历史版本,实现非锁定读(快照读)。

协作流程

  1. 事务执行阶段

    修改数据时,同时生成redo log(记录“如何修改”)和Undo Log(记录“修改前状态”)。

    Redo Log进入redo log buffer,Undo Log写入回滚段。

  2. 事务提交阶段

    Redo Log通过刷盘策略持久化到磁盘。

    Undo Log根据类型决定是否保留(Update类型需等待Purge)。

  3. 崩溃恢复阶段

    若redo log已持久化但数据未刷盘,根据redo log重做修改。

    若事务未提交,根据Undo Log回滚未完成操作。

关键特性对比

  • Redo Log:物理日志,关注数据页的最终状态,用于崩溃恢复。
  • Undo Log:逻辑日志,关注数据的历史版本,用于回滚和MVCC。
    两者通过两阶段提交(2PC)协同工作:先写redo log的prepare阶段,再写binlog(二进制日志),最后提交redo log的commit阶段,确保redo log与binlog逻辑一致,避免主从数据不一致。