Redo日志
undo日志有一个潜在的问题,即我们在将书屋改变的所有数据写到磁盘前不能提交该事务。有时,如果让数据库修改暂时只存在于主存中,我们可以节省磁盘IO;只要在崩溃发生时有日志可以恢复,这样做就是安全的。
如果我们使用redo日志机制,立即将数据元素备份到磁盘的需要就可以被避免。redo日志和undo日志的主要区别是:
1. undo日志在恢复时消除未完成事务的影响并忽略已提交事务,而redo日志忽略未完成的事务并重复已提交事务所做的改变。
2. undo日志要求我们在COMMIT日志记录达到磁盘前将修改后的数据元素写到磁盘,而redo日志要求COMMIT记录在任何修改后的值到达磁盘前出现在磁盘上
3. 当遵循undo规则U1和U2时,在恢复时我们需要的是发生改变的数据源的旧值,而是用redo日志恢复时,我们需要的是新值。
规则
在redo日志中,日志记录<T, v="" x,="">的含义是“事务T为数据库元素X写入的新值v”。在这个记录中没有指出X的旧值。每当一个事务T修改一个数据元素X时,必须网日志中写入一条形如<T, v="" x,="">的记录。
对于redo日志,数据和日志项达到磁盘的顺序可以用一条“redo规则”描述,这条规则成为先写日志规则:
R1: 在修改磁盘上的任何数据元素X以前,要保证与X的这一修改先骨干的所有的日志记录,包括更新记录<T, v="" x,="">及记录,都必须出现在磁盘上。
事务的COMMIT记录只有在事务完成后才能写入日志,因而提交记录必然在所有更新日志记录后,所以当使用redo日志时,与一个事务相关的材料写入到磁盘的顺序为:
1. 指出被修改元素的日志记录。
2. COMMIT日志记录
3. 改变数据元素自身
下面我们按照undo日志规则来考虑如下的事务T:
A := A*
B := B*
| 步骤 | 动作 | t | M-A | M-B | D-A | D-B | 日志 |
|------+-------------+----+-----+-----+-----+-----+------------|
| ) | | | | | | | <START T> |
| ) | READ(A, t) | | | | | | |
| ) | t := t* | | | | | | |
| ) | WRITE(A, t) | | | | | | <T, A, > |
| ) | READ(B, t) | | | | | | |
| ) | t := t* | | | | | | |
| ) | WRITE(B, t) | | | | | | <T, B, > |
| ) | | | | | | | <COMMIT T> |
| ) | FLUSH LOG | | | | | | |
| ) | OUTPUT(A) | | | | | | |
| ) | OUTPUT(B) | | | | | | |
恢复
redo规则R1的一个重要推论是,只要日志中没有记录,我们就知道事务T对数据库所做的更新都没有写到磁盘上。因此,恢复时对未完成事务的处理就可以像它们从未发生似的。然而,已提交的事务存在问题,因为我们不知道他们的那些数据库改变已经写到磁盘。幸运的是,redo日志正好有我们需要的信息:新值。我们可以讲新值写到磁盘而不管他们是否已经在磁盘上。在系统崩溃后要使用redo日志恢复,我们需要做以下事情:
1. 确定已提交的事务。
2. 从收不开始扫描日志。对遇到的每一个<T, v="" x,="">记录:
a) 如果T是未提交的事务,则什么也不做
b)如果t是提交的事务,则为数据库元素X写入值v
3. 对每个未完成的事务T,在日志中写入一个记录并刷新日志。
我们考虑上图中的日志,看看在不同步骤上发生故障时如何进行恢复。
1. 如果故障发生在第9步的任何时候,那么记录已被刷新到磁盘。T是一个提交的事务。当向前扫描日志时,日志记录<T, 16="" a,="">和<T, 16="" b,="">将A和B写入16.请注意,如果故障发生在第10和11步之间,那么写A是多余的,而写B还未发生,因而将B改变为16是恢复数据库的一致状态所必须的。如果故障发生在第11步以后,那么些A和写B都是多余的但也是无害的。
2. 如果故障发生在第8和第9步之间,那么尽管记录写入了日志,但可能还没有到达磁盘(依赖于日志是否因其他原因而刷新)。如果该记录到达磁盘,则恢复如情况1那样进行,而如果该记录没能到达磁盘,那么恢复和下面的情况3一样。
3. 如果故障发生在第8步以前,那么记录肯定没有达到磁盘。因此,T被看做一个未完成的事务。磁盘上的A和B不为T做任何改变,而最后一条记录被写到日志中。
检查点
对于redo日志的检查点,这儿有一个undo日志中没有的问题。由于已提交事务做的数据修改拷贝到磁盘的时间可能比事务提交的时间晚的多,因此我们不能仅仅考虑在我们决定创建检查点时活跃的事务。在检查点的开始和结束之间我们必须将已被提交事务修改的所有数据库元素写到磁盘。
另一方面,我们不需要等待活跃事务提交或中止就能完成检查点,因为他们呢无论如何都不被允许在那个时候将它们写到磁盘。进行redo日志的非静止检查点步骤如下:
1. 写入日志记录,其中T1,...,Tk是所有活跃(即未提交的)事务,并刷新日志
2. 将START CKPT记录写入日志时所有已提交事务已经写到缓冲区但还没有写到磁盘的数据写到磁盘
3. 写入日志记录并刷新日志
例:下图给出了一个可能的redo日志,其中发生了一个检查点。当我们开始检查点时,只有T2是活跃的,但T1所写的A值可能已经到达磁盘。如果没有,那么我们必须在检查点结束前将A拷贝回磁盘。我们表明检查点的技术在几个其他的事件后发生:T2为数据库元素C写入一个值,一个新事务T3开始并为D写入一个值。在检查点结束后发生的唯一的事情是T2和T3提交。
<START T1>
<T1, A, >
<START T2>
<COMMIT T1>
<T2, B, >
<START CKPT(T2)>
<T2, C, >
<START T3>
<T3, D, >
<END CKPT>
<COMMIT T2>
<COMMIT T3>
使用带检查点的redo日志恢复
首先假设崩溃发生前日志中的最后一条检查点记录是。现在,我们知道在对应的前提交的事务已经将其修改写到了磁盘,因此我们不必关心如何恢复这些事务的影响。但是Ti中的任一事务或检查点开始后启动的任一事务及时已经提交,都仍然可能未将其修改转到磁盘上。因此,需要进行恢复,但可以只关心最后一个START CKPT(T1,...,Tk)中提到的事务Ti与该日志记录中在日志中出现后开始的事务。在搜索日志时,我们在找到最早的记录后就不必继续向后看。蛋清注意,这些START记录可能出现在任意多个检查点前。将一个事务的所有日志记录向后链接在一起可以帮助我们找到所需记录。
现在建设日志中的最后一条检查点记录是:
<START CKPT(T1,...,Tk)>
我们不能确定再次检查点开始前提交的事务是否已经将其修改写到磁盘上。因此我们必须搜索到前一记录,找到与之匹配的记录,并重做这些已经提交的事务,这些事务要么在START CKPT后开始要么在Si中。
例:考虑上图中的日志。如果故障在尾部发生,我们向后搜索,找到记录。我们只需知道将所有在写记录后开始的事务以及出现在该记录的列表中的事务(T2)作为重做的候选者。因此,我们的候选集合是{T2, T3}。我们找到了记录和,于是我们知道他们都必须重做。我们向后搜索日志直到记录,为提交的事务找到更新记录<T2, b,="" 10="">, <T2, 15="" c,="">, <T3, 20="" d,="">。由于我们不知道这些改变是否已经到达磁盘,我们分别为B、C、D重新写入值10、15、20.
现在我们假设崩溃在记录和之间发生。恢复过程与上述过程类似,只不过T3不再是已提交的事务,因此其修改<T3, 20="" d,="">不能被重做,并且在恢复中不对D做任何改变,尽管日志记录处于被检查记录范围内。恢复后我们也要在日志中写入一条记录。
最后,假设崩溃正好在记录前发生。原则上,我们必须i型昂后搜索到倒数第二个START CKPT记录并得到其活跃事务里诶包。但是,这种情况下没有前一个检查点,因为我们必须一致走到日志的开头。因此我们确定已提交的只有T1,重做其动作<T1, a,="" 5="">,并且在恢复后将记录和写入到日志中。
Redo日志的更多相关文章
- dump redo日志文件的信息
通常会用到以下两个命令:1.'alter session'命令用来dump redo日志的文件头2.'alter system dump logfile'命令用来dump redo文件的内容 以上命令 ...
- Oracle redo 日志切换时间频率
DB: 11.2.0.3.0 查看Oracle的redo日志切换频率 两条SQL,原理是一样的,第二个用到了统计函数 时间单位:分钟 方法一. select * from v$log a where ...
- 检查REDO日志相关信息并生成HTML文件的脚本
生成HTML格式的文件 内容有: 检查数据库版本.REDO日志组情况, 最近20次日志切换频率检查--日志间的归档时间间隔, 这对查看数据库的IO繁忙时段 统计指定日期当天每小时的归档日志产生量--日 ...
- 关于数据库一致改关闭下redo日志文件丢失的处理办法的总结
数据库一致性关闭下redo日志文件丢失的处理办法(归档和非归档都行) 1. inactive log 在一致性关闭后删除重启时可以在mount下(不丢失数据) alter database clea ...
- 添加redo日志组和添加日志组多元化
查看redo日志组的状态和日志的位置. SQL> 没有被使用,所以切几次日志,组合4已生效. SQL> select * from v$log; GROUP# THREAD# SEQ ...
- 数据库中的undo日志、redo日志
MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...
- 非IMU模式下DML语句产生的REDO日志内容格式解读
实验内容:非IMU模式下DML语句产生的REDO日志内容格式解读 最详细的解读是UPDATE的. 实验环境准备 11G中默认是开启IMU特性的,做此实验需要关闭此特性. alter system se ...
- Oracle11g温习-第七章:redo日志
2013年4月27日 星期六 10:33 1.redo (重做) log 的功能: 用于数据恢复 2.redo log 特征: [特征]: 1) 记录数据块的变化(DML.D ...
- 查看Oracle的redo日志切换频率
1.Oracle log 每次切换会记录到告警日志中 设想写个方案来查看log切换频率来判断Oracle log是否应该更改大小. 2.sql a.查看redo日志信息 select * from v ...
随机推荐
- 使用 Environment Indicator 模块区分不同的 Drupal 环境
每个 Drupal 网站建设人员到了某个时期,都会有误将线上站点当做本地站点进行修改的经历.尤其是在浏览器中打开了几十个页面时,很容易忘记究竟哪个是哪个. Environment Indicator ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- PMP--项目经理解决冲突的模式
如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 在实际工作过程中,作为一个项目经理,在解决冲突的时候可以通过多种模式解决,项目经理在 ...
- 华为OJ平台——查找组成一个偶数最接近的两个素数
import java.util.Scanner; /** * 问题描述:任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况, * 本题目要求输出组成指定偶数的两个素数差值最小 ...
- ubuntu解压zip文件乱码问题
我的zip文件里的内容是有中文名,也有密码,在网上找到几种解决办法只有一种可以,所以在这里记录一下: 首先是安装7zip来解压,7zip的解决办法在这里,但是无法解决我的问题,仍然有乱码问题 最后是在 ...
- leetcode 14
14. Longest Common Prefix Write a function to find the longest common prefix string amongst an array ...
- Command
#include <iostream> using namespace std; #define DESTROY_POINTER(ptr) if (ptr) { delete ptr; p ...
- 在网页中使用H1标记的须注意的事项
H1标签是网站排名非常重要的一个因素,因此我们一定要正确使用它. 本文为你介绍H1标签使用的七大注意事项: 1.每个页面都应该有H1标签,H1标签是每个网页不可缺少的要素. 2.使用H1标签的内容应该 ...
- Android照相机应用
前言 Android在设计架构的时候,采用了mashup(混搭)的设计理念,也就是说一切都是组建,自己写的是组件,别人提供的也是组件,使用的时候只要符合相关协议就可以把他们当作自己的组件.比如系统提供 ...
- js一些实用例子
1.获取焦点选中文本内容 $("#id").focus(function(){ this.select(); }); 2.表单提交方式 A.自动提交 setTimeout(func ...