转自:http://biancheng.dnbcw.info/oracle/309191.html

Rollbackundo到底做了些什么?

从概念上讲,undo正好与redo相对。当你对数据执行修改时,数据库会生成undo信息,这样万一你执行的事务或语句由于某种原因失败了,或者如果你用一条rollback语句请求回滚,就可以利用这些undo信息将数据还原到修改前的样子。Redo用于在失败时还原事务(即恢复事务),undo则用于取消一条语句或者一组语句的作用。与redo不同,undo在数据库内部存储在一组特殊的段中,这称为undo段(undo segment)。

通常对undo有一个误解,认为undo用于将数据库物理地恢复到执行语句或者事务之前的样子,但实际上并非如此。数据库只是逻辑地恢复到原来的样子,所有修改都被逻辑地取消,但数据结构以及数据库块本身在回滚后可能大不相同。原因在于:在所有的多用户系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要功能之一就是协调对数据的并发访问。也许我们的事务在修改一些块,而一般来讲往往会有许多其他的事务也在修改这些块。因此,不能简单地将一个块放回到我们事务开始前的状态,这样会撤销其他人(其他事务)的工作!

例如,我们的事务执行一个insert语句,这条语句导致分配一个新区段(也就是说,导致表的空间增大)。通过执行这个insert,我们将得到一个新的块,格式化这个块以便使用,并在其中放上一些数据。此时,可能出现某个事务,他也向这个块中插入数据。如果要回滚我们的事务,显然不能取消对这个块的格式化和空间分配。因此,oracle回滚时,它实际上会做与先前逻辑上相反的工作。对于每个insert,oracle会完成一个delete。对于每个delete,oracle会执行一个insert。对于每个update,oracle则会执行一个“反update”,或者执行另一个update将修改的行放回去。当然这种undo生成对于直接路径操作(direct path operation)不适用,直接路径操作能够绕过表上的undo生成。

为了更好的说明问题,下面做一个小小的测试,以便验证上述的正确性。以下就是一个简单测试的步骤:

(1)      创建一个新的空表。

(2)      对它做一个全表扫描,观察对该表所执行的I/O数量。

(3)      向表中填入许多行(暂时不提交commit)

(4)      回滚这个工作。

(5)      再次进行全表扫描,观察对该表所执行的I/O数量。

好了,下面我们一起来做一个简单的测试工作:

首先,创建一个空表:

hongsy@test>create table t

2  as

3  select *

4  from all_objects

5  where 1=0;

表已创建。

hongsy@test>select * from t;

未选定行

hongsy@test>set autotrace traceonly statistics

hongsy@test>select * from t;

未选定行

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

3  consistent gets

0  physical reads

0  redo size

915  bytes sent via SQL*Net to client

372  bytes received via SQL*Net from client

1  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

0  rows processed

hongsy@test>set autotrace off

hongsy@test>insert into t select * from all_objects;

已创建31620行。

hongsy@test>rollback;

回退已完成。

hongsy@test>select * from t;

未选定行

hongsy@test>set autotrace traceonly statistics

hongsy@test>select * from t;

未选定行

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

 436  consistent gets

0  physical reads

0  redo size

915  bytes sent via SQL*Net to client

372  bytes received via SQL*Net from client

1  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

0    rows processed

前面的insert 导致将一些块增加到表的高水位线(high-water mark,HWM)之下,这些块没有因为rollback而消失,它们还在那里并且已经格式化,只不过现在为空。全表扫描必须读取这些块,看看其中是否包含行。通过比较上面对同一表查询的两个统计信息我们得出:undo操作只是回滚了数据库的逻辑结构,而没有撤销其物理结构。

以上是本人近期对undo的研究之一,写下自己的学习心得,供大家讨论。限于本人学识水平,难免存在问题,请批评指正。如有异议请email:hongsy@e-u.cn。

