Oracle回滚/撤销
撤销数据是反转DML语句结果所需的信息。撤销数据通常被称为“回滚数据”,在过去的Oracle版本中,“回滚数据”和“撤销数据”可以交替使用,但从9i版本开始,这两个术语有所不同:功能相同,但管理方式不同。只要某个事务修改了数据,那么更新前的原有数据就会被写入一个回滚段或撤销段。回滚段在11g版本中依然存在,但从9i版本开始,Oracle数据库引入了可供选择的撤销段。Oracle强烈建议所有数据库都应当使用撤销段,回滚段只被保留用于向后兼容。
撤销管理
Oracle数据库中,也设置了一个专门的存储空间,用来保存操作过程及被操作的数据,即撤销记录,以便提供撤销功能,即允许用户撤销对数据库所执行的最后操作。
撤销表空间中创建撤销段,自动保存当前对数据库的操作,以便实现自动撤销管理,撤销该操作。
撤销表空间,也叫还原空间,Undo tablespace
![撤销](https://tva3.sinaimg.cn/large/0072YHp3ly1gkpnlhc8ipj30m60bjgmj.jpg)
自动撤销管理
undo_tablespace
指定默认的撤销表空间undo_retention
指定撤销记录在撤销段中保留的时间undo_management
设置为auto,即使用的是自动撤销管理功能
由系统来决定在undo表空间内开多少undo段
Oracle服务器在UNDO表空间中,自动维护撤销数据- 在system表空间中保留一个system回退段,以便存放和处理由Oracle系统事务产生的撤销数据。
创建数据库时,运行sql.bsq脚本会自动创建system回退段,DBA不需要对它进行任何维护和管理,也不能删除它
撤销的目的与作用
![目的](https://tvax4.sinaimg.cn/large/0072YHp3ly1gkpnlhttygj30mq0d9mxu.jpg)
①事物的回退
在Oracle数据库中,对数据库的操作被划分成事务,一个事务由一条或多条SQL语句组成。一个事务中的SQL语句要么都执行要么都不执行,即可以回退
当用户回退一个事务时,Oracle使用撤销段中的撤销数据来撤销自从这个事务开始以来所发生的全部更改,并释放这个事务所涉及的表行上的任何锁,然后结束这个事务
②读一致性
-
数据库的读操作不会妨碍写操作,而数据库的写操作也不会妨碍读操作
- 举例:如果在查询所有员工工资数据的同时有人修改了几个员工的工资数据,那么查询出来的所有员工的工资数据应该是修改前的、上一次提交后的数据,而不是修改后的数据。
-
有了读一致性,就能保证修改前的数据和修改后的数据不会混杂在一起。读一致性是由Oracle自动提供的,并由撤销段中的撤销记录来实现
③闪回查询
![读一致性](https://tva1.sinaimg.cn/large/0072YHp3ly1gkpnlho32aj30k80cwq3m.jpg)
- 利用撤销段和闪回查询功能实现
- 闪回查询允许用户回到过去,查询刚刚过去的某个时间点上已经存在的一个表中的内容(这个时间点必然受到撤销空间、撤销信息保留时间的限制)
- 看起来像一条SELECT语句,不同的是它另外包含一个AS OF TIMESTAMP子句
④事物的恢复
事务恢复是例程恢复的一部分,是由Oracle自动完成的。在数据库运行过程中,正在做大量的事务,其中一些事务还没有提交,但出现了例程失败(如断电、内存故障、后台进程故障等),此时就可以使用撤销恢复数据。
创建和配置撤销段
①类型
-
SYSTEM:用于在SYSTEM表空间中的对象
-
Non-SYSTEM:用于其它表空间中的对象
-
自动模式:需要一个撤销表空间
-
手动模式:8i之前才使用的
-
私有的:仅用于一个单独实例、
-
公用的:用于任意实例
-
-
-
延迟的撤销段:用于表空间立即、临时离线时,或恢复时
②配置
- 在初始化文件中配置两个参数:
UNDO_MANAGEMENT(auto或manual)
指定系统是使用自动的还是手动的模式
UNDO_TABLESPACE
指定使用一个特定的撤销表空间 - 建立至少一个撤销表空间。
③创建撤销表空间
undo_management=auto
使用自动管理方式
-
必须在数据库中创建一个撤销表空间,以便Oracle在其中分配撤销段来保存撤销数据。
- 在创建数据库的同时创建一个默认的撤销表空间
- 在数据库创建之后创建一个撤销表空间
-
如果没有指定一个撤销表空间,则在例程启动时,Oracle会自动搜索是否存在一个可用的(或联机的)撤销表空间,并自动选择第一个可用的撤销表空间来保存撤销数据。
-
如果没有找到一个可用的撤销表空间,Oracle就使用SYSTEM表空间的system回退段来保存撤销数据,并会在预警文件中记录如下警告信息:
Warning – Executing transaction without active Undo Tablespace
④创建UNDO表空间
通过在CREATE DATABASE命令中增加一个子句,可以为数据库建立UNDO表空间
CREATE DATABASE db01
. . .
UNDO TABLESPACE undo1 DATAFILE 'undo1db01.dbf'
SIZE 20M AUTOEXTEND ON
或者通过使用CREATE UNDO TABLESPACE命令,在之后建立
CREATE UNDO TABLESPACE undo1
DATAFILE 'undo1db01.dbf' SIZE 20M;
⑤改变UNDO表空间
ALTER TABLESPACE命令能改变UNDO表空间
例:把另一个数据文件加入到UNDO表空间中:
ALTER TABLESPACE undotbs
ADD DATAFILE 'undotbs2.dbf' SIZE 30M
AUTOEXTEND ON;
⑥切换UNDO表空间
可以在不同的UNDO表空间之间进行切换
- 由于不能实际缩小撤销表空间的大小,如果启用了自动扩展功能,则为了响应一个产生大量撤销数据的大事务时,撤销表空间会自动增大。因为需要备份撤销表空间的数据文件,所以这会影响未来所有备份的大小
- 解决这个问题的方法是及时更换撤销表空间
注:
- 在任何时候,一个实例只能指定一个UNDO表空间
- 一个实例可以有多于一个的UNDO表空间,但是只能有一个是活跃的(被激活)
- 使用ALTER SYSTEM命令动态地在UNDO表空间之间切换
创建一个新的撤销表空间
CREATE DATABASE db01 . . . UNDO TABLESPACE undo1 DATAFILE 'undo1db01.dbf' SIZE 20M AUTOEXTEND ON
或者
CREATE UNDO TABLESPACE undo1 DATAFILE 'undo1db01.dbf' SIZE 20M;
更改使用该新的撤销表空间:
ALTER SYSTEM SET undo_tablespace=undotbs_new
删除旧的撤销表空间:
DROP TABLESPACE undotbs_old
⑦删除一个UNDO表空间
DROP TABLESPACE命令删除一个UNDO表空间
DROP TABLESPACE UNDOTBS2;
一个UNDO表空间只能在当前实例没有用它时才被删除。为了删除一个活跃的UNDO表空间:
- 切换到一个新的UNDO表空间
- 等待在原表空间工作的当前事务都完成之后,删除表空间
⑧其他参数
UNDO_SUPPRESS_ERRORS
:设置为真,这个参数在AUTO模式中确定是否报错
UNDO_RETENTION
:单位是秒。控制回滚数据的数量,保持读一致性的时间(在回滚段中保持一段时间,保持读一致性)
ALTER SYSTEM SET undo_retention=600 SCOPE=memory;
#如果将UNDO_RETENTION设置成较大的值,就应该保证撤销表空间具有足够的空间,否则UNDO_RETENTION参数的值就会失去意义。
⑨设置UNDO表空间的大小
U n d o S i z e = U R × U P S × B S × ( 1 + o v e r h e a d ) UndoSize = UR × UPS × BS ×( 1 + overhead) UndoSize=UR×UPS×BS×(1+overhead)
参数 | 意义 |
---|---|
UndoSize | 所需的撤销表空间的大小。 |
UR | 表示UNDO_RETENTION参数的值(以秒为单位)。 |
UPS | 表示每秒钟产生的撤销数据的Oracle块数。 |
BS | 表示由DB_BLOCK_SIZE参数决定的Oracle块的大小。 |
Overhead | 表示在撤销表空间中保留系统信息所需要的额外开销(一般为UR × UPS × BS 的5%~10%)。 |
⑩撤销数据统计量
SELECT end_time,begin_time,undoblks
FROM v$undostat;
参数名 | 意义 |
---|---|
Endtime | 以10分钟为间隔的结束时间 |
UndoBlocksUsed | 使用的undo块总数 |
TxnConcurrency | 事务并发执行的最大数 |
TxnTotal | 在时间段内事务执行总数 |
QueryLength | 查询长度的最大值 |
ExtentsStolen | 在时间段内undo区必须从一个undo段转到另一个的次数 |
SSTooOldError | 在时间段内’Snapshot Too Old’错误发生的次数 |
UNDOTSN | 这段时间内最后活动的undo表空间ID |
获得撤销段信息
#数据字典视图
DBA_ROLLBACK_SEGS
#动态性能视图
V$ROLLNAME
V$ROLLSTAT
V$UNDOSTAT
V$SESSION
V$TRANSACTION
用法:
select * from V$ROLLNAME;