UNDO表空间持续增长的根源是事务卡住或\_undo\_autotune动态拉高保留时间,需通过v$undostat和v$transaction定位长事务、未提交会话及tuned\_undoretention异常,而非盲目扩容或删文件。

UNDO 表空间持续增长不释放,不是磁盘真被占满,而是有事务卡住或 _undo_autotune 在暗中拉高保留时间。直接扩容或删文件,往往几分钟后新表空间也涨满——问题根本没解决。
查 v$undostat 看历史压力,别只盯当前占用率
当前 DBA_DATA_FILES 显示 UNDOTBS1 占用 95%,这个数字不告诉你“为什么占着”。真正关键的是 v$undostat:它每 10 分钟一条记录,保留最近 4 天,反映真实负载。
-
NOSPACEERRCNT > 0→ 已发生ORA-30036,必须立刻干预 -
MAXQUERYLEN持续大于你设的undo_retention→ 长查询强制保留旧版本,undo被锁死 -
UNDOBLKS高 +TXNCOUNT低 → 单个事务极大(比如未分批的全表DELETE) -
NOSPACEERRCNT = 0且MAXQUERYLEN → 很可能只是长事务没提交,不是配置问题
执行这句快速看趋势:
SELECT BEGIN_TIME, UNDOBLKS, TXNCOUNT, MAXQUERYLEN, NOSPACEERRCNT FROM v$undostat ORDER BY BEGIN_TIME DESC FETCH FIRST 10 ROWS ONLY;
查 v$transaction 找真正在“吃” undo 的会话
很多 DBA 直接切表空间,结果新表空间几分钟后也涨满——因为同一个长事务还在跑。关键字段是 used_ublk 和 idle_mins:
-
idle_mins > 5且used_ublk > 10000→ 极可能挂起(应用忘记COMMIT或被阻塞) -
username是业务账号(非SYSTEM/DBA)→ 找对应开发确认逻辑 -
osuser/machine指向某台应用服务器 → 可临时重启该连接池,而非杀会话
别漏掉关联 v$session 查来源:
SELECT s.sid, s.serial#, s.username, s.osuser, s.machine,
t.start_time, t.used_ublk, (SYSDATE - t.start_time) * 24 * 60 idle_mins
FROM v$transaction t
JOIN v$session s ON s.taddr = t.addr
ORDER BY t.start_time;小心 _undo_autotune 把 undo_retention 给“覆盖”了
Oracle 10.2+ 默认开启 _undo_autotune=true,它会无视你手动设的 undo_retention,按实际负载动态拉高保留时间——尤其当 undo 表空间非自动扩展时,为防 ORA-01555,它可能把 tuned_undoretention 推到几小时甚至一天。
- 查当前是否生效:
SELECT tuned_undoretention FROM v$undostat WHERE rownum = 1 - 如果远高于你设的
undo_retention,且磁盘紧张,可关掉:ALTER SYSTEM SET "_undo_autotune"=false - 注意:该参数需重启生效(
scope=spfile),且在 12.1 后已修复相关 bug,但 11g 仍存在风险
别急着重建 undo 表空间,先确认有没有活动回滚段
切换或删除 undo 表空间时遇到 ORA-01548: 已找到活动回退段 '_SYSSMU1$',说明还有活跃事务在用旧段。此时强行 DROP TABLESPACE 会失败。
- 先查
DBA_ROLLBACK_SEGS状态:SELECT segment_name, status FROM dba_rollback_segs - 状态为
ONLINE的段,对应v$transaction中仍有未提交事务 - 确认无业务影响后,再用
ALTER SYSTEM SET undo_tablespace=newundotbs切换,等旧段自动转为OFFLINE后再删 - 重建操作本身不释放物理文件空间,只是让 Oracle 重用块;若要真正回收磁盘,得靠
ALTER DATABASE DATAFILE ... RESIZE(前提是文件尾部为空闲)
真正卡住 undo 释放的,往往是那个没人管的、idle 了十几分钟却还挂着的事务,或者被 _undo_autotune 悄悄推到 8 小时的保留窗口——这些细节,在 v$undostat 和 v$transaction 里才看得见。


















