一次Undo表空间耗尽问题

来源:这里教程网 时间:2026-03-03 21:40:47 作者:

Undo表空间耗尽问题

1、 问题描述

oracle版本19.16,发现undo表空间使用率过高,查询发现事物占用的表空间与undo表空间 active 状态的空间大小不一致 事物 使用 undo 表空间 sql 查询: SELECT s.username,        s.sid,        pr.PID,        s.OSUSER,        s.MACHINE,        s.PROGRAM,        rs.segment_id,        r.usn,        rs.segment_name,              r.rssize/1024/1024,        sq.sql_text   FROM gv$transaction t, gv$session s, gv$rollstat r, dba_rollback_segs rs ,gv$sqltext  sq,gv$process pr WHERE s.saddr = t.ses_addr    AND t.xidusn = r.usn    AND rs.segment_id = t.xidusn    AND s.sql_address=sq.address    AND s.sql_hash_value = sq.hash_value    AND s.PADDR=pr.ADDR ORDER BY t.used_ublk DESC ,sq.PIECE;     undo表空间 active 的过大 与事物占用空间相差太大 SELECT tablespace_name,status,SUM (bytes)/1024/1024 "Bytes(M)" FROM dba_undo_extents GROUP BY tablespace_name,status;    

2、 问题分析

排查过程中间 预估 dba/v$ 视图与基表的收集问题,尝试根据基表来查结果,未果。 后面 mos上查到一片文档: High UNDO Tablespace Usage Caused By Recursive SQL f3yfg50ga0r8n From KTSJ Slave Process (Doc ID 3013880.1)   查询消耗的 sql_id确实是:“ f3yfg50ga0r8n select MAXQUERYID,count(*) from gv$undostat group by MAXQUERYID; 通过 gv$session 查询确实有 KTSJ Slave执行,事件“Space Manager: slave idle wait”,也就是回收undo空间一直处于等待状态 select SID,SERIAL#,SCHEMANAME,TYPE,SQL_ID,SQL_CHILD_NUMBER,SQL_EXEC_START,MODULE,ACTION,ACTION_HASH,EVENT from gv$session where SQL_ID='f3yfg50ga0r8n'; 查询 sql_id对应的sql: select SQL_TEXT,SQL_ID,EXECUTIONS,LOADS,PARSE_CALLS,INVALIDATIONS from v$sql where SQL_ID='f3yfg50ga0r8n'; Sql为:select obj# from obj$ where dataobj# = :1

3、问题原因  

