一. 什么是redo(用于前滚数据)

redo也就是重做日志文件(redo log file),Oracle维护着两类重做日志文件:在线(online)重做日志文件和归档(archived)重做日志文件。这两类重做日志文件都用于恢复;其主要目的是,万一实例失败或介质失败,它们能够恢复数据。

二. 什么是undo(用于回滚数据)

从概念上讲,undo正好与redo相对。你对数据执行修改时,数据库会生成undo信息,这样万一你执行的事务或语句由于某种原因失败了,或者如果你用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据放回到修改前的样子。redo用于在失败时重放事务(即恢复事务),undo则用于取消一条语句或一组语句的作用。

三. 对undo段的一个误解

通常对undo有一个误解,认为undo用 于数据库物理地恢复到执行语句或事务之前的样子,但实际上并非如此。数据库只是逻辑地恢复到原来的样子,所有修改都被逻辑地取消,但是数据结构以及数据库 块本身在回滚后可能大不相同。(比如一个插入操作,新分配了一些数据块。后来事务失败,插入操作全部回滚,新分配的一些数据块还是存在的)

原因在于:在所有多用户系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要功能之一就是协调对数据的并发访问。也 许我们的事务在修改一些块,而一般来讲往往会有许多其他的事务也在修改这些块。因此,不能简单地将一个块放回到我们的事务开始前的样子,这样会撤销其他人 (其他事务)的工作!

例如,假设我们的事务执行了一个INSERT语句,这条语句导致分配一个新区段(也就是说,导致表的空间增大)。通过执行这个INSET,我们将得到一个新的块,格式化这个块以便使用,并在其中放上一些数据。此时,可能出现另外某个事务,它也向这个块中插入数据。如果要回滚我们的事务,显然不能取消对这个块的格式化和空间分配。因此,Oracle回滚时,它实际上会做与先前逻辑上相反的工作。对于每个INSERT,Oracle会完成一个DELETE。对于每个DELETE,Oracle会执行一个INSERT。对于每个UPDATE,Oracle则会执行一个“反UPDATE“,或者执行另一个UPDATE将修改前的行放回去。

所以有一种异常情况就很容易解释了,一个表明明只有1000行左右的数据,一条select * from table 语句可能需要耗时1,2分钟。这张表应该是经常进行新增删除操作的表,比如我新增了1000万行数据,然后又将这些数据删除。对这个表进行全表扫描的时候,仍然会去扫描这1000万行以前所占用的那些数据块,看看里面是否包含数据。也就是oracle里面所说的高水平线(HWM),这些数据块都增加到了高水平线下面,oracle会扫描所有高水平线下的数据块。

四. redo与undo如何协作保证数据完整与安全性

以一个例子来说明一下(一个事务包含一组sql语句):

insert into t(x,y) values(1,1);

update t set x = x+1 where x = 1;

delete from t where x = 2;

1.INSERT

对于第一条INSERT INTO T语句,redo和undo都会生成。所生成的undo信息足以使INSERT“消失“。INSERT INTO T生成的redo信息则足以让这个插入”再次发生“。

插入发生后,系统状态如图9-1所示。


     这里缓存了一些已修改的undo块、索引块和表数据块。这些块得到重做日志缓冲区中相应条目的“保护“。

假想场景一:系统现在崩溃

系统现在崩溃是没什么关系的。SGA会被清空,但是我们并不需要SGA里的任何内容。重启动时就好像这个事务从来没有发生过一样。没有将任何已修改的块刷新输出到磁盘,也没有任何redo刷新输出到磁盘。我们不需要这些undo或redo信息来实现实例失败恢复。

假想场景二:缓冲区缓存现在已满

在这种情况下,DBWR必须留出空间,要把已修改的块从缓存刷新输出。如果是这样,DBWR首先要求LGWR将保护这些数据库块的redo条目刷新输出。DBWR将任何有修改的块写至磁盘之前,LGWR必须先刷新输出与这些块相关的redo信息。这是有道理的——如果我们要刷新输出表T中已修改的块,但没有刷新输出与undo块关联的redo条目,倘若系统失败了,此时就会有一个已修改的表T块,而没有与之相关的redo信息。在写出这些块之前需要先刷新输出重做日志缓存区,这样就能重做(重做)所有必要的修改,将SGA放回到现在的状态,从而能发生回滚。(也就是任何一条修改记录持久化到数据文件的时候,必须先把它对应的redo条目持久化到磁盘文件,以保证这个过程的可逆性。你可能会问,redo不是前滚吗,可逆应该是回滚,怎么跟redo有关系呢?其实是redo段里面包含了undo段的信息)

2.UPDATE

UPDATE所带来的工作与INSERT大体一样。不过UPDATE生成的undo量更大;由于存在更新,所以需要保存一些“前“映像。系统状态如下图所示。


     块缓冲区缓存中会有更多新的undo段块。为了撤销这个更新,如果必要,已修改的数据库表和索引块也会放在缓存中。我们还生成了更多的重做日志缓存区条目。下面假设前面的插入语句生成了一些重做日志,其中有些重做日志已经刷新输出到磁盘上,有些还放在缓存中。

假想场景一:系统现在崩溃

启动时,oracle会去读取重做日志文件,会发现有一些redo文件对应的修改记录还没有持久化到数据文件。然后发现这些redo文件是一个事务里面的,于是得回滚这个事务。步骤如下:

a. 根据redo文件,进行数据前滚,会在内存中构造出undo块、已修改的表块,以及已修改的索引块。

b. 根据undo块进行数据回滚,回滚到插入前的数据状态。

3.DELETE

       同样,DELETE会生成undo,块将被修改,并把redo发送到重做日志缓冲区。这与前面没有太大的不同。实际上,它与UPDATE如此类似,所以我们不再啰嗦,直接来介绍COMMIT。

