ora-30036 错误需从数据库侧紧急干预:查 undo 表空间真实使用率(用 dba_tablespace_usage_metrics)、揪出长事务、优先启用 autoextend 扩容、调整 undo_retention 并分批提交大事务。

ORA-30036 不是 Java 或应用层能“修好”的错误,它明确指向 Oracle 的 UNDOTBS1(或你当前使用的 undo 表空间)已无法分配新 undo 段——必须立刻从数据库侧干预,否则所有 DML 会持续失败。
查真实使用率,别信 DBA_FREE_SPACE 的“空闲 MB”
很多 DBA 看到 DBA_FREE_SPACE 还剩几百 MB 就松口气,但 undo 段需要连续空间,且受未提交事务和 undo_retention 锁定,空闲块可能完全不可用。直接跑这个语句看实时水位:
SELECT tablespace_name,
ROUND(used_space*8192/1024/1024, 2) AS used_mb,
ROUND(tablespace_size*8192/1024/1024, 2) AS total_mb,
ROUND(used_percent, 2) AS used_pct
FROM dba_tablespace_usage_metrics
WHERE tablespace_name LIKE 'UNDO%';
-
used_pct > 95%是红色警报;used_pct = 100且不下降,基本说明有长事务卡住或 autoextend 关闭 - 如果结果为空,确认你有
SELECT_CATALOG_ROLE权限,或让 DBA 执行 - 不要依赖
dba_free_space的SUM(bytes),它不反映 undo 段可分配能力
揪出占用最多 undo 的“幽灵事务”
长事务(尤其未提交的 UPDATE/DELETE)会锁死 undo 块,导致新事务无处落脚。运行:
SELECT s.sid, s.serial#, s.username, s.osuser, s.machine,
t.used_ublk, t.start_time, sq.sql_text
FROM v$transaction t
JOIN v$session s ON t.ses_addr = s.saddr
LEFT JOIN v$sql sq ON s.sql_id = sq.sql_id
ORDER BY t.used_ublk DESC;
- 重点看
used_ublk > 10000或start_time超过 30 分钟的行 -
sql_text为空?说明会话已断连但事务没清理,需ALTER SYSTEM KILL SESSION 'sid,serial#' - 若看到 ETL 工具、Java 应用连接池里的
update ... where rownum ,这就是根因——应用层必须分批提交
紧急扩容:优先开 AUTOEXTEND,不是 RESIZE
磁盘还有空间?立刻启用自动扩展。硬 RESIZE 容易因文件系统碎片失败,且不能防下一次爆满。
先查当前文件状态:
SELECT file_name, bytes/1024/1024 AS mb, autoextensible FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';
- 如果
autoextensible = 'NO':先执行ALTER DATABASE DATAFILE '/u01/oradata/ORCL/undotbs01.dbf' AUTOEXTEND ON NEXT 512M MAXSIZE 32G; - 如果文件已达
MAXSIZE上限:先ALTER DATABASE DATAFILE ... AUTOEXTEND ON再RESIZE,比直接RESIZE更稳 -
MAXSIZE UNLIMITED在 ASM 或某些存储策略下被禁用,设具体值(如32G)更可靠
长期规避:调 undo_retention 和拆大事务
临时扩容只是止痛,真正治本要控制 undo 生成节奏:
-
undo_retention默认 900 秒(15 分钟),高并发场景建议调到10800(3 小时):ALTER SYSTEM SET undo_retention = 10800 SCOPE=BOTH; - Java 应用批量删改必须按
500~1000行分批,每批后commit,避免单事务撑爆 undo - 数据泵导入时加
EXCLUDE=INDEX,CONSTRAINT,索引和约束留到导入后再建,大幅降低 undo 压力
最常被忽略的一点:used_percent = 100 时,kill session 可能不立即释放空间——Oracle 需等 rollback 完成,而大事务 rollback 本身也耗时。此时扩容 + 杀会话要同步做,不能只等 kill 生效。











