回滚段的前世今生

回滚段的前世今生:

在Oracle 9i之前,回滚表空间创建之后,Oracle随后创建回滚段供数据库使用,也可以手工创建或者删除回滚段进行维护,比如在开始事务之前,可以通过如下命令指定使用特定的回滚段:

set transaction user rollback segment <rollback_segment_name>;

可以从数据库中查询这些回滚段的状态:

sys@TQGZS> select segment_name,tablespace_name,status from dba_rollback_segs;
SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1$                      UNDOTBS1                       ONLINE
_SYSSMU2$                      UNDOTBS1                       ONLINE
_SYSSMU3$                      UNDOTBS1                       ONLINE
_SYSSMU4$                      UNDOTBS1                       ONLINE
_SYSSMU5$                      UNDOTBS1                       ONLINE
_SYSSMU6$                      UNDOTBS1                       ONLINE
_SYSSMU7$                      UNDOTBS1                       ONLINE
_SYSSMU8$                      UNDOTBS1                       ONLINE
_SYSSMU9$                      UNDOTBS1                       ONLINE
_SYSSMU10$                     UNDOTBS1                       ONLINE
_SYSSMU11$                     UNDO_SMALL                     OFFLINE
_SYSSMU12$                     UNDO_SMALL                     OFFLINE
_SYSSMU13$                     UNDO_SMALL                     OFFLINE
_SYSSMU14$                     UNDO_SMALL                     OFFLINE
_SYSSMU15$                     UNDO_SMALL                     OFFLINE
_SYSSMU16$                     UNDO_SMALL                     OFFLINE
_SYSSMU17$                     UNDO_SMALL                     OFFLINE
_SYSSMU18$                     UNDO_SMALL                     OFFLINE
_SYSSMU19$                     UNDO_SMALL                     OFFLINE
_SYSSMU20$                     UNDO_SMALL                     OFFLINE
21 rows selected.

从Oracle 9i开始,Oracle引入了自动管理的Undo表空间,如果选择使用自动的Undo表空间的管理,那么用户不再能够创建或删除回滚段,也不再需要为事务指定回滚段,这一切将由Oracle自动进行。

SQL> select * from v$version where rownum<2;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
SQL> show parameter undo
NAME                       TYPE        VALUE
-------------------------- ----------- ---------
undo_management            string      AUTO
undo_retention             integer     10800
undo_suppress_errors       boolean     FALSE
undo_tablespace            string      UNDOTBS1

伴随自动Undo管理功能的引入,Oracle随之引入了几个新的初始化参数。

·undo_management:用来定义数据库使用的回滚段是否使用自动管理模式。该参数有来个可选项,AUTO表示自动管理,MANUAL表示手工管理。
·undo_tablespace:用来定义在自动管理模式下,当前实例使用哪个Undo表空间。
·undo_suppress_errors:表示当使用自动管理模式时,如果使用不再支持的操作时(比如:为事务指定回滚段)是否返回出错信息。设置为True时不返回出错信息,操作无效但是可以继续,设置为False时,则操作不能继续,这实际上是一个向后兼容的参数。

该参数在Oracle 10g中已经被舍弃:
sys@TQGZS> select * from v$version where rownum<2;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
sys@TQGZS> show parameter undo
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

·undo_retention:表示在自动管理模式下,当回滚段变得非激活(INACTIVE)之后,回滚段中的数据在被覆盖前保留的时间,该单位是秒。在Oracle 9iR2中,这个参数的缺省值为10800,也就是3个小时。通过该参数的调节作用,在繁忙的查询系统中,可以有效地避免ORA-01555错误,这是Oracle 9i AUM的一大增强。

在自动管理的Undo表空间中,回滚段的个数是Oracle根据数据库的繁忙程度自动分配或者回收的,数据库创建时缺省初始化10个回滚段,从数据库内部v$rollname视图也可以查询得到这些自动创建的回滚段信息:

sys@TQGZS> select * from v$rollname;
       USN NAME
---------- --------------------------------------------------
         0 SYSTEM
         1 _SYSSMU1$
         2 _SYSSMU2$
         3 _SYSSMU3$
         4 _SYSSMU4$
         5 _SYSSMU5$
         6 _SYSSMU6$
         7 _SYSSMU7$
         8 _SYSSMU8$
         9 _SYSSMU9$
        10 _SYSSMU10$
11 rows selected.

在系统繁忙时,可以从数据库的警告日志文件中看到回滚段的动态创建和释放过程,这也正是自动管理Undo表空间的优势之一。

在Oracle 11g中,Undo段的命名规则有了进一步变化,现在Oracle将回滚段创建的时间戳包含在回滚段名称中,这样我们通过名称就能得知一个Undo Segment的创建时间,请看以下查询:

sys@CCDB> select * from v$version where rownum <2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
sys@CCDB> select * from v$rollname;              
       USN NAME
---------- ------------------------------------------------------------
         0 SYSTEM
         1 _SYSSMU1_1192403689$
         2 _SYSSMU2_1192403689$
         3 _SYSSMU3_1192403689$
         4 _SYSSMU4_1192403689$
         5 _SYSSMU5_1192403689$
         6 _SYSSMU6_1192403689$
         7 _SYSSMU7_1192403689$
         8 _SYSSMU8_1192403689$
         9 _SYSSMU9_1192403689$
        10 _SYSSMU10_1192403689$
11 rows selected.

这里的时间戳是UNIX Time,需要经过转换才能变换为标准时间。请看以下测试。首先创建一个新的Undo表空间undotbs2,然后设置数据库切换到这个新建的Undo表空间:

sys@CCDB> create undo tablespace undotbs2 datafile '/oracle/oradata/ccdb/ccdb/undotbs02.dbf' size 3000M; 
Tablespace created.
sys@CCDB> alter system set undo_tablespace='undotbs2';
System altered.
sys@CCDB> show parameter undo
NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- ------------------------------
undo_management                      string                           AUTO
undo_retention                       integer                          900
undo_tablespace                      string                           undotbs2

原有Undo表空间的回滚段会逐渐离线,新的表空间Undo段顺序创建:

sys@CCDB> select * from v$rollname;
       USN NAME
---------- ------------------------------------------------------------
         0 SYSTEM
        21 _SYSSMU21_1261559868$
        22 _SYSSMU22_1261559868$
        23 _SYSSMU23_1261559868$
        24 _SYSSMU24_1261559868$
        25 _SYSSMU25_1261559868$
        26 _SYSSMU26_1261559868$
        27 _SYSSMU27_1261559868$
        28 _SYSSMU28_1261559868$
        29 _SYSSMU29_1261559868$
        30 _SYSSMU30_1261559868$
11 rows selected.

在Linux上可以通过Date命令将这个UNIX Time时间戳转换成标准时间:

[oracle@test7: ~]$date -d '1970-01-01 00:00:00 UTC 1261559868 seconds' +"%Y-%m-%d %T %z"
2009-12-23 17:17:48 +0800
[oracle@test7: ~]$date
Wed Dec 23 17:25:25 CST 2009

- The End -