详解InnoDB存储引擎redo log 和 undo log

在MySQL的InnoDB存储引擎中,redo logundo log是支持事务ACID特性的核心机制。它们通过不同的方式记录事务的修改,确保数据的可靠性、一致性以及崩溃恢复能力。以下是它们的详细介绍:

一. redo log(重做日志)

1.作用
  • 持久性(Durability):确保事务提交后,修改的数据即使在系统崩溃或重启后也不会丢失。
  • 崩溃恢复(Crash Recovery):当数据库异常关闭后,通过重放redo log中的记录,将未写入磁盘的已提交事务数据恢复到最新状态。
  • 性能优化:通过**预写式日志(Write-Ahead Logging, WAL)**机制,减少直接写磁盘的随机IO压力。
2.特点
  • 物理日志:记录的是数据页(Page)的物理修改(如页号、偏移量、具体值的变化),而非逻辑SQL语句。
  • 顺序写入:redo log以顺序追加的方式写入磁盘(文件通常为ib_logfile0ib_logfile1),效率高。
  • 循环覆盖:日志空间固定,写满后会覆盖旧日志。
  • 与事务提交绑定:事务提交时,必须将redo log刷入磁盘(innodb_flush_log_at_trx_commit=1时强制刷盘)。
3.工作原理
  1. 写入顺序:事务执行过程中,InnoDB会先将数据页的修改记录到内存中的redo log buffer
  2. 刷盘时机:事务提交时,redo log从buffer写入磁盘(具体由参数innodb_flush_log_at_trx_commit控制)。
  3. 崩溃恢复
    • 数据库启动时,如果发现脏页(内存中修改但未写入磁盘的数据页)未持久化,会通过redo log重放这些修改,恢复数据一致性。
    • 例如:假设事务修改了某行数据但未刷盘,系统崩溃后重启,InnoDB会通过redo log将该修改应用到数据页。
4.示例

假设执行一条SQL语句:

UPDATE account SET balance = 1000 WHERE id = 1;
  • redo log记录:数据页中id=1balance字段从旧值修改为1000的物理操作(如页号、偏移量、新值)。
  • 作用:即使系统崩溃,重启后也能通过redo log恢复该修改。

二. undo log(回滚日志)

1.作用
  • 原子性(Atomicity):事务回滚时,通过undo log将数据恢复到事务开始前的状态。
  • 一致性(Consistency):配合多版本并发控制(MVCC),实现读写不阻塞,确保事务隔离性。
  • 历史版本管理:记录数据修改前的旧值,用于生成快照(Snapshot),支持可重复读(Repeatable Read)隔离级别。
2.特点
  • 逻辑日志:记录的是逆向操作(如INSERT对应DELETEUPDATE对应反向UPDATE)。
  • 随机写入:存储于系统表空间的**回滚段(Rollback Segment)**中,可能涉及随机IO。
  • 生命周期
    • 事务提交后,undo log不会立即删除,而是由Purge线程异步清理。
    • 在MVCC中,未被读取事务引用的旧版本数据才会被清除。
3.工作原理
  1. 记录逆向操作
    • 在事务修改数据前,InnoDB会将旧值写入undo log。
    • 例如:UPDATE account SET balance = 1000 WHERE id = 1时,undo log会记录balance=原值
  2. 事务回滚
    • 如果事务回滚,InnoDB会根据undo log中的逆向操作,将数据恢复到修改前的状态。
  3. MVCC支持
    • 通过undo log链表保存数据的多个版本,不同事务根据隔离级别读取对应的历史版本。
    • 例如:事务A读取数据时,若其他事务B正在修改该数据,A会通过undo log获取数据修改前的版本,避免冲突。
4.示例

假设执行一条SQL语句:

UPDATE account SET balance = 1000 WHERE id = 1;
  • undo log记录balance字段的旧值(如500)及反向操作(如UPDATE account SET balance = 500 WHERE id = 1)。
  • 作用
    • 若事务回滚,通过undo log将balance恢复为500。
    • 若其他事务需要读取该行数据的历史版本(如MVCC),通过undo log获取旧值。

三. redo log与undo log的协同

  • 事务提交的两阶段提交
    1. Prepare阶段:将事务的修改写入redo log(标记为prepare状态)。
    2. Commit阶段:将事务的修改写入binlog,再更新redo log为commit状态。
    • 这确保了redo log和binlog的一致性,避免数据不一致问题。
  • 持久性保障
    • undo log的修改也会生成redo log,确保undo log本身在崩溃恢复后仍然可用。
  • MVCC实现
    • undo log保存数据的历史版本,结合事务的隔离级别(如可重复读),提供一致性读。

四. redo log与undo log的区别

特性redo logundo log
作用保证事务的持久性(Durability)保证事务的原子性(Atomicity)和MVCC
记录内容物理日志(数据页的修改细节)逻辑日志(逆向操作)
存储位置独立文件(ib_logfile0等)系统表空间的回滚段(Rollback Segment)
写入方式顺序写入(高效)随机写入
生命周期事务提交后可能被覆盖(循环使用)事务提交后由Purge线程异步清理
与事务的关系记录事务的修改,用于崩溃恢复记录事务的旧值,用于回滚和MVCC

五. 实际场景中的协作

转账操作为例:

  1. 事务开始
    • 扣减账户A的余额(balance -= 100)。
    • 增加账户B的余额(balance += 100)。
  2. undo log记录
    • 记录账户A的旧余额(如1000)和反向操作(balance += 100)。
    • 记录账户B的旧余额(如500)和反向操作(balance -= 100)。
  3. redo log记录
    • 记录账户A和账户B的数据页修改(物理操作)。
  4. 事务提交
    • redo log刷入磁盘,确保持久性。
  5. 崩溃恢复
    • 如果系统崩溃,重启后通过redo log恢复已提交的转账操作。
  6. 回滚操作
    • 如果事务失败,通过undo log将账户A和B的余额恢复到原始值。

六.总结

  • redo log物理日志,用于崩溃恢复和持久性,确保已提交事务的修改不丢失。
  • undo log逻辑日志,用于事务回滚和MVCC,保证原子性和一致性。
  • 两者共同协作,支撑MySQL的ACID特性,是数据库可靠性和高性能的关键机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值