一、什么是undo
1.undo是Oracle数据库在回退、撤销的或者改变数据所需要维护数据库信息的一种手段。这里的数据库信息是指在数据库提交之前的记录的改变等事务信息。
2.undo的三大作用:
一致性读(ConsistentRead)
回滚事务(RollbackTransaction)
实例恢复(InstanceRecovery)
3.当系统发出rollback命令时,undo通过记录的信息将数据库的改变恢复到commit之前的状态。在实例恢复期间,undo信息被用来从redo log中撤销任何未提交到数据文件的事务。当一个用户在访问数据时,undo记录通过维护访问数据的前镜像数据来保证当有其他用户改变相同数据时数据库的读一致性。
4.以前数据库使用回滚段来存储undo信息,这种回滚段管理方式非常的复杂。现在数据库采用undo的方式降低了管理的复杂性,同时减少了dba的工作负荷。但是数据库只能使用这两种方式的一种。可以在数据库里定义两种方式的文件,但是,同一时刻,必须指定数据使用哪一种方式。当你需要在两种方式中切换时,必须将系统重新启动。
5.Oracle数据库一直使用系统回滚段来完成系统的事务。系统回滚段是在数据库创建的时候产生的,系统启动后就一直在线。Dba不需要对它作任何的操作来优化。
二、指定undo的方式
1.oracle 9i以后有个初始化参数:undo_management。当将undo_management设置成AUTO时系统使用重做表空间来管理回滚段,当它被设置成MENUAL时系统使用手工创建回滚段。oracle推荐使用重做表空间代替回滚段。
2.当系统使用auto方式管理undo信息时,系统必须指定一个undo表空间。这个表空间可以是在数据库创建时产生,也可以在数据库创建后再创建。
3.当实例启动的时候,系统自动选择第一个有效的undo表空间或者是rollbacksegment,如果没有有效的可用的undo表空间或者是回滚段,系统使用system rollbacksegment。这种情况是不被推荐的,当系统运行在没有undo的情况下,系统会在alert.log中记录一条警告信息。
4.自动管理模式(Automatic Undo Management)
如果系统要使用auto方式管理undo信息,那么需要通过指定初始化参数undo_tablespace的值来指定系统使用哪一个undo表空间来存放undo信息。如果指定了undo_tablespace的值,但是系统中不存在这样的表空间,那么系统启动将会失败。此时可以做的操作是,如果系统存在undo表空间,为undo_tablespace指定正确的undo表空间名字,或者将undo_tablespace注释。系统会采用存在的undo表空间。否则使用手动方式。
5.相关的初始化参数:
undo_tablespace——指名系统使用哪一个重做表空间。
undo_retention——系统提交后,回滚段的数据保留多长时间,单位是秒。
当系统被设置成manual后,这几个参数被忽略。
6.补充:初始化参数UNDO_RETENTION
该参数用来指定undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改,通常默认是900秒,也就是15分钟。
一定要注意,undo_retention只是指定undo数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15分钟,比如说一个新事务刚开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,因此,当你创建一个自动管理的undo 表空间时,还要注意其空间大小,要尽可能保证undo表空间有足够的存储空间。
7.同时还要注意,也并不是说,undo_retention中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback特性引用。如果你的undo表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo数据,它就会持续有效。因此呢,这里还是那句话,要注意undo表空间的大小,保证其有足够的存储空间。
8.只有在一种情况下,undo表空间能够确保undo中的数据在undo_retention指定时间过期前一定有效,就是为undo表空间指定Retention Guarantee,指定之后,oracle对于undo表空间中未过期的undo数据不会覆盖。
举例说明:
alter tablespace undotbs1 retentionguarantee;
alter tablespace undotbs1 retentionnoguarantee;
三、管理undo表空间
1.创建undo talespace有两种方式:
a、数据库创建时创建undo tablespace;
CREATE DATABASE rbdb1
CONTROLFILE REUSE
...
UNDO TABLESPACE undotbs_01 DATAFILE'/u01/oracle/rbdb1/undo0101.dbf';
b、在一个已经存在的数据库创建。
CREATE UNDO TABLESPACE undotbs_02
DATAFILE '/u01/oracle/rbdb1/undo0201.dbf'SIZE 2M REUSEAUTOEXTEND ON;
在undotablespace中不能创建数据库对象,这是因为这个表空间是为数据库recover而准备的。
2.如果在创建数据库时,系统指定是auto模式,但是没有指明undotablespace的名字,那么系统会创建一个默认的回滚表空间,名称叫sys_undotbs。这个表空间根据oracle定义的缺省值创建。初始化大小是10m,可以自动扩展。不过oracle推荐最好还是使用一个指定的大小。
3.增加数据文件
ALTER TABLESPACE undotbs_01
ADD DATAFILE'/u01/oracle/rbdb1/undo0102.dbf' AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED;
4.重命名数据文件
ALTER TABLESPACE undotbs_01 RENAME DATAFILE'/u01/oracle/rbdb1/undo0102.dbf' TO '/u01/oracle/rbdb1/undo0101.dbf';
5.使数据文件online或者offline
ALTER TABLESPACE undotbs_01 online|offline;
6.删除undo表空间
drop tablespace undotbs_01;
drop undo表空间的时候必须是在未使用的情况下才能进行。如果undo表空间正在使用(例如事务失败,但是还没有恢复成功),那么drop表空间命令将失败。在drop表空间的时候可以使用including contents。
7.切换undo表空间
alter system set undo_tablespace=undotbs1;
当切换命令完成后,所有的事务就会在新的回滚表空间内进行。
以下几种情况会导致切换命令失败:
a、表空间不存在;
b、表空间不是一个回滚段表空间;
c、表空间已经被另一个实例使用。
注意:切换的操作不等待旧undo表空间的事务提交。如果旧undo表空间有事务未提交,那么旧的undo表空间进入pending offline状态,在这种模式下所有的事务能够继续进行,但是undo表空间不能被其他实例使用,也不能被删除,直到所有的事务提交后,undo表空间才进入offline模式。
8.设置undo retention
dba可以设置undo_retention初始化参数指定undo回滚表空间保留undo信息的时间。在设置好这个参数时,系统会保留undo信息在指定的时间段后才收回这个空间。一般情况下,系统会保留undo信息到指定的时间后才回收空间,但是,如果系统存在大量的事务,也会将未到期的undo空间回收,以供使用。
9.undo表空间大小的设计规范的计算公式:
Undospace = UR * UPS * db_block_size + 冗余量
UR:表示在undo中保持的最长时间数(秒),由数据库参数UNDO_RETENTION值决定。
UPS:表示在undo中,每秒产生的数据库块数量。
select blks/((end-begin)*3600) as"Undo Per Second" from
(select min(begin_time) begin,max(end_time)end, sum(undoblks) blks from v$undostat);
10.和undo有关的动态性能视图:
v$undostat——包含undo的统计信息。使用这张视图可以估计系统当前所需的undo大小。
v$rollstat——是undo模式的视图。是undo表空间的undo segments的统计信息。
v$transaction——包含undo segments的信息。
dba_undo_extents——包含undo表空间中每一个区的提交时间。
11.当我们使用AUM,并设置了undo_retention以后,undo块就存在四种状态:
active:表示正在使用该undo的事务还没有提交或回滚
inactive:表示该undo上没有活动的事务,该状态的undo可以被其他事务覆盖
expired:表示该undo持续inactive的时间超过undo_retention所指定的时间
freed:表示该undo块的内容是空的,从来没有被使用过
12.当活动的事务使用undo segment的时候,在AUM模式下,事务可以在不同的undosegment之间动态交换undo空间,也就是在不同的undo segment里交换extents。当一个正在执行的事务需要更多的undo空间时,首先会重用当前undo segment里的可用空间,如果当前undo segment里的可用空间(也就是extents)不足时,则会按照下面的步骤获得所需要的extent:
a、获取undo表空间里可用的、空的extents
b、获取其他undo segment里的expired状态的extents
c、如果undo表空间里的数据文件启用了自动扩展,则数据文件进行自动扩展
d、如果undo表空间里的数据文件没有启用自动扩展,则获取其他undo segment里的inactive状态的extents
e、如果以上步骤均无法获得可用空间时,报空间不足的错误消息