这是一个 bug,Bug 3633060,“ KTSJ slave ”执行空间管理协调( SMCO 出现了资源等待 但是目前 oracle开发团队未发布补丁  

4、 问题解决

Bug 36330602得到修复之前,请考虑应用以下解决方案。 高了就关 smco: ALTER SYSTEM SET "_enable_space_preallocation" = 0; 低了就开 smco,3也是默认参数: ALTER SYSTEM SET "_ENABLE_SPACE_PREALLOCATION" = 3;  

5、 技术原理 smco

smco的含义 SMCO (Space Management Coordinator) For Autoextend On Datafiles And How To Disable/Enable (Doc ID 743773.1)     翻译:    

6、 总结建议 

1、该问题 最终结论( Bug 36330602,未发布的bug)(Doc ID 3013880.1) 2、我们要了解undo表空间,Undo段中区3中状态: DBA_UNDO_EXTENTS的STATUS列 三种状态: ACTIVE 未提交的 Undo信息 事物还在活动, ACTIVE状态的Undo区不会被覆盖。 EXPIRED 过期的 Undo信息 事务已经提交且超过了 UNDO_RETENTION指定时间,该状态可以被覆盖使用。   UNEXPIRED 提交的未过期 Undo信息:表示事务已经提交但是还没有超过UNDO_RETENTION指定时间,该状态可以被覆盖使用。 3、Undo相关报错 ORA-30036 如果 undo 表空间设置为 guarantee, 那么当 undo表空间的 expire d段不够时 , 不会覆盖 unexpire d状态的undo段 , 就会出现事务失败 ,ORA-30036 错误。 ORA-01555 如果 undo 表空间设置为 noguarantee, 那么当 undo表空间的 expire d不够时 , 会强行覆盖 unexpired 的段 , 来保证事务的成功执行 , 这样可能会导致出现 ORA-01555 错误 , 因为保留的旧数据被覆盖掉了。 查看是否为 guarantee select tablespace_name,contents,retention from dba_tablespaces;   Undo_retention 默认 900,就是15分钟 只要表空间足够, Oracle内部会尽量保证将Undo数据保留超过undo_retention设置的时间。 4、 事务回滚 事物未回滚情况:数据库 Abort,再启动;Kill;未提交,rollback; 回滚过程: SMON 进程的 CPU 使用率高 在大型事务恢复期间数据库可能会挂起。 如果数据库被关闭中止,则数据库可能在随后的启动过程中挂起。 并行事务恢复 FAST_START_PARALLEL_ROLLBACK LOW- 将最大并行度限制为 2 * CPU_COUNT   默认值 HIGH- 将最大并行度限制为 4 * CPU_COUNT 串行事务恢复 此模式顺序恢复事务。 FAST_START_PARALLEL_ROLLBACK 参数设置为 false 将启用串行事务恢复。 alter system set fast_start_parallel_rollback=false; 死事务,一般是事务正在跑的时候,被 kill掉了,或者数据库shutdown abort了,那么当数据库再次启动的时候,这些事务就需要做回滚。 在一般情况下,并发的回滚总是比串行的快,一般在系统资源可以接受的范围内采用并发回滚,但是 也有 例外 情况 ,就是并发的子进程之间存在资源冲突的情况 所以我们有时候发现回滚时业务也卡住了 在并发子进程之间需要的资源冲突时,往往此时 smon的等待事件是长期处于Wait for stopper event to be increased,而子进程的等待事件是较多出现Wait for a undo record。此时,就是子进程冲突了。并发的回滚速度反而不如串行的回滚速度。冲突时,我们需要把fast_start_parallel_rollback 改成 false。   死事务 回滚段查询 select b.name     useg,        b.inst#    instid,        b.status$  status,        a.ktuxeusn xid_usn,        a.ktuxeslt xid_slot,        a.ktuxesqn xid_seq,        a.ktuxesiz undoblocks,        a.ktuxesta txstatus   from x$ktuxe a, undo$ b  where a.ktuxecfl like '%DEAD%'    and a.ktuxeusn = b.us#;     确认事务完成恢复的时间 select usn,        state,        undoblockstotal "Total",        undoblocksdone "Done",        undoblockstotal - undoblocksdone "ToDo",        decode(cputime,               0,               'unknown',               sysdate + (((undoblockstotal - undoblocksdone) /               (undoblocksdone / cputime)) / 86400)) "Estimated time to complete"   from v$fast_start_transactions;      USN STATE     Total       Done       ToDo    Estimated time to c ---------- ---------------- ---------- ---------- ---------- ------------------- 11005 RECOVERING            17772       6624      11148 202 4 -0 7 -03 14:46:05 查询并行恢复的数量: select * from v$fast_start_servers;   STATE       UNDOBLOCKSDONE        PID XID ----------- -------------- ---------- ---------------- RECOVERING            6624         27 FD2A0B008A000000 RECOVERING               0         30 FD2A0B008A000000 RECOVERING               0         32 FD2A0B008A000000 RECOVERING               0         33 FD2A0B008A000000   查询事务恢复的对象:

select decode(px.qcinst_id,               NULL,               username,               ' - ' || lower(substr(s.program, length(s.program) - 4, 4))) "Username",        decode(px.qcinst_id, NULL, 'QC', '(Slave)') "QC/Slave",        to_char(px.server_set) "Slave Set",        to_char(s.sid) "SID",         s.serial#,        decode(px.qcinst_id, NULL, to_char(s.sid), px.qcsid) "QC SID",        px.req_degree "Requested DOP",        px.degree "Actual DOP"   from gv$px_session px, gv$session s  where px.sid = s.sid(+)    and px.serial# = s.serial#  order by 5, 1 desc;   select distinct current_obj#   from v$active_session_history  where SESSION_ID = 145    and SESSION_SERIAL# = 15;    select Object_name, object_type from dba_objects where object_id = 77211;

 

select * from v$fast_start_transactions; USN        SLT        SEQ STATE            UNDOBLOCKSDONE UNDOBLOCKSTOTAL        PID    CPUTIME  PARENTUSN  PARENTSLT  PARENTSEQ XID              PXID             RCVSERVERS ---------- ---------- ---------- ---------------- -------------- --------------- ---------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- 11005         11        138 RECOVERING                 5555           17772         27         21          0          0          0 FD2A0B008A000000 0000000000000000          3   select * from v$rollname where usn=11005;        USN NAME ---------- ------------------------------      11005 _SYSSMU11005_3138824131$   alter system dump undo block "_SYSSMU11005_3138824131$" XID 11005 11 138;   select * from v$diag_info where name='Default Trace File';   object number objn )或者 object id objd   more /ora11203/app/diag/rdbms/crmdb/crmdb/trace/crmdb_ora_8070.trc |grep objn |more * Rec #0x2e  slt: 0x0b  objn: 76496(0x00012ad0)  objd: 76496  tblspc: 4(0x00000004) * Rec #0x2d  slt: 0x0b  objn: 76495(0x00012acf)  objd: 76495  tblspc: 4(0x00000004) * Rec #0x2c  slt: 0x0b  objn: 83147(0x000144cb)  objd: 83147  tblspc: 4(0x00000004) * Rec #0x2b  slt: 0x0b  objn: 76497(0x00012ad1)  objd: 76497  tblspc: 4(0x00000004)   select owner,object_name,object_type from dba_objects where object_id in ('76496','76495','83147','76497'); 

 

相关推荐