Oracle 11g undo 管理

 

oracle 11g undo 介绍: http://blog.csdn.net/dataminer_2007/article/details/41213945sql

 

undo 是 oracle 数据库中一个很是重要的机制, 在对数据库进行数据修改的时候, 可以为修改的数据构造一种前镜像数据(保存修改以前的旧值), 用来保证回滚对数据库的修改以及对多个用户同时访问的数据提供一致性读. 此外, undo 对于恢复数据库以及 flashback 查询以前时间的数据有着相当重要的做用,数据库

 

1. undo 相关的数据字典

 

1.1 v$undostat: session

 

displays a histogram of statistical data to show how well the system is working. The available statistics include undo space consumption, transaction concurrency, and length of queries executed in the instance. You can use this view to estimate the amount of undo space required for the current workload. Oracle uses this view to tune undo usage in the system. The view returns NULL values if the system is in manual undo management mode.oracle

 

显示最近一段时间内关于 undo 表空间使用状况的统计信息, 能够用这个 view 来优化系统, 每隔 10 分钟自动增长一条数据, 总共只保存四天的数据, 若是要查询超过四天的数据就要使用 dba_hist_undostat, 这个 view 仅对于自动 undo 管理模式有效.优化

 

几个重要的字段说明:ui

 

UNDOTSN NUMBER 最近活动的 undo 表空间的 id
UNDOBLKS NUMBER 当前时间段内消耗的 undo blocks 总数
TXNCOUNT NUMBER 当前时间段内执行的事务总数
MAXQUERYLEN NUMBER 当前时间段内执行单个查询花费的最长时间, 单位为秒
MAXQUERYID NUMBER 当前时间段内执行单个查询花费的最长时间的 sql id
UNXPSTEALCNT NUMBER 其余事务尝试盗用未过时 undo 回滚段的次数
UNXPBLKRELCNT NUMBER 其余事务已经盗用未过时 undo 回滚段的数量
UNXPBLKREUCNT NUMBER 未过时的 undo 回滚段重用的数量
EXPSTEALCNT NUMBER 尝试盗用已通过期回滚段的次数
EXPBLKRELCNT NUMBER 已经盗用过时回滚段的数量
EXPBLKREUCNT NUMBER 已通过期回滚端重用的数量
SSOLDERRCNT NUMBER 返回 ora-01555 错误的次数, 若是 SSOLDERRCNT 大于 0, 说明 undo_retention 设置有问题, 须要增长 undo_retention 的大小
NOSPACEERRCNT NUMBER 空间不足申请新的 undo 表空间的次数
TUNED_UNDORETENTION NUMBER 已提交数据的undo 数据过时时间, 单位为秒 , 对于估计 flashback 可用的时间有用

  

SQL> select UNDOTSN, UNDOBLKS, TXNCOUNT, MAXQUERYLEN, MAXQUERYID, UNXPSTEALCNT, UNXPBLKRELCNT, UNXPBLKREUCNT,  EXPSTEALCNT, EXPBLKRELCNT, EXPBLKREUCNT, SSOLDERRCNT, NOSPACEERRCNT, TUNED_UNDORETENTIONthis

            from v$undostat;spa

 

1.2 dba_hist_undostat.net

 

显示全部的 v$undostat 的历史记录blog

 


1.3 dba_undo_extents:

 

显示数据库全部 undo 表空间的回滚段状况, 其中 status 的取值为 EXPIRED / UNEXPIRED / ACTIVE

 

Active:       活动状态, 说明当前这个回滚段被某个事务正在使用, 不会被其余事务使用

Expired:     已通过期, 随时能够被其余事务使用

Unexpired: 没有过时, 为了 undo_retention 的须要保留在 undo 表空间, 当空间不足时有可能被其余事务使用

 

1.4 v$rollname:

 

只有两个字段(usn, name), 就是一个回滚段 id 和 name, 一般和 v$rollstat 一块儿使用

 

1.5 v$rollstat:

 

 统计回滚段表的使用状况

其中 xacts 表示当前回滚段上存在的活动事务的数量

        status 的取值为 ONLINE / PENDING OFFLINE / OFFLINE / FULL

 

SQL> select a.usn, a.name, b.rssize, b.writes, b.xacts, b.waits, b.extends, b.status

            from v$rollname a, v$rollstat b

         where  a.usn = b.usn;

 

1.6 dba_rollback_segs:

 

显示全部回滚段(包括 SYS 和 PUBLIC)的空间分配状况及当前状态

其中 status 的取值为 OFFLINE / ONLINE / NEEDS RECOVERY /  PARTLY AVAILABLE / UNDEFINED

 