转Rollback后undo到底做了些什么?的更多相关文章

  1. linux内核中宏likely和unlikely到底做了些什么?

    1. 先看看它们长啥样吧!(它们有两种定义,第一种是使能了程序trace功能的宏定义,第二种是普通的宏定义,咱们分析普通宏定义吧) # define likely(x) __builtin_expec ...

  2. js中的new()到底做了些什么??

    要创建 Person 的新实例,必须使用 new 操作符.以这种方式调用构造函数实际上会经历以下 4个步骤:(1) 创建一个新对象:(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新 ...

  3. Java环境的搭建及用记事本来揭露下JDK到底做了些什么

    和我一样的新手想学Java就从自己搭建环境开始,请看完这边文章,我搜集资料的整合. Java的标准版本是Java SE,所说的JDK(Java Development Kits)就是Java SE的开 ...

  4. iOS 中push和pop到底系统做了些什么事

    iOS中的push和pop是一个很常用的视图切换方法,他们是成对出现的, 简而言之,push就是压栈,pop就是出栈! [self.navigationController pushViewContr ...

  5. AFNetworking到底做了什么

    写在开头: 作为一个iOS开发,也许你不知道NSUrlRequest.不知道NSUrlConnection.也不知道NSURLSession...(说不下去了...怎么会什么都不知道...)但是你一定 ...

  6. AFNetworking到底做了什么?(二)

      接着上一篇的内容往下讲,如果没看过上一篇内容可以点这: AFNetworking到底做了什么? 之前我们讲到NSUrlSession代理这一块: 代理8: /* task完成之后的回调,成功和失败 ...

  7. dreamvc框架(三),dispartcher做了些什么

    这一篇我会介绍一些dreamvc的核心类Dispatcher都做了些什么,首先我们先来看一看init方法,这是在DispatcherServlet和DispatcherFilter里面都会调用到的一个 ...

  8. 转 OGG add trandata 到底做了什么

    有的时候我们做OGG的时候add trandata会出现异常. 这里就剖析一下add trandata到底做了什么 GGSCI (yjfora81 as ggs_admin@testdb) 2> ...

  9. vue.js中,input和textarea上的v-model指令到底做了什么?

    v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能: 对,它本质上只是一个语法糖,但到底是一 ...

随机推荐

  1. bootstrap IE8 相互兼容

    针对 IE8 仍然需要额外引入 Respond.js 文件(由于仍然利用了浏览器对媒体查询(media query)的支持,因此还需要做处理) <html lang="zh-cn&qu ...

  2. Linux的一些简单命令(三)

    1.解压缩算法:使用gzip算法进行解压缩,   压缩语法:gzip filename   解压语法:gzip -dv filename 2.解压缩算法:使用bzip2算法进行解压缩, 压缩语法:bz ...

  3. 制作Ubuntu14.04的Openstack镜像

    下载好Ubuntu官方镜像安装文件:不要使用desktop版,在virtualbox和vm上都安装报错,因为不需要桌面,所有没去管了. 第一步.准备好如下文件: 1.ubuntu-14.04.4-se ...

  4. [SOJ] can I post the letter?

    1155. Can I Post the letter Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description I am a t ...

  5. 使用python修改QQ密保(脚本)

    一.基于以下目的: 1.为了增加对Http协议理解能力,对QQ密保修改的请求进行了分析 2.为了锻炼python的编写能力 3.对web综合知识的理解 花了点时间写了这个脚本,下面介绍脚本的过程 二. ...

  6. As input tri-stated

    前些日子正好看到了riple兄的<一波三折--危险的"未分配"引脚>一文,颇受启发.正好最近也遇上了类似的问题,也可谓一波三折,还好最后摆平了,要不煮熟的鸭子可就要飞了 ...

  7. request相关研究

    一.什么是httpservletrequest 用来处理一个对Servlet的HTTP格式的请求信息. 二.httpservletrequest的作用是什么 优点: 公共接口类HttpServletR ...

  8. Javascript Date 判断输入日期是否正确

    JavaScript的Date对象有容错性,可将随意给定的日期的年月日自动生成正确的日期时间 //JavaScript中Date对象容错性 function dateCheck(){ var date ...

  9. H264帧内预测模式编号的编码过程

    1 本文词汇约定 宏块:H264编码基本单元,16x16像素(或采样)构成 块:   由8x8像素(或采样)构成的单位 子块:   由4x4像素(或采样)构成的单位 2 帧内亮度预测模式 H264规范 ...

  10. Textarea自适应高度 JS实现,兼容IE6\7\8\9\10\11

    <!DOCTYPE html> <html> <head> <title>autoresizing textarea</title> < ...