事务原理(redo log 与 undo log)
InnoDB 靠 redo log 保证持久性、undo log 保证原子性,两者共同保证一致性;隔离性则由锁 + MVCC 实现。
一、事务与 ACID
事务是一组操作的集合,是一个不可分割的工作单位:所有操作作为一个整体一起向系统提交或撤销,要么同时成功,要么同时失败。
| 特性 | 含义 | 实现手段 |
|---|---|---|
| 原子性(Atomicity) | 事务是不可分割的最小操作单元,要么全部成功,要么全部失败 | undo log |
| 一致性(Consistency) | 事务完成时,必须使所有数据都保持一致状态 | undo log + redo log |
| 隔离性(Isolation) | 数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行 | 锁 + MVCC |
| 持久性(Durability) | 事务一旦提交或回滚,它对数据库中数据的改变就是永久的 | redo log |
二、redo log(重做日志)
2.1 作用
- 记录的是事务提交时数据页的物理修改,用来实现事务的持久性。
- 由两部分组成:redo log buffer(内存中)和 redo log file(磁盘中)。
- 事务提交后,把所有修改信息存到该日志文件中;用于在刷新脏页到磁盘发生错误时进行数据恢复。
2.2 WAL(Write-Ahead Logging)
先写日志,再写磁盘:
update / delete → Buffer Pool(脏页)
→ redo log buffer → 提交时刷入 ib_logfile0/1
→ 脏页在后台异步刷入 xxx.ibd
即使脏页还没刷入
.ibd就宕机,重启后也能根据 redo log 重放已提交的修改,所以提交即持久。
2.3 循环写
redo log 采用固定大小、循环写的方式,涉及两个文件 ib_logfile0、ib_logfile1,写满后覆盖最早的记录。
三、undo log(回滚日志)
3.1 作用
- 记录数据被修改前的信息,作用有两个:提供回滚、支持 MVCC(多版本并发控制)。
- 与 redo log 记录物理日志不同,undo log 是逻辑日志:
DELETE一条记录时,undo log 记录一条对应的INSERT;INSERT一条记录时,undo log 记录一条对应的DELETE;UPDATE一条记录时,记录一条对应相反的UPDATE。
- 执行
ROLLBACK时,从 undo log 中读取逻辑记录并回滚。
3.2 销毁与存储
- 销毁:undo log 在事务执行时产生,事务提交时不会立即删除,因为这些日志可能还用于 MVCC。
- 存储:undo log 采用段的方式管理和记录,存放在 rollback segment 回滚段中,内部包含 1024 个 undo log segment。
3.3 insert 与 update / delete 的区别
| 操作 | 提交后 |
|---|---|
INSERT | 产生的 undo log 只在回滚时需要,事务提交后可立即删除 |
UPDATE / DELETE | 产生的 undo log 不仅在回滚时需要,快照读时也需要,不会立即删除 |
四、ACID 与日志的对应关系
原子性 —— undo log
持久性 —— redo log
一致性 —— undo log + redo log
隔离性 —— 锁 + MVCC
记忆:redo 管「已提交别丢」,undo 管「没提交能退」;两者都只保证单机崩溃恢复,不保证主从一致。
速查
-- 查看 redo log 相关参数
SHOW VARIABLES LIKE 'innodb_log_buffer_size';
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
-- 查看 redo log 文件与写入情况
SHOW ENGINE INNODB STATUS;
-- 查看 undo 表空间
SELECT name, space_type FROM information_schema.INNODB_TABLESPACES
WHERE space_type = 'Undo';
| 要做什么 | 结论 |
|---|---|
| 保证提交不丢 | redo log(WAL,先写日志再刷脏页) |
| 保证能回滚 | undo log(逻辑日志,记录修改前的信息) |
| 实现隔离 | 锁 + MVCC |
| 提交后 undo 能删吗 | INSERT 可删;UPDATE / DELETE 还要给快照读用,不能立即删 |
相关
- MVCC:undo log 版本链与 ReadView
- InnoDB 架构:Log Buffer、Redo Log、Undo Tablespaces
- 事务:
COMMIT/ROLLBACK的语法 - 并发事务问题与隔离级别:四种隔离级别与并发问题
- 锁概述与全局锁:隔离性中的「锁」