ora-30036 根本原因是 undo 表空间物理耗尽或被长事务锁死;需先查 dba_tablespace_usage_metrics 确认使用率 ≥95%,再联查 v$transaction 与 v$session 识别运行超30分钟且 used_ublk>10000 的僵尸事务。

ORA-30036 不是临时卡顿,而是 UNDO 表空间物理空间已耗尽或被长事务锁死,必须立刻干预——扩容不是唯一解,但通常是最快生效的手段。
怎么确认真的是 UNDO 表空间满了
别一看到错误就 rush 扩容。先验证是不是真满,还是被“僵尸事务”占着不放:
- 查实时使用率:
SELECT tablespace_name, used_percent FROM dba_tablespace_usage_metrics WHERE tablespace_name = 'UNDOTBS1'—— 若used_percent ≥ 95%,基本可判定物理空间告急 - 查长事务占用:
SELECT s.sid, s.serial#, s.username, t.used_ublk, t.start_time FROM v$transaction t JOIN v$session s ON t.ses_addr = s.saddr WHERE t.used_ublk > 10000 AND t.start_time —— <code>USED_UBLK > 10000且运行超 30 分钟,大概率是未提交的大批量 DML - 注意:
V$UNDOSTAT的MAXQUERYLEN只反映历史最长查询时间,不能代表当前占用;UNDOBLKS是累计值,也不等于实时压力
加数据文件比调 UNDO_RETENTION 更直接有效
UNDO_RETENTION 是保留建议值,不是强制锁定期。空间紧张时 Oracle 仍会覆盖旧 UNDO,调大它不解决空间不足问题,反而可能加剧争用。
- 优先添加新数据文件(最安全):
ALTER TABLESPACE UNDOTBS1 ADD DATAFILE '/u01/oradata/yourdb/undotbs02.dbf' SIZE 2G AUTOEXTEND ON NEXT 100M MAXSIZE 8G - 若磁盘受限,只能扩现有文件:先查是否支持自动扩展:
SELECT file_name, autoextensible, maxbytes FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';再执行:ALTER DATABASE DATAFILE '/u01/oradata/yourdb/undotbs01.dbf' AUTOEXTEND ON NEXT 200M MAXSIZE 4G - 路径必须有写权限,Oracle OS 用户需能访问;
MAXSIZE UNLIMITED在生产环境慎用,建议设明确上限(如8G),避免填满磁盘
批量 DML 必须分事务提交,否则 UNDO 压力翻倍
一条 UPDATE 影响 50 万行,UNDO 不按“行”存,而是按“块变更前镜像”存。全在一个事务里提交,UNDO 瞬间暴涨,极易触发 ORA-30036。
- 典型场景:导入(
impdp)、历史数据清理(DELETE)、大表更新(UPDATE ... WHERE ...) - 实操建议:用
ROWNUM或DBMS_PARALLEL_EXECUTE分批,每 5000–10000 行COMMIT一次 - 导入时务必加参数:
commit=y(Data Pump)或显式控制提交粒度;否则默认单事务导入整个表,6.23G 表极易压垮 UNDO
重建 UNDO 表空间是兜底方案,但风险高
当原 UNDOTBS1 文件损坏、无法扩容、或存在大量不可回收的过期 UNDO 段时,才考虑重建。
- 步骤顺序不能错:先建新 UNDO 表空间 →
ALTER SYSTEM SET undo_tablespace = 'NEW_UNDOTBS'→ 确认切换完成(查v$parameter和v$rollname)→ALTER TABLESPACE UNDOTBS1 OFFLINE→ 最后DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES - 切勿跳过离线步骤直接删旧表空间,否则可能引发实例崩溃
- 重建过程需停业务或严格窗口期,且新 UNDO 表空间必须提前配置好
AUTOEXTEND和合理MAXSIZE
真正容易被忽略的是:长事务和批量操作的耦合性。一个未提交的 UPDATE 占着 UNDO,会让后续所有并发事务排队失败;而分批提交逻辑若写在应用层,数据库根本感知不到——所以排查时一定得从 v$transaction + v$session 联查入手,而不是只盯着表空间大小。











