1、undo log 的类型
undo log 与 redo log 一样,也是有各种类型的。比如,undo log 有 TRX_UNDO_INSERT_REC 类型,表示插入数据的 undo log 日志,只需要记录主键的值,后续回滚直接根据主键删除就行。
TRX_UNDO_INSERT_REC 类型的 undo log 日志
delete 对应的 undo log 类型为 TRX_UNDO_DEL_MARK_REC,它的结构如下:
TRX_UNDO_DEL_MARK_REC 类型的 undo log
因为删除的时候并不是真的删除,而是给每一个行数据打了一个删除标记,所以 delete 的 undo log 也只需要记录主键的值即可。
update 有更新主键和不更新主键的情况(更新主键的行为很蠢,会导致页分裂),update 的 undo log 的值类型为 TRX_UNDO_UPD_EXIST_REC,它的结构如下:
TRX_UNDO_UPD_EXIST_REC 类型的 undo log
它需要记住被更新的列以及列原始的值。
2.总结
产生 undo log 时会产生相应的 redo log,那么为什么还需要 undo log?直接用 redo log 恢复不行吗?
原因
在恢复时,对于已经COMMIT的事务使用redo log进行重做,对于没有COMMIT的事务,使用undo log进行回滚。
所以整个流程是:
首先介绍几个概念:
REDO 为了重做对数据页(page)更改保存的信息,用于恢复
UNDO 为了撤销对数据记录(tuple)更改保存的信息,用于回滚事务
LSN(Log Sequence NO) 日志号,一个递增的64位整数,一个LSN表示一个(redo)Log结构。
CHECKPOINT表示一个时间点,在CHECKPOINT LSN之前的更改都已经保存到了持久存储。恢复时只需从最后一个CHECKPOINT LSN开始。
下面从update, commit, recovery三个方面简单说明:
update(Insert与之类似)
- 1.计算更新后tuple到原tuple的delta信息,把这个delta复制到rollback segment中的undo
- 2.写redo log,记录对rollback segment的更改
- 3.把buffer pool中的对应tuple更新成新值,把新值的rollback pointer写入undo log
- 4.写redo log,记入对页(page)的更改
- 5.将页状态改成dirty
commit
force log, flush当前事务的redo
logrecovery
- 1.启动开始时检测是否发生崩溃
- 2.定位到最近的一个checkpoint
- 3.定位在这个checkpoint时flush到磁盘的数据页,检查checksum。如果不正确,说明这个页在上次写入是不完整的,从doublewrite buffer里把正确的页读出来,更新到buffer中的页
- 4.分析redo log,标识出未提交事务
- 5.顺序执行redo
- 6.rollback未提交的事务
网友评论