UNDO
UNDO及事物
undo表空间是Oracle独有,在oracle开启一个事物之后,oracle对数据进行修改,同时,会把修改前的数据保存到UNDO表空间的UNDO段里。undo表空间中会自动分配undo段,这些undo段用来保存事务中的DML语句的undo信息,也就是来保存数据在被修改之前的值。在rollback,实例恢复(前滚),一致性读CR块的构造时会使用到undo信息。由于undo的引入,从而Oracle的select语句实现一致性读时,不需要任何锁。
undo表空间和其它表空间有很多类似的地方:undo数据块也会被读到buffer cache缓存起来,修改时也会产生redo log,数据也会写回到undo表空间的磁盘上。所以崩溃后,undo块的buffer cache也会恢复过来。
UNDO所有的段中,有一个段放入SYSTEM表空间的,其他都在UNDO表空间。DDL语句使用的就是SYSTEM这个undo段。当undo表空间UNDOTBS1损坏了时,也会使用SYSTEM这个undo段。随着系统的负载,undo段会根据需要自动增加。
段与段之间是不连续的,而段内部的block是连续的。从Oracle9i开始,undo表空间是自动管理,undo中的段、区等都是自动分配自动释放的,我只需要保证undo表空间有足够的大小。
一、undo表空间的作用
Oracle开始一个事务,当要修改数据时,会先将修改前的数据保存到undo表空间的undo段中。保存这些修改前的数据的原因下面这些场合需要undo数据:(1)事务的回滚;(2)实例恢复(回滚);回滚未提交事物对应的块。(3)一致性读时需要构造CR块。
在标准SQL中,为了防止并发事务中产生脏读,就需要通过加锁来控制.这样就会带来死锁、阻塞的问题,即时是粒度最小的行级锁,也无法避免这些问题.
为了解决这一矛盾,Oracle充分利用的回滚段,通过回滚段进行一致性读取,即避免了脏读,又大大减少了系统的阻塞、死锁问题.
二、UNDO段中区的状态
FREE:从来没用过的,可以用来写事物。
ACTIVE:有事物,没有提交。
INACTIVE:有事物,已经提交,没有过undo_retetion的时间。尽量不覆盖,但是可以被覆盖。如果改为GUARANTEE,则不能被覆盖。
EXPIRED:失效,可以覆盖。
Oracle尽量回使用free的undo区,不够再去扩充FREE区空间,再不够会使用expired的undo区,Oracle原则上是不覆盖inactive的区,但是当undo空间不够时,也可能会使用inactive状态的区。当INACTIVE的区保留了UNDO_RETETION的时间之后,会变成EXPIRED状态,就能覆盖。
Alter tablespace undotbs1 retention gurantee;
强制undo表中间里面的inactive的区,不能被覆盖。
三、事物相关概念
Oracle每产生一个事物,都会在v$transaction中生成一条记录,对应一个事物ID。
1、事物表
位于UNDO段头块(undo segment header)中,用以记录该UNDO段中的所有事物信息。事物表放置在undo段的第一个块中,因为块的大小限制,只能放47行。所以,每个回滚段只能有47个事物。一个事物启动后,需要在undo表空间寻找一个段头块,记录事物id。一个回滚段最多有47个活动事物,oracle尽量一个回滚段只有一个事物,然后均匀的将事物分布在各个段中。
2、事物槽
每一个数据块中都有自己的事物槽,在事物槽中,记录事物的状态,同时只有事物已经提交了,这个事物槽才能被其他事物覆盖。一个数据块最多能有255个数据槽,当事物槽的数量增加导致PCT-FREE空间不够时,就会导致事物槽争用,需要等待其他事物提交。oracle为了减少事物槽的争用,为多个事物分配多个不同的数据块。所以容易出现事物槽争用的,一般都是update和delete。
数据块dump得到的头部的ITL事务槽结构:

Itl: 事务槽编号;
xid: 事务ID;其中包含了xidusn, xidslot, xidsqn,所以xid指向了事务表的一个条目;
uba: 回滚块地址;(数据块中的uba在构造CR块时使用;而事务表中的uba在rollback时使用)
flag: 事务是否提交的标识;用于实现行级锁;
lck:该事务锁定了几行数据;
scn: 前面我们知道每一条日志记录有一个scn;
3、XID:事物编号
是事物的唯一标识,由三个部分组成,这三个部分也保证了它的唯一性。通过事物id,能直接找到事务表。
(1)使用了哪个回滚段的段头块。
(2)使用了47行的哪一行。
(3)覆盖了多少次。
4、UBA 回滚块
在UNDO表中间中,保存具体被修改的数据块。
5、数据库隔离级别
一个事务对数据库的修改与并行的另一个事务的隔离程度。
未提交读:一个事物还没有提交,另一个事物就能读取到数据。
提交读:一个事物提交之后,其他事物才能读取到这个数据更改的数据。
序列化读:事物A读取了一个表的数据,其他事物在这之后,就算改了数据,提交了,事物A也不会读取其他事物已经改变的数据,依旧读取的是第一次看到的数据情况。
四、UNDO的工作流程

