博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Undo日志
阅读量:6312 次
发布时间:2019-06-22

本文共 3097 字,大约阅读时间需要 10 分钟。

hot3.png

在存储系统中,redo日志可以应对那些已经执行成功的事务没有反映到磁盘时系统崩溃情形的数据恢复,但是,有时候会有另外一种情形,一个事务中,有多步操作,有部分操作已经成功,有部分操作失败,导致整个事务不能被完整执行,或者一个事务的执行过程中,人为的终止此事务的执行。不能被完整执行的事务,其中已经执行的步骤对于数据元素的修改已经反映到磁盘,或者反映到内存。根据事务的原子性原语,对于没有执行成功的事务,必须被当着像没有发生过一样。这种情形下,使用另外一种日志---undo日志,来保证事务的原子性,undo日志也具有三个原语

  1. <BEGIN T>

  2. <T, A, x>  此原组表示事务T中,数据元素A被修改前的旧值是x 

  3. <COMMIT T>

在更新一个数据元素过程中,系统遵循下面的规则,

  1. 修改任何一个数据元素前,向日志文件添加一个undo日志记录,以保存此数据元素被修改前的旧值

  2. 根据事务的隔离原则,在添加<COMMIT T>成功后,当前事务中对于数据元素的修改才能被反映到系统

我们仍然以从账户A转50元到账户B,在前一个涌道图中,增加undo日志,为了表示方便,这里假设同时写redo日志和undo日志

+----------------+-------+-------+----------------+----------------+|      OP        |  M-A  |  M-B  |   REDO LOG     |   UNDO LOG     |+----------------+-------+-------+----------------+----------------+|                |       |       | 
     | 
     |(1)| READ(A, a)     | 200   |       |                |                |(2)| a = a - 50     |       |       |                |                |(3)|                |       |       | 
   | 
   |(4)| OUTPUT(A, a)   | 150   |       |                |                |(5)| READ(B, b)     |       | 200   |                |                |(6)| b = b + 50     |       |       |                |                |(7)|                |       |       | 
   | 
   |(8)| OUTPUT(B, b)   |       | 250   |                |                |(9)|                |       |       | 
    | 
    |(10) +----------------+-------+-------+----------------+----------------+

在这个示意图中,如果崩溃点是发生在(10)之后,说明此事务已经被完整的执行,可以被重做redo日志,恢复数据;如果崩溃点发生在步骤(6),此时,A的新值150已经被反映到磁盘中,根据事务的原子性,我们需要撤销这个操作,幸运的是,undo日志记录中有数据元素A的旧值200,把这个旧值写回磁盘的操作叫undo操作或者叫撤销操作。在这个例子中,崩溃点发生在步骤(6) ~ (10)之间皆表示这个事务需要被撤销。

系统恢复后,从undo日志的尾部开始扫描undo日志记录,遵循下面的规则

  1. 如果一个事务具有<COMMIT T>记录,则忽略此事务,如果发现一个事务没有<COMMIT T>记录,或者具有<ABORT T>记录,则撤销此事务

  2. 如果事务Ti早于事务Tj发生,先撤销事务Tj,再撤销事务Ti

  3. 在一个被撤销的事务内,如果undo日志记录<T, A, x>早于<T, B, y>发生,则先执行<T, B, y>,再执行<T, A, x>

  4. 事务被撤销后,向日志文件增加<ABORT T>记录,告诉系统,不再撤销此事务。

redo日志所使用的检查点技术也可以应用在undo日志。

还有一种应对故障的方式是讲redo日志和undo日志进行合并,称为redo/undo日志,使用一个四元组<T, A, x, y>表示事务使用新值x更新数据元素A,其旧值是y,系统在记录redo/undo日志时,只需要遵循一条规则

  1. 在更新数据元素前,把此数据元素的新值和旧值使用<T, A, x, y>的形式写入日志文件。

对于账户A转50元到账户B这个操作,带有redo/undo日志的涌道图,形式如下

+----------------+-------+-------+------------------+|      OP        |  M-A  |  M-B  |  REDO/UNDO LOG   |+----------------+-------+-------+------------------+|                |       |       | 
       |(1)| READ(A, a)     | 200   |       |                  |(2)| a = a - 50     |       |       |                  |(3)|                |       |       | 
   |(4)| OUTPUT(A, a)   | 150   |       |                  |(5)| READ(B, b)     |       | 200   |                  |(6)| b = b + 50     |       |       |                  |(7)|                |       |       | 
   |(8)| OUTPUT(B, b)   |       | 250   |                  |(9)|                |       |       | 
      |(10) +----------------+-------+-------+------------------+

使用redo/undo日志恢复数据时,首先从日志的头部开始扫描,对于所有已经commit的事务,组成redo列表,执行重做操作,再从日志的尾部扫描,组成undo列表,执行撤销操作。

redo日志的检查点也适用redo/undo日志。

原创日志,若有转载,请著名作者

转载于:https://my.oschina.net/yishanhu/blog/465947

你可能感兴趣的文章
sublime text 3 快捷键大全
查看>>
WPF BitmapImage 占用资源无法释放、无法删除问题
查看>>
Welcome to Apache OpenNLP
查看>>
UltraMemcache , UltraMySQL 初试
查看>>
水木→函数式编程语言→lisp是不是主要用来编网站的?
查看>>
分享:WebView使用总结(应用函数与JS函数互相调用)
查看>>
MySQL TIPS
查看>>
Alamps学习设计模式之备忘录模式(笑话:劫个色OR抢个鸡蛋版)
查看>>
iphone使用xib界面与和代码相关联的方法
查看>>
struts2对拦截器使用带实例
查看>>
Subset leetcode java
查看>>
【EM】代码理解
查看>>
国内车联网行业 2015年发展趋势
查看>>
winform 窗体实现增删改查(CRUD)窗体基类模式
查看>>
数据挖掘之推荐系统实践--基于用户的协同过滤算法
查看>>
让 ASP.NET JS验证和服务端的 双验证 更简单
查看>>
php 反射
查看>>
MyEclipse内存不足问题
查看>>
Deep Learning 深度学习 学习教程网站集锦
查看>>
Canu FAQ常见问题
查看>>