oracle 19c中undo表空间不能直接shrink或resize,唯一可靠方法是新建表空间、切换undo_tablespace、等待旧段离线后删除旧表空间并清理物理文件;因文件头部含固定回滚段头且hwm不可下移,强行resize会报ora-03297。

UNDO表空间不能靠“猜”,得看v$undostat的实际负载
Oracle 19c 的 UNDO 表空间大小不是凭经验拍脑袋定的,而是由业务峰值、undo_retention 和 db_block_size 共同决定的。直接套用“OLTP设2G”“DSS设10G”这类经验值,往往导致空间浪费或 ORA-01555 错误。
关键数据来源是 v$undostat,它每10分钟记录一次历史指标,包含:undoblks(该时段产生的 undo 块数)、maxquerylen(最长查询运行秒数)、ssolderrcnt(因 undo 不足导致的快照过旧错误次数)。
- 查最近24小时峰值每秒 undo 块生成率:
SELECT MAX(undoblks / ((end_time - begin_time) * 86400)) AS "Peak Blocks/sec" FROM v$undostat WHERE begin_time > SYSDATE - 1;
- 查当前
undo_retention值:SHOW PARAMETER undo_retention - 查
db_block_size:SHOW PARAMETER db_block_size - 计算理论最小值(单位 MB):
Peak Blocks/sec × undo_retention × db_block_size / 1024 / 1024
注意:如果 ssolderrcnt > 0,说明当前配置已不够用,必须按峰值重新算,不能只看平均值。
别信 AUTOEXTEND ON,生产环境必须设 MAXSIZE
UNDO 表空间一旦开启 AUTOEXTEND ON 却不设 MAXSIZE,等于放任它无限增长——Oracle 默认就是 UNLIMITED,磁盘爆掉前几乎不会预警。
ALTER TABLESPACE undotbs AUTOEXTEND ON 是无效语法,会报 ORA-00905;真正生效的是对单个数据文件的操作:
- 先查当前文件状态:
SELECT file_name, autoextensible, maxbytes/1024/1024 AS max_mb FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';
- 若
autoextensible = 'NO',需先开扩展再设上限:ALTER DATABASE DATAFILE '/path/to/undotbs01.dbf' AUTOEXTEND ON NEXT 100M MAXSIZE 4G; -
MAXSIZE 4G比MAXSIZE 4096M更安全——单位明确,避免 Oracle 把没带单位的数字当成字节
特别注意:RAC 或 ASM 环境下,路径大小写、+号前缀、斜杠方向必须与 dba_data_files.file_name 完全一致,否则命令静默失败。
收缩 UNDO 表空间唯一靠谱方式:换表空间,不是 shrink
Oracle 19c 的 UNDO 表空间数据文件无法直接 RESIZE 或 SHRINK,因为文件头部固定存放回滚段头,高水位(HWM)卡死不动。强行执行 ALTER DATABASE DATAFILE ... RESIZE 会报 ORA-03297,提示“file contains used data beyond requested RESIZE value”。
真实可行路径只有三步,且顺序不可颠倒:
- 确认当前容器:
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;(CDB$ROOT 还是某个 PDB?) - 创建新 UNDO 表空间:
CREATE UNDO TABLESPACE undotbs2 DATAFILE '+DATA' SIZE 2G AUTOEXTEND ON NEXT 200M MAXSIZE 4G;(大小按上一步算出的理论值 +20% 余量) - 切换并等待旧段离线:
ALTER SYSTEM SET undo_tablespace=undotbs2 SCOPE=BOTH;→ 查SELECT segment_name, status FROM dba_rollback_segs WHERE tablespace_name = 'UNDOTBS1';→ 全部为OFFLINE后再删 - 删除旧表空间(务必带
AND DATAFILES):DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;
漏掉 AND DATAFILES 在 ASM 环境下会导致物理文件残留,后续重建同名表空间时可能报 ORA-01119。
_undo_autotune 开启时,手动调 undo_retention 是无效的
Oracle 19c 默认启用隐藏参数 _undo_autotune = TRUE,它会动态拉长实际保留时间,优先保障空间可用性而非你设的 undo_retention 值。此时即使你把 undo_retention 改成 600,监控里看到的 UNEXPIRED undo 段占比仍可能高达 90% 以上。
验证是否被接管:
SELECT value FROM v$parameter WHERE name = '_undo_autotune';
若返回 TRUE,临时禁用需重启实例:ALTER SYSTEM SET "_undo_autotune" = FALSE SCOPE=SPFILE;。但这是紧急手段,日常应通过调整新 UNDO 表空间大小来应对,而不是关 autotune。
真正容易被忽略的是:PDB 级别的 undo_tablespace 设置独立于 CDB$ROOT,切表空间前必须在目标容器内执行,否则切换无效。