1、在undo表空间找一个相对空闲的undo段的段头块中的事务表找一个槽位,将事物(XID)写入。给事物分配一个undo块。将undo块的地址(UBA),写到事务表中。
2、修改数据块。
(1)将事物(XID)写入数据块的事物槽中,并记上事物是否已经提交。
(2)将修改前的数据 ,写到回滚块中。
(3)将回滚块的地址,写入到数据块的事物槽中(为了更快构造CR块)。
(4)在修改的数据行头部写上事物槽。
3、当回滚块的数据写满之后,系统会自动分配另一个回滚块,将回滚块链接在第一个回滚块之后。同时,将最后一个回滚块地址放入UNDO段头块事务表中。(为了rollback)
事物是否已经提交标志,需要写在回滚段段头块的事务表中,也需要写入数据块的事物槽中。写入回滚段段头块的事务表中,是为了实例恢复时,进行回滚。写入数据块的事物槽中,是为了方便找到那些数据行被事物占用,从而避免在事务表中出现争用。
当oracle rollback时,首先找到事物,找到回滚段的事务表,就能找到最后一个UBA,才能一次回滚所有回滚块。
为什么需要在数据块的事物槽中,记录回滚块的地址呢?为了更快的找到回滚块,从而加快构造CR块的速度。
UNDO的更多相关文章
- MySQL,MariaDB:Undo | Redo [转]
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- iOS: 为画板App增加 Undo/Redo(撤销/重做)操作
这个随笔的内容以上一个随笔为基础,(在iOS中实现一个简单的画板),上一个随笔实现了一个简单的画板: 今天我们要为这个画板增加Undo/Redo操作,当画错了一笔,可以撤销它,或者撤销之后后悔了, ...
- 【msql】关于redo 和 undo log
InnoDB 有两块非常重要的日志,一个是undo log,另外一个是redo log,前者用来保证事务的原子性以及InnoDB的MVCC,后者用来保证事务的持久性.和大多数关系型数据库一样,Inno ...
- [转]undo log与redo log原理分析
数据库通常借助日志来实现事务,常见的有undo log.redo log,undo/redo log都能保证事务特性,这里主要是原子性和持久性,即事务相关的操作,要么全做,要么不做,并且修改的数据能得 ...
- [转]MySQL日志——Undo | Redo
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- 【转】ORACLE的REDO与UNDO
一.什么是redo?redo:oracle在在线或者归档重做日志文件中的记录的信息,外以出现失败时可以利用这些数据来"重放"事务.每个oracle数据都至少有二个在线重做日志组,每 ...
- oracle undo回滚段详解
1.Undo是干嘛用的? 在介绍undo之前先说一下另外一个东西 transaction ,翻译成交易或事务.我们在进行一个事务的过程中需要申请许多资源,一个复杂的事务也需要很多步来完成.那么一个 ...
- 从Undo,Redo谈命令模式
一般的应用软件中,通常会提供Redo和Undo的操作,比如Paint.NET中的动作面板,Word中的撤销重做,一般我们按Ctrl-Z即可回退到上次操作. 要实现上面的这一功能,最直观的想法就是,我们 ...
- Undo/Redo for Qt Tree Model
Undo/Redo for Qt Tree Model eryar@163.com Abstract. Qt contains a set of item view classes that use ...
- Qt Undo Framework Demo
Qt Undo Framework Demo eryar@163.com Abstract. Qt’s Undo Framework is an implementation of the Comma ...
随机推荐
- SQL2005语句实现行转列,列转行
在做报表时,经常需要将数据表中的行转列,或者列转行,如果不知道方法,你会觉得通过SQL语句来实现非常难.这里,我将使用pivot和unpivot来实现看似复杂的功能.这个功能在sql2005及以上版本 ...
- Scss开发临时学习过程
SCSS语法: 假设变量申明带有!default,那么如果在此申明之前没有这个变量的申明,则用这个值,反之如果之前有申明,则用申明的值. ‘...’传递多个参数: @mixin box-shadow( ...
- 使用7-zip制作自解压安装包
7-zip制作自解压包很方便,只要在压缩时选择”创建自释放程序”选项. 而自解压安装包有点麻烦,不如WinRAR方便. 准备工具:下载 LZMA SDK 这里面有 7zSD.sfx (16.04版7z ...
- 写出形似QML的C++代码
最开始想出的标题是<Declarative C++ GUI库>,但太标题党了.只写了两行代码,连Demo都算不上,怎么能叫库呢……后来想换掉“库”这个字,但始终找不到合适词来替换.最后还是 ...
- 安装Oracle报错,全部为未知!
安装Oracle一开始就报错:需要将以下日志文件发送给管理员,<未知><未知><未知>. 这种问题需要对oracle的setup.exe设置 兼容性.具体如下图:
- [Maven]Maven 那点事儿
0. 前言 Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他. 这兄弟是干嘛的? 他就是 Maven 的创始人,人们都尊称他为"Maven 他爸". 毋庸 ...
- C++坑点集合 - 1 隐式调用和默认实现的构造函数的坑
C++是一个编译器会替你在背后做很多事情的语言,包括模板实例化,按需要创造隐式的构造函数,默认构造你没有显式构造的成员,按需进行隐式转换和饮食构造等等,如果没有彻底了解清楚,就容易被这些编译器背后做好 ...
- python 类变量和实例变量
super(cls, inst) 获得的是 cls 在 inst 的 MRO 列表中的下一个类. 实例的属性存储在实例的__dict__中,类属性和方法存储在类的__dict__中.查找属性时,先检 ...
- Momo自定义DialogFragment
在Fragnment弹窗提示 XML <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...
- Struts2:MyEclippse中使用struts-default.xml中定义的拦截器(timmer,logger)
环境:MyEclipse 2015 Stable 2.0:struts2-core-2.3.16.1.jar等 struts.xml <struts> <package name=& ...