undo表空间
undo表空间的管理,主要包括创建、删除、修改、切换。其中需要注意的是不能在undo表空间创建数据库对象,还有就是只能是单文件或大文件表空间。
创建
创建主要有两种方法,一种是在创建数据库时创建(create database),另一种就是通过create undo tablespace 来创建。如果用第一种方法创建时失败了,必须清理数据文件及修正错误后才能重新尝试创建,第二种方法创建跟普通表空间的创建是一样的,只是参数有所不同而已。
1.在创建数据库时创建
CREATE DATABASE rbdb1
CONTROLFILE REUSE
...
UNDO TABLESPACE undotbs_01 DATAFILE '/u01/oracle/rbdb1/undo0101.dbf'; --在用SQL语句创建数据库时,通过指定UNDO TABLESPACE参数来创建
2.直接用SQL创建
CREATE UNDO TABLESPACE undotbs_02
DATAFILE '/u01/oracle/rbdb1/undo0201.dbf' SIZE 2M REUSE AUTOEXTEND ON; --创建思路跟普通表空间差不多
删除
删除方法跟普通的表空间一样,需要注意的是只有在没有被任何实例正在使用的情况下才能被删除;如果包含有外部事务的话则会删除失败。
DROP TABLESPACE undotbs_01; --此语句的效果跟普通表空间的删除方法 TABLESPACE...INCLUDING CONTENTS差不多,表空间的所有内容都会被删掉
修改
修改重做表空间的内容和普通的表空间大致相同,包括增加数据文件、重命名数据文件、让数据文件脱机/联机、开始或结束一个开放备份的数据文件、启用或禁用retention guarantee。
切换
通过语句ALTER SYSTEM SET ...可以实现表空间切换(更改实例的undo表空间)。不过需要注意的是,如果所指定的表空间不存在或者所指定的根本不是表空间,也或者是已经被其他实例正在使用,那么都将会出现报错。
另外,这个切换操作它不会等待旧undo表空间里的事务提交才执行;在切换的过程中,如果在旧的undo表空间有等待的事务要执行,旧的undo表空间会进入等待下线模式(PENDING OFFLINE),这种模式下事务可以被执行,但是新的事务都不会存到这个旧的表空间。
在进入待下线模式(PENDING OFFLINE)的undo表空间,既不能被别的实例使用也不能被删除,只有在所有的事物执行完成之后,undo表空间由PENDING OFFLINE模式转到OFFLINE模式时才可被其他实例使用或删除。
ALTER SYSTEM SET UNDO_TABLESPACE = undotbs_02; --指定uodo表空间
ALTER SYSTEM SET UNDO_TABLESPACE = ''; --释放当前undo表空间
UNDO
Oracle数据库的创建和管理过程的信息用来回滚、重做或改变数据库,这些信息组成了事务提交的记录,这些记录就叫做undo。
undo记录可以用作:
1.回滚操作(执行ROLLBACK语句);
2.回复数据库;
3.保证读取的连贯性;
4.通过闪回来分析先前的一个时间点的数据;
undo自动管理
oracle数据库能自动管理undo信息和空间;自动管理在undo表空间管理undo段。undo自动管理是oracle默认的模式,当你使用DBCA创建数据库时undo表空间UNDOTBS1会自动创建,当然你也可以手动创建undo表空间。
当数据库实例启动时,数据库会自动选择第一个可用的undo表空间,如果undo表空间不可用,实例照常启动并选择system表空间,这是不推荐的!
如果数据库有多个undo表空间,你可以通过UNDO_TABLEASPACE参数为数据库实例设置指定的undo表空间。
例:UNDO_TABLESPACE = undotbs_01
如果指定的表空间不存在,startup启动数据库会失败。
数据库也支持manual undo management mode 在这种模式下,不需要undo表空间,通过回滚段管理undo空间。不过,通过回滚段管理空间是一个复杂的操作,Oracle官方强烈推荐自动管理模式。
以下是,undo管理初始化参数的简介:
如果启用了自动管理模式,那么即使初始化文件里的参数设置了手动管理也都将不会生效。
undo保存期
undo保存期就是oracle数据库在覆盖旧的undo信息前能保存的最小的时间,当事务提交后undo数据就不再用于回滚或事物恢复了;然而,对于连续性读取来说,长时间查询可能就用到这些信息来产生旧的镜像数据块,再者,闪回的成功与否也取决于undo信息是否可用;因此,旧的undo信息尽量保存久一点。
旧的undo信息存在的时间比当前保存期要久,那么undo信息就已经过期了,undo信息的空间就会被新的事物覆盖;反之,undo信息就还没过期,仍可用于连续性读取和闪回操作。
Oracle会基于表空间的大小和系统的运行情况自动调整undo保存期的大小,当然你也可以通过UNDO_RETENTION来手动设置undo保存期的大小。
手动设置UNDO_RETENTION对保存期的实际影响有以下:
1.如果undo表空间是固定大小那么UNDO_RETENTION参数将会被忽略,数据库会根据undo表空间大小和数据库的运行情况来决定保存期。
2.当undo表空间启用了AUTOEXTEND时,保存期会跟参数UNDO_RETENTION设置的一致,当空间不足时,表空间会自动扩展;然而,undo表空间设置了MAXSIZE参数,当表空间的大小达到最大值时,数据库可能会开始覆盖未过期的undo信息。
例
ALTER SYSTEM SET UNDO_RETENTION = 2400;
自动调整undo保存期
Oracle数据库能基于undo表空间的配置来自动调整undo保存期。
1.如果undo表空间设置了AUTOEXTEND,数据库会自动调整undo保存期并尽量让它大于当前正在执行的用时最长的查询;但是这个保存期可能还容纳不下一个闪回操作,就可能出现snapshot too old 的错误,这时你就需要手动去干预保存期的大小来使其达到闪回操作的要求,有两种选择:一种是更改UNDO_RETENTION的大小,另一种就是更改undo表空间的大小(使系统用足够的空间去调整保存期大小)
2.如果undo表空间是固定大小,数据库会根据表空间的大小和系统当前的负载情况动态调整保存期的大小,最好的保存时间应该是比当前正在执行的持续时间最长的查询时间长;如果选择修改undo表空间的大小,就应该选择足够大的空间,如果空间不够系统将会出现以下报错:
(1)DML会执行因没有足够的空间去容纳新的事物而失败;
(2)持续时间较长的查询会报snapshot too old错误。
需要注意的是,udno保存期自动调整并不支持大对象(LOBs)。这是因为大对象的undo信息并不是存储在undo表空间,而是存在它们自己的段里了。对于大对象(LOBs),数据库会通过UNDO_RETENTION来尽量满足它的要求;然而,如果空间太小,未过期的大对象(LOBs)可能会被覆盖掉。
保存期保证(Retention Guarantee)
可以通过设置Retention Guarantee来保证持久查询和闪回的成功执行。
如果设置了Retention Guarantee,指定的最小保存期会得到保证,也就是说数据库不会去覆盖那些未过期的undo数据(包括那些因空间不够而未能成功执行的事务)。
如果没有设置Retention Guarantee,当空间不够用时数据库会把未过期的undo数据覆盖掉,Oracle默认是禁用保存期保证的。
需要注意的是,启用Retention Guarantee会导致多DML执行失败。所以一定要小心使用这个选项。
设置方法有以下几种:
1.通过在CREATE DATABASE或CREATE UNDO TABLESPACE时添加参数RETENTION GUARANTEE;
2.通过ALTER TABLESPACE添加RETENTION NOGUARNATEE参数。
可以查看视图DBA_TABLESPACES里的RETENTION列,GUARANTEE, NOGUARANTEE, or NOT APPLY, NOT APPLY是用于表空间的不是undo表空间。
undo保存期调整和警告阈值
对于一个固定大小的undo表空间,数据库会根据undo表空间的大小以及剩余空间来调整保存期。数据库undo保存期是基于百分之八十五的undo表空间大小或者是空间的使用情况警告阈值来调整的,空间使用警告阈值默认是百分之八十五(你可以改变它的大小)。
可以通过是同V$UNDOSTAT的TUNED_UNDORETENTION列来查看当前保存期的情况。视图的每一列的数值是每隔十分钟统计过去四天的数值。
例:
select to_char(begin_time, 'DD-MON-RR HH24:MI') begin_time,
to_char(end_time, 'DD-MON-RR HH24:MI') end_time, tuned_undoretention
from v$undostat order by end_time;