查v$undostat不能反映当前瞬时占用率,它每10分钟采样一次,统计的是时段内活动量;真正体现“此刻”物理占用的是dba_undo_extents与dba_data_files联合计算的使用率,需动态获取当前undo_tablespace并过滤UNEXPIRED/EXPIRED状态。

查 v$undostat 能看到最近 1 小时的实时使用趋势,但不是当前瞬时占用率
很多人直接查 v$undostat 想看“现在用了多少”,结果发现 UNDOBLKS 和 TUNED_UNDORETENTION 是滚动统计值,反映的是过去一段时间的平均或峰值,不是当前实际占用。真正反映“此刻” UNDO 表空间物理块占用的是 dba_undo_extents 和数据文件视图。
-
v$undostat每 10 分钟采样一次,BEGIN_TIME/END_TIME范围内统计的是该时段的事务回滚段活动量,不是空间占用快照 - 想定位“当前正在被哪些事务占用”,得结合
v$transaction和v$rollname - 该视图里
MAXQUERYLEN(秒)和UNXPSTEALCNT(非过期块被偷用次数)对判断是否需要调大UNDO_RETENTION更有用
查 dba_undo_extents + dba_data_files 才能得到真实使用率
UNDO 表空间本质是普通表空间,其使用率计算逻辑和其他表空间一致:已分配的 UNDO 段所占数据文件块数 ÷ 数据文件总块数。关键是要过滤出状态为 UNEXPIRED 或 EXPIRED 的 extent —— 它们才是真正被 UNDO 段占用的物理空间。
- 执行以下语句可得精确百分比:
SELECT ROUND((SUM(bytes)/SUM(maxbytes))*100, 2) AS "Used_Pct" FROM dba_data_files d JOIN dba_undo_extents u ON d.file_id = u.file_id WHERE d.tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace') AND u.status IN ('UNEXPIRED', 'EXPIRED'); - 注意:
dba_undo_extents只包含当前属于 UNDO 表空间的 extent;如果 UNDO 表空间启用了自动扩展(AUTOEXTENSIBLE = YES),maxbytes可能远大于当前bytes,此时分母要用maxbytes而非user_bytes - 若 UNDO 表空间未启用自动扩展,
maxbytes = bytes,此时应改用dba_free_space计算:已用 = 总大小 − 空闲大小
show parameter undo 和 v$parameter 必须核对,否则查询结果可能指向错误表空间
Oracle 允许运行时切换 UNDO 表空间(ALTER SYSTEM SET undo_tablespace = ...),但新设置不会立即刷新所有会话的上下文。如果你在某个会话里查 dba_undo_extents 却没加过滤条件,可能扫到旧 UNDO 表空间的历史 extent(尤其当旧表空间尚未被彻底 drop)。
- 务必用
SELECT value FROM v$parameter WHERE name = 'undo_tablespace'动态获取当前生效值,不要硬编码表空间名 -
v$parameter返回的是当前实例级配置;而v$system_parameter才反映 SPFILE 中的持久化设置,两者不一致说明刚用ALTER SYSTEM修改过但没写入 SPFILE - 如果查询结果为空,先确认
value是否为NULL(表示使用默认UNDOTBS1)或拼写是否含空格/大小写问题(Oracle 默认表空间名全大写)
长期高水位但无 ORA-30013 错误?重点看 v$rollstat 里的 SHRINKS 和 WRAPS
UNDO 表空间使用率持续 85%+ 却没报错,不代表安全。Oracle 在空间不足时会尝试收缩回滚段(SHRINKS)、重用过期块(EXPIRED),甚至强制覆盖未过期块(UNXPSTEALCNT > 0),这些行为不会立刻触发错误,但会导致查询报 ORA-01555: snapshot too old。
-
SELECT usn, shrinks, wraps, extends FROM v$rollstat——shrinks频繁说明回滚段频繁收缩,是空间紧张的早期信号 -
wraps高意味着事务频繁跨区分配,结合extends增长快,说明 UNDO 段增长失控,需检查长事务或批量 DML 是否缺乏分批控制 - 即使使用率仅 60%,若
v$undostat.UNXPSTEALCNT连续多个采样周期 > 0,就已在牺牲一致性换取空间复用,应优先优化事务设计而非扩容
v$transaction.start_time 早于当前时间 1 小时以上,再高的使用率数字都不如 kill 掉它来得实在。


















