首页 cmu 15-445

数据恢复就是为了在故障时也要保证ACID

checkpoint 存档点

存档点的那个点不好找,

扫描日志去查找没有提交的txn可能花费了很长时间

存档频率不好把握

aries

algrithms for recovery and isolation exploting semantics数据库恢复原型算法

  • WAL 预写日志

steal+no force非强制+窃取

  • repeating history during redo

需要回放的回放

  • logging changes during undo

跑了一半的事务undo

任务:

  • log sequence numbers lsn日志序列号
  • normal commit & abort operations 事务正常commit与回滚
  • fuzzy CheckPointing 一种优化
  • recovery algorithm 算法本身

LSN (log sequence numbers) 日志序列号

flushedLSN,最后一个进磁盘的LSN(意思是之前的都进去了,之后的都没进去)

pageLSN,buffer pool的每个page中,该page上最后一次更新对应的LSN

recLSN,存在同样的位置,从这个页上一次刷盘之后对这个页的第一个操作

lastLSN,在Txn中,事务留下的最后一条日志记录的LSN

masterRecord,在磁盘中,最后的存档点对应的LSN

image-20220307110248457.png

脏页是可以被写入磁盘的,pageLSN <= flushedLSN

flushedLSN = 16,maseterRecord = 007,这个时候是不能刷盘的,因为之前的LSN没有完全刷入磁盘(buffer pool中的pageLSN != 磁盘中的pageLSN),所以把

image-20220307112224648.png

所有的日志记录都有编号,

normal execution

  • 所有的数据记录都在一个页中
  • 磁盘写入是原子的
  • 严格2PL
  • steal+no-force

commit过程:

在log加一条commit指令

在提交时要保证有关这个事务的所有日志全部都刷入盘中

  • 刷盘操作是连续写的
  • 日志文件的页是有多条文件记录的

当txn commit完全成功的时候加一条 txn-end

过程:

T4 commit的时候,先写一个commit日志,并把12~15全部刷入磁盘中,并保证flushedLSN=15,用户认为结束了,但是其实还没有结束,因为只有日志落入磁盘了,但是脏页数据还没有落盘

当这一页满了或者其他情况,要讲buffer pool中的page放入磁盘的时候要在日志中加入TXN-END标识符表示彻底结束了

image-20220307113515546.png

这时候就可以删除之前的内存日志缓存

image-20220307114119972.png

txn abort:

首先回滚只是特殊情况,我们要在日志再加一个字段:prevLSN,代表的是这条日志的上一条日志是几号,类似链表记录上一条地址,因为日志是所有txn共用的,所以更容易实现回滚

image-20220307114416339.png

原则:回滚是可以回滚的,但是回滚过程也是要记录的,记录在CLR中

CLR(compensation log records) 清空日志

CLR是不需要强制刷盘的,目的就是记录回滚日志

image-20220307114713192.png

回滚的具体操作:

  • 写一个ABORT日志
  • 反向回滚日志,并追加清理日志
  • 清理完成后加TXN-END

清理日志是不需要回滚的

fuzzy checkpointng

模糊存档点(对存档点的优化)

为什么checkpoint会影响速度:

  • 打点的时候要停下其他的所有txn
  • 要让所有正在做的都做完
  • 讲脏页刷入磁盘

改进方案:

  • 不要等待所有进行中的事务都结束,仅仅让他们停下就行了,加锁刷盘

需要做一些工作:

  • ATT(active transaction table) 正在执行的活动事务表
  • DPT(dirty page table) 脏页表

ATT : 活动事务表

  • txnId 事务id
  • status 模式
  • lastLSN 最后的LSN

当事务这的做完(TXN-END),才能删ATT

status 状态:

  • R-running 运行中
  • C-committing 提交中
  • U-candidate for undo 尚未提交(undo 候选者)

DPT 脏页表

  • recLSN,代表着第一个让这个页变脏的LSN

就是在checkpoint的时候加了ATT与DPT

能够了解到T2与T3是依旧活跃的,p22是已经进去了

image-20220307140711452.png

原本策略是checkpoint要讲所有脏页与事务都要完成,现在是允许不做完

新的想法:fuzzy checkpoints 模糊的检查

  • checkpoint-begin
  • checkpoint-end

可以发现之间是有其他事务在进行操作等待,记录操作之间有那些操作在进行,但是如果这个txn是在之间start时,就不记录,用checkpoint-begin做那个操作点

image-20220307141207540.png

ARIES 算法 :

  • analysis 分析,读WAL文件的MasterRecord,找那个begin,分析上下日志
  • redo
  • undo

analysis :

找到last successful checkpoint

如果找了了一个TXN-END,表示这个事务已经成功结束了,就不用管这个txn(从ATT把他删了就行)

  • 把事务放入ATT中暂时让他变成undo状态
  • 如果发现commit,就把他的状态变成commit

如果发现有修改的语句,如果这个页没在DPT中,就把这个页放入DPT中,记录这个页的LSN放入recLSN

分析阶段做完就变成:

  • ATT记录到数据库崩溃时,系统有多少事务是活着的
  • DPT记录到数据库崩溃时,系统有多少脏页没进磁盘

image-20220307143041444.png

redo phase:

把需要回滚和不需要回滚的都重做,CLR也要重做

把脏页从recLSN开始重做,有两个特殊情况

  • DPT表中没有这个页,就不用处理这个页(本就不是脏页)
  • DPT中有这个页,但是LSN比recLSN还小就不用管

状态是C的就redo,并写一个TXN-END,并从ATT中移除

undo phase:

从ATT中找到状态为U的事务undo,可以用lastLSN找那个记录

这时候宕机

image-20220307150318762.png

1,做表

image-20220307150352824.png

undo T2先回滚60,再记录下一个20,T3回滚50,T3 回滚结束,刷盘

image-20220307150607934.png

但是这个时候,T3回滚完了,又停电了,T2怎么办,重启之后重新做表:继续操作

image-20220307150936760.png

三个时间段断电都无所谓

大家都不要写超长的事务,对大家都好




文章评论