您的位置:首页 > 其它

ORA-1628: max # extents 32765 reached for rollback segment 错误处理

2014-09-30 10:16 363 查看
客户执行过程,其中有长查询(把结果插入到表中,insert into tab1 select * from view_1之类的语句)报错经查看告警日志,告警日志中出现如下错误内容:

Mon Sep 29 12:06:05 2014
ORA-1628: max # extents 32765 reached for rollback segment _SYSSMU465_3766520548$
Mon Sep 29 12:29:45 2014
minact-scn: useg scan erroring out with error e:12751
Mon Sep 29 12:33:45 2014
ORA-1628: max # extents 32765 reached for rollback segment _SYSSMU236_3356150501$
Mon Sep 29 12:34:55 2014
SMON: Parallel transaction recovery tried

错误是rollback segment 的extents 已经达到了32765已经不能再通过增加extents来扩展段大小了,就是上面段_SYSSMU465_3766520548$和段_SYSSMU236_3356150501$的碎片过多。
查看相关数据库信息
1)查看undo管理

SQL> show parameter
undo

NAME TYPE VALUE
-------------------- ----------- ------------------
undo_management string AUTO

undo_retention integer 7110
undo_tablespace string UNDOTBS11

2)查看undo表空间

SQL> select distinct status,tablespace_name ,to_char(round(sum(bytes)/1024/1024)) sizeM,count(1) from dba_undo_extents group by status,tablespace_name;

STATUS TABLESPACE_NAME SIZEM COUNT(1)

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

EXPIRED UNDOTBS12 55643
17001

UNEXPIRED UNDOTBS11 893
415

UNEXPIRED UNDOTBS12 1473
287

EXPIRED UNDOTBS11 43777
69141
3)查看报错的两个回滚段
SQL> select sum(blocks), count(*), SEGMENT_NAME

from sys.dba_extents t

WHERE T.segment_name IN

('_SYSSMU465_3766520548$', '_SYSSMU236_3356150501$')

GROUP BY T.segment_name;

SUM(BLOCKS) COUNT(*) SEGMENT_NAME

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

1528552 32765 _SYSSMU465_3766520548$

753016 32765 _SYSSMU236_3356150501$

SQL> SELECT T.segment_name,T.BLOCKS,T.EXTENTS FROM DBA_SEGMENTS T WHERE T.segment_name IN ('_SYSSMU465_3766520548$', '_SYSSMU236_3356150501$');

SEGMENT_NAME BLOCKS
EXTENTS

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

_SYSSMU236_3356150501$ 753016
32765

_SYSSMU465_3766520548$ 1528552 32765

SQL> SELECT T.segment_name,T.BLOCKS,T.EXTENTS FROM DBA_SEGMENTS T WHERE T.segment_name IN ('_SYSSMU465_3766520548$', '_SYSSMU236_3356150501$');

SEGMENT_NAME BLOCKS
EXTENTS

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

_SYSSMU236_3356150501$ 753016
32765

_SYSSMU465_3766520548$ 1528552
32765

通过以上信息,外面看出是两个segment的extents 过多,也就是碎片过多导致,我要做的就是减少两个segment的extents数据量解决办法有两种
a 重新建个undo表空间,使用新的undo表空间替换正在使用的,这个操作可以在线做 注意选择业务空闲时段做
b 收缩这个这个两个段,减少extents数量
这里我选择的是后一种
处理步骤如下:

1 查询隐藏参数_smu_debug_mode记录老的值,收缩后修改会此值
select a.inst_id,

a.ksppinm "Parameter",

b.ksppstvl "Session Value",

c.ksppstvl "Instance Value"

from x$ksppi a, x$ksppcv b, x$ksppsv c

where a.indx = b.indx

and a.indx = c.indx

and a.inst_id = b.inst_id

and b.inst_id = c.inst_id

and a.ksppinm in ('_smu_debug_mode');
我的系统_smu_debug_mode的值是0
2 alter system set "_smu_debug_mode"=4 scope=memory ; --0x00000004
Allow RBU operations to be executed in SMU mode

3 收缩两个segment
SQL> alter rollback segment "_SYSSMU465_3766520548$" shrink;

Rollback segment altered.

SQL> alter rollback segment "_SYSSMU236_3356150501$" shrink;

Rollback segment altered.

4 修改为之前的值,由于系统是一体机,需要设置为0,否则storage index不能使用
SQL> alter system set "_smu_debug_mode"=0 scope=memory ;

System altered.

5 查看收缩后两个segment的extents 数量

SQL> SELECT T.segment_name,T.BLOCKS,T.EXTENTS FROM DBA_SEGMENTS T WHERE T.segment_name IN ('_SYSSMU465_3766520548$', '_SYSSMU236_3356150501$');

SEGMENT_NAME BLOCKS EXTENTS
------------------------------ ---------- ----------
_SYSSMU236_3356150501$ 232 29
_SYSSMU465_3766520548$ 760 16

客户再次执行过程问题解决。

总结
出现此问题的原因主要是事务过大占用过多的undo segment 导致segment 扩展到一定的extents后不能再扩展
可以通过优化慢的SQL语句和减小事务来避免这样的问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: