唯一安全、彻底释放磁盘空间的方法是重建临时表空间:新建temp2、切换默认、确认旧TEMP无活跃会话、DROP INCLUDING CONTENTS AND DATAFILES;SHRINK SPACE和RESIZE在19c中对TEMP无效,因底层不支持段级收缩且高位extent残留导致ORA-03297或静默失败。

别用 ALTER DATABASE TEMPFILE ... RESIZE,也别信 SHRINK SPACE 能自动生效——19c 中对 TEMP 表空间执行 SHRINK SPACE 会静默失败,RESIZE 大概率报 ORA-03297;唯一安全、彻底释放磁盘空间的方法是重建临时表空间。
为什么 SHRINK SPACE 在 19c 中看似成功实则无效
Oracle 文档明确限定:SHRINK SPACE 只适用于永久表空间中的段(segment),而临时表空间使用的是临时文件(tempfile),其空间管理不走段级逻辑。即使命令执行无报错,DBA_TEMP_FILES.BYTES 和磁盘实际占用都不会变。这不是权限或语法问题,是底层设计限制。
常见误判点:
- 看到
v$version显示11.1.0.0或更高,就以为支持 TEMP SHRINK —— 实际上该功能在 11g 是“伪支持”,仅对极简场景(如刚建完空 TEMP)有效;19c 已彻底移除逻辑有效性 - 查
DBA_FREE_SPACE或DBA_TEMP_FILES判断空间是否“真满” —— 这两个视图根本不反映临时段实时可分配状态 - 执行
ALTER TABLESPACE temp SHRINK SPACE后立刻查df -h—— 磁盘空间纹丝不动,因为没真正删文件
怎么确认 TEMP 真的“假满”而不是磁盘真爆了
临时文件扩展后高位区(high watermark)残留已分配但空闲的 extent,控制文件仍标记为“已用”,导致 RESIZE 必然失败。真实可用空间必须看 v$temp_space_header:
-
FREE_BLOCKS字段才是当前可立即重用的块数,不是估算值 - 计算真实空闲 MB:
SELECT tablespace_name, ROUND((free_blocks * block_size) / 1024 / 1024) free_mb FROM v$temp_space_header; - 如果
free_mb接近 0,哪怕DBA_TEMP_FILES.BYTES显示还有 30G,也会立刻触发ORA-01652
生产库安全重建 TEMP 表空间的最小必要步骤
整个过程数据库在线,但必须避开大排序、建索引、ETL 等高峰期,否则新 TEMP 尚未接管时可能因资源争抢失败。
- 新建中转 TEMP 表空间:
CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '/u01/oradata/ORCL/temp02.dbf' SIZE 2G AUTOEXTEND ON NEXT 100M MAXSIZE 8G;(路径、大小按 ASM 或文件系统实际规划) - 切换全局默认:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2;(注意:只影响新登录会话,老会话仍用旧 TEMP) - 确认旧 TEMP 无活跃使用:
SELECT sid, serial#, username, program FROM v$session WHERE tempseg_used > 0 AND tablespace = 'TEMP';—— 结果必须为空;若有残留,等它自然结束或联系业务方中止长事务,不要硬杀 - 删除旧表空间:
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES;(INCLUDING CONTENTS不可省,否则物理文件留底)
重建后必须做的三件事,否则等于白干
很多人删完旧 TEMP 就以为结束,结果很快发现空间又涨回来、用户报错、甚至备库失效:
- 重建后的 TEMP 表空间名若与原名不同(比如叫
temp2),需重设回标准名:CREATE TEMPORARY TABLESPACE temp TEMPFILE ...+ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp; - 逐个修正用户级绑定:
ALTER USER scott TEMPORARY TABLESPACE temp;——DBA_USERS.TEMPORARY_TABLESPACE不随数据库默认值自动更新 - ADG 备库必须手动补临时文件:
ALTER TABLESPACE temp ADD TEMPFILE '/u01/oradata/CDB1/PDB1/temp01.dbf' SIZE 100M;,否则 switchover 后立刻ORA-25153
真正麻烦的从来不是命令敲错,而是没盯住 v$session 和 v$sort_usage 的实时状态;哪怕一个长事务里藏着一次 ORDER BY,都可能让整个切换卡在最后一步。











