Oracle 19c无法直接shrink UNDO表空间,这是设计限制;必须通过新建UNDO表空间、切换undo_tablespace参数、等待旧表空间回滚段全部OFFLINE后删除旧表空间(含DATAFILES)来实现空间释放。

Oracle 19c 无法直接 shrink UNDO 表空间,这是设计限制
你执行 ALTER DATABASE DATAFILE ... RESIZE 或 ALTER TABLESPACE undotbs1 SHRINK SPACE 一定会失败,报错类似 ORA-30036 或 ORA-1237。根本原因不是操作不对,而是 UNDO 文件头部固定存储回滚段头信息,高水位(HWM)无法下移;哪怕所有回滚段都 OFFLINE,文件物理结构也不支持在线收缩。
所谓“缩小 UNDO 表空间”,实际是替换:新建一个更小的 UNDO 表空间,切换过去,再删掉旧的。这不是权宜之计,是 Oracle 19c 官方唯一推荐路径。
先确认是不是真被占满,还是被“卡住”了
别急着建新表空间。很多情况下空间没真用完,只是被未过期或活跃事务锁死:
-
SELECT tablespace_name, status, SUM(bytes)/1024/1024 "MB" FROM dba_undo_extents GROUP BY tablespace_name, status ORDER BY 1,2;—— 关注UNEXPIRED占比。如果远高于EXPIRED,说明_undo_autotune=TRUE(默认开启),它会动态延长undo_retention,导致空间无法释放 -
SELECT usn, xacts, status, rssize/1024/1024 "MB" FROM v$rollstat ORDER BY rssize DESC;—— 看是否有ACTIVE段长期不释放。若有,连查v$transaction和v$session找出对应SID,确认是否事务卡死或未提交 -
SHOW PARAMETER undo_retention和SELECT value FROM v$parameter WHERE name = '_undo_autotune';—— 若后者为TRUE,调低undo_retention无效;紧急时可临时禁用该隐藏参数(需重启,慎用)
创建并切换到新 UNDO 表空间(CDB/PDB 必须分清)
Oracle 19c 中 CDB 和每个 PDB 各自管理自己的 UNDO 表空间。操作前务必确认当前容器:
- 运行
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;查当前是CDB$ROOT还是某个 PDB - 在目标容器中执行:
CREATE UNDO TABLESPACE undotbs2 DATAFILE '+DATA' SIZE 500M AUTOEXTEND ON NEXT 100M MAXSIZE 2G;—— 初始大小按负载定,500M 是保守起点;ASM 路径需匹配你的磁盘组 -
ALTER SYSTEM SET undo_tablespace=undotbs2 SCOPE=BOTH;——SCOPE=BOTH确保写入 spfile,避免实例重启后失效 - 等待原 UNDO 表空间所有回滚段变为
OFFLINE:SELECT segment_name, status FROM dba_rollback_segs WHERE tablespace_name = 'UNDOTBS1';—— 全部返回OFFLINE后才可继续下一步
删除旧 UNDO 表空间必须带 AND DATAFILES
这步最容易出错,尤其在 RAC 或 ASM 环境下:
- 执行
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;—— 缺少AND DATAFILES会导致只删数据字典,物理文件仍留在 ASM 磁盘组里,磁盘空间根本没释放 - 若报
ORA-30013: undo tablespace 'UNDOTBS1' is currently in use,说明仍有隐式事务(比如未结束的查询、延迟块清理等),不是v$session显示的显式事务;可稍等几分钟再试,或检查v$fast_start_servers是否有恢复进程在跑 - 删除后建议立即验证:
SELECT name FROM v$datafile WHERE name LIKE '%undotbs1%';应无返回;再查 ASM 磁盘组剩余空间确认是否真实释放
真正麻烦的不是步骤本身,而是判断“能不能删”——OFFLINE 不等于“安全可删”,有些后台事务不会立刻反映在 v$rollstat 里。生产环境建议在业务低峰期操作,并预留回退窗口。


















