ORA-30036错误本质是UNDO表空间物理耗尽或被长事务锁死,需查DBA_TABLESPACE_USAGE_METRICS确认used_percent≥95%,关联V$TRANSACTION与V$SESSION识别USED_UBLK>10000且START_TIME超30分钟的长事务,优先添加自动扩展数据文件扩容,并分批提交批量DML。

ORA-30036 不是磁盘满或权限问题,而是 UNDO 表空间物理上没空间可分配段 —— 本质是当前 UNDO 表空间的数据文件已用尽(无 free space),或所有数据文件都达到 maxsize 上限,或根本没开 autoextend。
查清 UNDO 表空间真实剩余容量
别只看 dba_free_space;19c 中 UNDO 表空间的“空闲”受 undo_retention 和活动事务双重压制,dba_free_space 显示有空闲 ≠ 实际能分配新 undo 段。必须结合三处验证:
-
SELECT tablespace_name, status, contents FROM dba_tablespaces WHERE contents = 'UNDO';—— 确认当前生效的 UNDO 表空间名(如UNDOTBS1) -
SELECT file_name, bytes/1024/1024 "MB", maxbytes/1024/1024 "MAX_MB", autoextensible FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';—— 关键看autoextensible是否为YES,以及maxbytes是否已到硬上限(比如 32G 文件系统限制) -
SELECT SUM(bytes)/1024/1024 "FREE_MB" FROM dba_undo_extents WHERE status = 'EXPIRED';—— 只有EXPIRED的 extent 才真能复用;若结果接近 0,说明 retention 太长或事务堆积,dba_free_space的“空闲”只是假象
优先扩容:加文件比调大小更稳妥
在 19c 中,对单个 UNDO 数据文件执行 resize 有风险:若该文件已接近 32GB(常见于 ext4 或某些 ASM 配置),Oracle 可能拒绝扩大;而新增文件无此限制,且不影响现有事务。
- 路径必须有足够磁盘空间,且 Oracle 用户有写权限:
df -h /u01/oradata先确认 - 执行:
ALTER TABLESPACE UNDOTBS1 ADD DATAFILE '/u01/oradata/ORCL/undotbs02.dbf' SIZE 4G AUTOEXTEND ON NEXT 512M MAXSIZE 32G; - 注意:不要省略
AUTOEXTEND ON—— 19c 默认不开启,不加则新增文件仍是死容量 - 无需重启、无需切换表空间,命令成功即刻生效
切换 UNDO 表空间前必须等旧段 offline
创建新 UNDO 表空间(如 UNDOTBS2)后,ALTER SYSTEM SET undo_tablespace = 'UNDOTBS2' 立即生效,但旧表空间里的 rollback segment 不会立刻释放 —— 它们要等所有依赖它的事务结束(commit/rollback)或超时(由 undo_retention 控制)才会转为 OFFLINE。强行删会报 ORA-01548。
- 监控旧段状态:
SELECT segment_name, status FROM dba_rollback_segs WHERE tablespace_name = 'UNDOTBS1';—— 全部变成OFFLINE才安全 - 若卡在
ONLINE或PENDING OFFLINE,检查长事务:SELECT usn, xidusn||'.'||xidslot||'.'||xidsqn "XID", start_time, used_ublk FROM v$transaction ORDER BY start_time; - 不建议直接 kill session:可能引发应用层逻辑错乱;优先联系业务方确认能否提交/回滚
undo_retention 设置不当会掩盖真实瓶颈
19c 默认 undo_retention = 900(15 分钟),但很多 OLTP 系统批量作业跑得比这久。如果设太高(比如 3 小时),即使空间充足,expired extent 也极少,dba_undo_extents 里全是 UNEXPIRED,等于把 UNDO 当成“只增不减”的日志池 —— 这不是扩容能解决的。
- 查当前值:
SHOW PARAMETER undo_retention - 合理值应略大于最长事务运行时间;可先临时调低测试:
ALTER SYSTEM SET undo_retention = 600 SCOPE=BOTH;(10 分钟) - 切勿盲目设成
UNLIMITED:19c 不支持该值,会报ORA-02097 - 配合
RETENTION GUARANTEE要慎用:它强制保留,会让空间更紧张,仅用于闪回查询强依赖场景
真正卡住的点往往不在“怎么加空间”,而在“为什么加了还报错”——多数情况是旧 UNDO 段没 offline、autoextend 实际关闭、或 undo_retention 把空间锁死了。动手前务必用那三条 SQL 把这三项钉死,否则扩容只是把报错延后几分钟。











