进程事务量过大导致undo空间满而影响整个系统
早上过来发现一个库上的一直在提示回退段扩展失败:Failure to extend rollback segment because of 30036 condition。同时,相关的事务都无法正常结束。检查undo空间使用情况,发现使用率已经达到100%,剩余空间为0。进一步检查回退段的空间使用情况,发现其中有一个回退段特别大,接近整个undo空间的分配大小:
SELECT r.status "Status",
r.segment_name "Name",
r.tablespace_name "Tablespace",
s.extents "Extents",
TO_CHAR((s.bytes / 1024 / 1024), '99999990.000') "Size"
FROM sys.dba_rollback_segs r, sys.dba_segments s
WHERE r.segment_name = s.segment_name
AND s.segment_type IN ('ROLLBACK', 'TYPE2 UNDO')
ORDER BY 5 DESC;
继续检查各回退段上的事务情况,发现是某个进程在使用该回退段,且已经执行了3个多小时了,状态还是active:
SELECT r.NAME 回滚段名,s.sid SID,s.serial# Serial,
s.username 用户名,s.machine 机器名,
t.start_time 开始时间,t.status 状态,
t.used_ublk 撤消块,USED_UREC 撤消记录,
t.cr_get 一致性取,t.cr_change 一致性变化,
t.log_io "逻辑I/O",t.phy_io "物理I/O",
t.noundo NoUndo,g.extents Extents,substr(s.program, 1, 50) 操作程序
FROM v$session s, v$transaction t, v$rollname r,v$rollstat g
WHERE t.addr = s.taddr
AND t.xidusn = r.usn
AND r.usn = g.usn
ORDER BY t.used_ublk desc;
考虑到要尽快恢复系统中其他进程的正常执行,所以只好牺牲此进程,将其kill。
kill后占用的回退段空间还不会马上释放出来,这就需要临时将undo_retention修改为一个较小的时间,待其空间释放出来之后再恢复为原来的值。当然,如果undo管理方式为manual的话,可以直接将回退段收缩。
另外,auto管理方式下自动收缩过程中,也要随时注意超大回退段的空间释放情况,如有其他进程用到的话讲导致该回退段中止释放空间。这就需要及时处理了。
SELECT r.status "Status",
r.segment_name "Name",
r.tablespace_name "Tablespace",
s.extents "Extents",
TO_CHAR((s.bytes / 1024 / 1024), '99999990.000') "Size"
FROM sys.dba_rollback_segs r, sys.dba_segments s
WHERE r.segment_name = s.segment_name
AND s.segment_type IN ('ROLLBACK', 'TYPE2 UNDO')
ORDER BY 5 DESC;
继续检查各回退段上的事务情况,发现是某个进程在使用该回退段,且已经执行了3个多小时了,状态还是active:
SELECT r.NAME 回滚段名,s.sid SID,s.serial# Serial,
s.username 用户名,s.machine 机器名,
t.start_time 开始时间,t.status 状态,
t.used_ublk 撤消块,USED_UREC 撤消记录,
t.cr_get 一致性取,t.cr_change 一致性变化,
t.log_io "逻辑I/O",t.phy_io "物理I/O",
t.noundo NoUndo,g.extents Extents,substr(s.program, 1, 50) 操作程序
FROM v$session s, v$transaction t, v$rollname r,v$rollstat g
WHERE t.addr = s.taddr
AND t.xidusn = r.usn
AND r.usn = g.usn
ORDER BY t.used_ublk desc;
考虑到要尽快恢复系统中其他进程的正常执行,所以只好牺牲此进程,将其kill。
kill后占用的回退段空间还不会马上释放出来,这就需要临时将undo_retention修改为一个较小的时间,待其空间释放出来之后再恢复为原来的值。当然,如果undo管理方式为manual的话,可以直接将回退段收缩。
另外,auto管理方式下自动收缩过程中,也要随时注意超大回退段的空间释放情况,如有其他进程用到的话讲导致该回退段中止释放空间。这就需要及时处理了。