SQL> select owner, segment_name, tablespace_name, initial_extent, next_extents, status

            from dba_rollback_segs;

 

2. Undo 表空间管理 

 

2.1 undo 回滚段

 

在自动管理的 undo 表空间下, 数据库建立时会自动初始化 10 个回滚段, 从 v$rollname 中能够查询到这些自动建立的回滚段信息, 此外, oracle 会根据系统的负载状况自动建立以及释放回滚段.

 

众所周知, 回滚段保存的是修改的数据的前镜像数据, 对于 DML(insert, update, delete) 语句来讲, 回滚段保存的就是 DML 反向操做的数据, 若是是 insert 插入一行数据, 回滚段保存的就是删除该行的记录, 为了节约空间精简数据, 回滚段中只保存 insert 数据的 rowid,  undo 只须要删除该 rowid 的记录便可;若是是 update 数据, 回滚段只保存修改字段的旧值, undo 只须要把旧值覆盖便可;若是是 delete 数据, 回滚段则须要保存整行的数据, undo 只须要把整行的数据插入便可.

 

由此可知, delete 操做产生的 undo(回滚段) 数据最多, 对于大批量的删除一定会对 undo 表空间产生比较大的冲击, 由此, 若是是删除整个表的数据能够用 truncate; 若是不是整个表的数据, 能够把分批删除数据.

 

回滚段的大小和数量对于系统相当重要, 全部 online 的回滚段(除了 system 的回滚段)都会被循环使用. 而每一个回滚段都包含有一些 extent(扩展), 当某个 extent 写满后会自动切换到另外一个 extent 继续使用.

 

2.2.2 undo 数据重用

 

对于自动扩展的 undo 表空间,  oracle 会根据 undo_retention 的值做为保留 undo 数据的最少时间. 而对于固定大小又非 guarante 的 undo 表空间, oracle 会根据 undo 表空间大小及 v$undostat 的统计信息自动调整 以最大可能的保留 undo 数据, 这种状况下设置的 undo_retention 设置将被忽略. 此外, 若是 undo 表空间不足且没法自动扩展时, undo_retention 设置也将被忽略, 由于为了知足系统事务需求, 一些状态为 unexpired 的 undo 数据也有可能被置换重用.

 

当一个正在执行的事务须要更多 undo 空间,而 undo 表空间不足且没法扩展时, oracle 优先会重用当前回滚段下状态为 expired 的 undo extents, 若是没有就去其余回滚段下状态为 expired undo extents, 若是没有再回到当前回滚段中查找状态为 unexpired 的 undo extents, 若是尚未再去查找其余回滚段中状态为 unexpired 的 undo extents, 若是尚未就报空间不足的错误消息.

 

所以, 若是 undo_retention 为 900 秒(默认值), 并不必定意味着 undo 数据在 undo 表空间中保存 900 秒, 由于若是空间不足就会去覆盖不论是否已经 expired 的 已提交事务的undo 数据. 此外, undo_retention 时间到了以后, 并不必定意味这些 undo 数据在 undo 表空间中消失, 它只是并标示为 expired, 只要没有被其余事务的 undo 数据覆盖, 它会依然存在.

 

总之, 对于自动管理的 undo 表空间, 咱们依然天天要对它进行巡检, 保证 undo 表空间有足够的存储空间.

 

2.3 平常监控 undo 表空间

 

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

 

查看当前 undo 表空间大小

 

SQL> select sum(bytes)/1024/1024 "Current Undo Size(M)" from dba_data_files where tablespace_name='UNDOTBS1';

 

Current Undo Size(M)

------------------------------

10

 

查看当前 undo 表空间使用状况

 

SQL> select owner, segment_name, bytes/1024/1024 from dba_segments where tablesp
ace_name='UNDOTBS1';

 

OWNER                          SEGMENT_NAME                   BYTES/1024/1024
       ------------------------------ ------------------------------ --------------------------------------
       SYS                            _SYSSMU20_781529403$                     .3125
       SYS                            _SYSSMU19_381980475$                     .1875
       SYS                            _SYSSMU18_53648357$                      .1875
       SYS                            _SYSSMU17_3412666006$                    .3125
       SYS                            _SYSSMU16_2828248073$                    .3125
       SYS                            _SYSSMU15_461690133$                     .1875
       SYS                            _SYSSMU14_3296674710$                     .375
       SYS                            _SYSSMU13_2498580566$                      .25
       SYS                            _SYSSMU12_2686240293$                    .1875
       SYS                            _SYSSMU11_103500371$                      .125

 

10 rows selected.

 

