P1 事务开始
P2 记录a=1到undo.log buffer
P3 修改a=3 ? 这一步去哪里了
P4 将undo log写到磁盘
P5 将数据写到磁盘
P6 事务提交 生成commit.log,
P7 删除undo.log
如果在P2结束后挂了,没事 a=1
如果在P3结束后挂了,没事 a=1
如果在P4结束后挂了,没事 a=1 有个日志文件
如果在P5结束后挂了,数据a=3,有日志undo.log 记录了a=1 重启后a=1,系统将a恢复
如果在P6结束后挂了,数据a=3,有个commit.log 记录了a=1 重启后a=3
undo的
https://blog.csdn.net/ggxxkkll/article/details/7616739
https://segmentfault.com/a/1190000017888478
简要概括规则U1和U2,与一个事务相关额内容必须按如下顺序写到磁盘:
指明所改变数据库元素的日志记录
改变的数据库元素数据本身
COMMIT日志记录
undo的过程有两个日志文件undo.log commit.log
undo规则
1.commit的事务不做处理,没有commit的事务undo回滚
2.数据库的数据进行修改之前,必须先保证事务日志undo.log已经持久化
3.COMMIT日志记录commit.log必须是数据库数据持久化之后
系统扫描规则
1.回放日志,需要扫描所有日志文件,并且日志文件不能删除
CheckPoint (检查点)回滚机制
日志在事务开启前记录一个START_CKPT事务结束后记录END_CKPT
这样回滚到上一个END_CKPT即可
REDO的策略
对于没有checkpoint的日志进行恢复需要:首先从后往前扫描日志:记录所有已经commit的事务,对于没有commit的事务在日志末尾追加abort; 然后从前往后扫描日志,redo所有已经commit的事务日志。
关键区别
Undo 日志要求数据在事务结束后立即写到磁盘,可能增加磁盘I/O数
Redo 日志要求我们在事务提交和日志记录刷新以前将所有修改过的块保留在缓冲区中,可能增加事务需要的平均缓冲区数
当使用undo/redo日志时,与一个事务相关的材料写到磁盘的顺序为:
1.记录update日志
2.更新数据库(不一定持久化,写入缓存中)
3.在合适的时候写commit日志 (在磁盘上任何数据库元素的修改之前或之后,即第3步可能比第2步可能早,或者可能晚)
edo/undo log的checkpoint方式与redo log相似:
1.写日志START_CKPT<T1, T2, ..., Tn>;其中Ti表示当前正在进行还没有commit的事务
2.将所有缓存中的脏数据持久化到磁盘
3.写日志END_CKPT
https://www.cs.sjsu.edu/faculty/pollett/157b.12.05s/Lec20042005.pdf
官方原文
https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-logs.html