日期:2014-05-16  浏览次数:20406 次

某客户回滚段达到32765处理
某客户数据库的版本为11.2.0.3,如下所示:
SQL> select * from v$version;

BANNER
------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for IBM/AIX RISC System/6000: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

数据库使用的UNDO表空间为UNDOTBS1,且为自动管理,如下所示:
SQL> show parameter undo_management

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
SQL> show parameter undo_tablespace

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace                      string      UNDOTBS1

某日,业务程序运行时突然出现ORA-1628错误,数据库警告日志如下所示:
Fri Jun 07 16:25:48 2013
ORA-1628: max # extents  32765 reached for rollback segment _SYSSMU985_640904372$
Fri Jun 07 16:58:14 2013
ORA-1628: max # extents  32765 reached for rollback segment _SYSSMU1496_3116906519$

进一步检查dba_undo_extents视图发现,_SYSSMU985_640904372$和_SYSSMU1496_3116906519$回滚段中的区数量确实已经达到了32765个,如下所示:
SQL> select SEGMENT_NAME,count(*) from dba_undo_extents where TABLESPACE_NAME='UNDOTBS1'                                 
  2  group by SEGMENT_NAME order by 2;
SEGMENT_NAME                     COUNT(*)
------------------------------ ----------
。。。。。。
_SYSSMU985_640904372$               32765
_SYSSMU1496_3116906519$             32765


检查_SYSSMU985_640904372回滚段中的每个区大小,发现每个区大小只有64k,这在区大小分配方式为系统分配下是极为不正常的,如下所示:
SQL> select EXTENT_MANAGEMENT,ALLOCATION_TYPE from dba_tablespaces where TABLESPACE_NAME='UNDOTBS1';

EXTENT_MAN ALLOCATIO
---------- ---------
LOCAL      SYSTEM

SQL> select distinct BYTES from dba_undo_extents where SEGMENT_NAME='_SYSSMU985_640904372';

     BYTES
----------
     65536
由于回滚段_SYSSMU985_640904372$中每个区的大小只有64k,所以整个回滚段大小只有2G不到,如下所示:  
SQL> select BYTES/1024/1024/1024 from dba_segments where SEGMENT_NAME='_SYSSMU985_640904372$';

BYTES/1024/1024/1024
--------------------
          1.99981689

在回滚段中,当事务所使用的块从一个区延伸到下一个区时,就是一次WRAP。当事务所使用的块发生WARP时,如果下一个区有活动事务,那么即使下下个区有空闲块,
Oracle也不会跳过下一区去使用下下一区,此时就会发生区扩展(EXTEND),Oracle会从回滚段中分配出一个空闲区。
从v$rollstat视图中可以看出,在32765个区中,区扩展总共发生了32763次,这是不正常的,而且这极有可能是同一个事务导致的,如下所示:
SQL>  select EXTENTS,EXTENDS,WRAPS,STATUS,CURBLK,CUREXT from v$ro