SQL> select tablespace_name, status, sum(bytes)/1024/1024 from dba_undo_extents
group by tablespace_name, status;

 

TABLESPACE_NAME      STATUS        SUM(BYTES)/1024/1024
       ------------------------------ --------- ----------------------------------------------
       UNDOTBS1                     UNEXPIRED               1.5625
       UNDOTBS1                     EXPIRED                    .75

 

查看当前谁占用了 undo 表空间

 

SQL> select r.name "undo tablespace name",
                           rssize / 1024 / 1024 / 1024 "rssize(G)",
                           s.sid,
                           s.serial#,
                           s.username "username",
                           s.status,
                           s.sql_hash_value,
                           s.sql_address,
                           s.machine,
                           s.module,
                           substr(s.program, 1, 78) "program",
                           r.usn,
                           hwmsize / 1024 / 1024 / 1024,
                           shrinks,
                           xacts
              from sys.v_$session     s,
                      sys.v_$transaction t,
                      sys.v_$rollname    r,
                      v$rollstat         rs
           where t.addr = s.taddr 
              and t.xidusn = r.usn
              and r.usn = rs.usn
            order by rssize desc;

  

2.3 切换 undo 表空间

 

SQL> create undo tablespace undo_david datafile 'g:\oracle\oradata\bakdb\undo_da
vid.dbf' size 10M;

Tablespace created.

 

SQL> alter system set undo_tablespace='undo_david' scope=both;

System altered.

 

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      undo_david


SQL> select segment_name, tablespace_name, status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1_719184344$            UNDOTBS1                       OFFLINE
_SYSSMU2_2817567661$           UNDOTBS1                       OFFLINE
_SYSSMU3_3680621135$           UNDOTBS1                       OFFLINE
_SYSSMU4_237230745$            UNDOTBS1                       OFFLINE
_SYSSMU5_2985270510$           UNDOTBS1                       OFFLINE
_SYSSMU6_2775061352$           UNDOTBS1                       OFFLINE
_SYSSMU7_3717448562$           UNDOTBS1                       OFFLINE
_SYSSMU8_1685456424$           UNDOTBS1                       OFFLINE
_SYSSMU9_2264502008$           UNDOTBS1                       OFFLINE
_SYSSMU10_1467141425$          UNDOTBS1                       OFFLINE

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
_SYSSMU11_103500371$           UNDO_DAVID                     ONLINE
_SYSSMU12_2686240293$          UNDO_DAVID                     ONLINE
_SYSSMU13_2498580566$          UNDO_DAVID                     ONLINE
_SYSSMU14_3296674710$          UNDO_DAVID                     ONLINE
_SYSSMU15_461690133$           UNDO_DAVID                     ONLINE
_SYSSMU16_2828248073$          UNDO_DAVID                     ONLINE
_SYSSMU17_3412666006$          UNDO_DAVID                     ONLINE
_SYSSMU18_53648357$            UNDO_DAVID                     ONLINE
_SYSSMU19_381980475$           UNDO_DAVID                     ONLINE
_SYSSMU20_781529403$           UNDO_DAVID                     ONLINE

21 rows selected.

 

SQL> select usn,xacts,status from v$rollstat;

       USN      XACTS STATUS
---------- ---------- ---------------
         0          0 ONLINE
        11          0 ONLINE
        12          0 ONLINE
        13          0 ONLINE
        14          0 ONLINE
        15          0 ONLINE
        16          0 ONLINE
        17          0 ONLINE
        18          0 ONLINE
        19          0 ONLINE
        20          0 ONLINE

11 rows selected.

 

要等到旧的 undo 表空间 undotbs1 上的回滚段都 offline 后才能 drop

 

SQL> drop tablespace undotbs1;

Tablespace dropped.

 

SQL> select tablespace_name, file_name, status from dba_data_files where tablesp
ace_name like 'UNDO%';

TABLESPACE_NAME                FILE_NAME                                                                          STATUS
------------------------------ ------------------------------ --------- ----------------------------------------------------------
UNDO_DAVID                     G:\ORACLE\ORADATA\BAKDB\UNDO_DAVID.DBF            AVAILABLE
                               

虽然 drop 成功, 可是若是有其余查询须要用到旧的 undo 表空间 undotbs1 上的数据时就会提示 ora-01555 的错误

 

SQL> select * from dba_undo_extents where tablespace_name='UNDOTBS1';

 

总之, 切换系统当前 undo 表空间到新建的 undo 表空间几乎能够随时执行成功, 可是若是要删除旧的 undo 表空间必定要等到该 undo 空间里全部的回滚段所有 offline. 千万别在尚有回滚段处于 online 状态强制删除数据文件.