undo log 与 redo log
理解数据库事务日志:Undo Log 与 Redo Log
在 MySQL InnoDB 存储引擎中,为了保证数据的原子性、一致性以及持久性,系统设计了两种重要的日志:undo log(撤销日志)和 redo log(重做日志)。它们分别承担着不同的职责,共同保障事务处理的正确性和高可用性。
1. Undo Log:支持事务回滚与多版本控制
1.1 作用与目的
- 事务回滚:当事务在执行过程中出现错误或用户主动回滚时,undo log 记录了每次数据修改前的状态。通过 undo log,数据库可以将数据恢复到修改前的状态,从而实现事务的原子性。
- 多版本并发控制(MVCC):为了支持一致性读(snapshot read),当一个事务启动后,即使其他事务修改了数据,当前事务依然可以通过 undo log 看到修改前的数据版本,从而构建出一个一致的快照视图。
1.2 工作原理
在执行数据更新操作之前,InnoDB 会先将即将被修改的数据的旧值写入 undo log。这样,当事务需要回滚时,系统就可以利用这些旧值撤销修改,确保数据回到原始状态。
例如,假设某个账户的余额从 1000 元更新为 900 元,undo log 会记录“余额从 1000 元改为 900 元前的状态 1000”,以便在回滚时恢复该账户余额。
2. Redo Log:保证数据恢复与持久性
2.1 作用与目的
- 数据恢复:redo log 用于记录数据修改后的新状态。在事务提交后,即使数据页还未及时刷新到磁盘,当系统发生崩溃时,可以利用 redo log 将已提交的事务操作重做(redo),确保数据不会丢失。
- 持久性保障:在事务提交时,InnoDB 会确保 redo log 的数据已经写入磁盘(遵循写前日志 WAL 原则),这样即使发生系统故障,也能保证数据的最终一致性。
2.2 工作原理
在数据更新时,InnoDB 会先把即将写入的数据的物理变化记录在 redo log 中。当事务提交后,即使数据页尚未写入磁盘,系统也能依赖 redo log 在崩溃恢复时将这些操作重新应用,保证所有已提交事务的结果能正确恢复。
举例说明:
假设我们有一个银行账户系统,账户信息存储在一张 account 表中,初始状态如下:
-- 初始数据
账户 A:id=1, balance=1000
账户 B:id=2, balance=500
现在我们执行一个转账操作,从账户 A 转 100 元到账户 B:
START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT;
执行过程:
-
修改前写入 undo log:
- 当账户 A 的余额从 1000 更新为 900 前,系统记录下 1000 的旧值。
- 同样,账户 B 从 500 更新为 600 之前,undo log 记录下 500 的旧值。
这保证了在需要回滚时能够恢复原状态。
-
修改后写入 redo log:
- 系统会把对账户 A 和账户 B 的更新操作记录在 redo log 中,即记录“余额从 1000 变为 900”和“余额从 500 变为 600”的物理变更。
- 当事务提交后,redo log 数据已经写入磁盘,即使数据页尚未刷新,系统崩溃后也能根据 redo log 将转账操作重做,恢复到正确的账户余额。
通过这种机制,redo log 确保了数据在系统崩溃时的持久性,而 undo log 则保证了事务的原子性与一致性。
3. Undo Log 与 Redo Log 的核心区别
-
记录内容不同
- Undo Log:记录修改前的数据状态(旧值),主要用于回滚事务以及支持 MVCC(一致性读)。
- Redo Log:记录修改后的数据状态(新值),主要用于崩溃恢复,确保事务提交的结果不会丢失。
-
作用目标不同
- Undo Log:支持事务的原子性,确保在事务回滚时数据能恢复到修改前状态,同时帮助构建事务一致性视图。
- Redo Log:确保事务的持久性,即使在系统故障后,已提交的事务也能通过 redo log 被重做,从而恢复数据。
-
写入时机不同
- 在执行修改操作前,系统会将旧数据写入 undo log;
- 在修改数据后,会把新数据的物理变化写入 redo log,并在事务提交时同步写入磁盘。
4. 小结
理解 undo log 与 redo log 的区别有助于掌握数据库事务的可靠性保障机制:
- Undo Log 通过记录修改前的数据状态,支持事务的回滚和 MVCC,确保事务在执行错误时能安全回退,并为一致性读提供历史版本数据。
- Redo Log 记录数据修改后的物理变更,保证了事务提交后的持久性,即使在系统崩溃后也能依靠 redo log 进行恢复,保证数据不丢失。
这种双重日志机制,使得 MySQL InnoDB 在高并发环境下既能保持高性能,又能确保数据的一致性和持久性。
通过上述解析和转账示例,希望你对 undo log 与 redo log 的作用与区别有了更清晰的认识。欢迎在评论区讨论和交流更多关于数据库事务日志的理解与应用。
浙公网安备 33010602011771号