4.COMMIT

在此,Oracle会把重做日志缓冲区刷新输出到磁盘,系统状态如下图所示。


     假设目前已修改的块放在缓冲区缓存中;有一些块已经刷新输出到磁盘上,有一些还没有。但是如果重做这个事务所需的全部redo都安全地存放在磁盘上,那么修改就是永久的了,即使有一些修改的块还没有刷新输出到磁盘上。(commit并不是把所有的修改持久化到了数据文件,而是所有的redo文件持久化到磁盘文件,只要所有的重做日志文件持久化到磁盘,这些修改就是永久的了。)如果从数据文件直接读取数据,可能会看到块还是事务发生前的样子,因为很有可能DBWR还没有(从缓冲区缓存)写出这些块。这没有关系,如果出现失败,可以利用重做日志文件来得到最新的块。

原文地址:http://liwenshui322.iteye.com/blog/1488949

Oracle redo与undo 第一弹的更多相关文章

  1. Oracle redo与undo 第二弹

    首先看一下undo与redo的字面意思:   undo:撤销,也就是取消之前的操作.   redo:重做,重新执行一遍之前的操作. 什么是REDO REDO记录transaction logs,分为o ...

  2. Oracle redo与undo浅析

    http://liwenshui322.iteye.com/blog/1488949 一. 什么是redo(用于前滚数据) redo也就是重做日志文件(redo log file),Oracle维护着 ...

  3. Oracle redo与undo

    Undo and redo Oracle最重要的两部分数据,undo 与redo,redo(重做信息)是oracle在线(或归档)重做日志文件中记录的信息,可以利用redo重放事务信息,undo(撤销 ...

  4. Oracle redo/undo 原理理解

    一. 什么是redo(用于重做数据) redo也就是重做日志文件(redo log file),Oracle维护着两类重做日志文件:在线(online)重做日志文件和归档(archived)重做日志文 ...

  5. 【转】ORACLE的REDO与UNDO

    一.什么是redo?redo:oracle在在线或者归档重做日志文件中的记录的信息,外以出现失败时可以利用这些数据来"重放"事务.每个oracle数据都至少有二个在线重做日志组,每 ...

  6. Oracle 9 - redo和undo

    1.redo redo 有在线redo日志和归档redo日志, 从Oracle 10g开始还新增加了flashback技术. 每个Oracle数据库至少有2个在线重做日志组,循环写. 只有INSERT ...

  7. Oracle redo undo

    通常对undo有一个误解,认为undo用于数据库物理地恢复到执行语句或事务之前的样子,但实际上并非如此.数据库只是逻辑地恢复到原来的样子,所有修改都被逻辑地取消,但是数据结构以及数据库块本身在回滚后可 ...

  8. [Oracle] Redo&Undo梳理

    Oracle Redo&undo Oracle中的redo和undo是关键技术的核心, 诸如实例恢复, 介质恢复, DataGuard, 闪回机制等都是给予redo和undo的, 所以很有必要 ...

  9. 【Oracle】redo与undo

    一 .redo(重做信息) 是Oracle在线(或归档)重做日志文件中记录的信息,万一出现失败时可以利用这些数据来“重放”(或重做)事务.Oracle中记录这些信息的文件叫做redo log file ...

随机推荐

  1. BFC(块级 格式化上下文)的理解

    本文转载(https://segmentfault.com/a/1190000013647777) 一.BFC的概念 1.规范解释 块格式化上下文(Block Formatting Context,B ...

  2. 多段图动态规划dp

    多段图问题是DP的基础题目.大体的意思是有一个赋权有向图,其顶点集被分为几个子集.求经过每个子集从源点到终点的最短路径 import java.util.ArrayList; import java. ...

  3. mysql 忘记root密码的解决办法

    1.修改MySQL的登录设置: # vim /etc/my.cnf 在[mysqld]的段中加上一句:skip-grant-tables 例如: [mysqld] datadir=/var/lib/m ...

  4. CefSharp试用

    Github地址: https://github.com/cefsharp/CefSharp 首先下载所有源代码下来 然后直接打开Sln 然后就可以直接调试WinForm.Wpf的Example了 注 ...

  5. HDU 3592 World Exhibition (差分约束,spfa,水)

    题意: 有n个人在排队,按照前后顺序编号为1~n,现在对其中某两人的距离进行约束,有上限和下限,表示dis[a,b]<=c或者dis[a,b]>=c,问第1个人与第n个人的距离最多可能为多 ...

  6. Linux OpenGL 实践篇-16 文本绘制

    文本绘制 本文主要射击Freetype的入门理解和在OpenGL中实现文字的渲染. freetype freetype的官网,本文大部分内容参考https://www.freetype.org/fre ...

  7. Berkeley DB (VC6.0 编译环境配置)

    操作系统:winxp VC环境:VC6.0 必需文件:Berkeley DB安装文件(db-.msi) 下载地址:http://www.oracle.com/technology/software/p ...

  8. [论文理解]SSD:Single Shot MultiBox Detector

    SSD:Single Shot MultiBox Detector Intro SSD是一套one-stage算法实现目标检测的框架,速度很快,在当时速度超过了yolo,精度也可以达到two-stag ...

  9. [视觉识别]OpenCV + CNN 大神符识别

    数据集 Mnist数据集:http://yann.lecun.com/exdb/mnist/ 训练 import numpy as np from keras.datasets import mnis ...

  10. 基于 Ubuntu + nextCloud 搭建自己的私人网盘

    提醒一下,如果之前通过apache搭建了网站,不要用snap命令来搭建,否则,至少有一个无法正常运行(不要问我怎么知道的,都是血的教训啊). 你可以通过腾讯云的实验主机进行尝试. 1.基础设置 切换为 ...