Oracle 19c 中 ALTER TABLESPACE ... SHRINK SPACE 对 TEMP 表空间无效,因其仅支持永久表空间段收缩;临时文件扩展后不自动收缩,需重建 TEMP 表空间释放磁盘空间。
alter tablespace ... shrink space 在 oracle 19c 中不生效,执行后无报错但空间不释放——这不是你操作错了,是 oracle 明确不支持对临时表空间做 shrink。
为什么 SHRINK SPACE 对 TEMP 表空间无效
临时表空间(TEMP)底层使用的是临时文件(tempfile),不是普通数据文件;SHRINK SPACE 是为段(segment)设计的 DML 级操作,而临时段在事务结束后即被标记为可重用,不走常规段管理路径。Oracle 文档明确说明:SHRINK 仅适用于永久表空间中的段,对 tempfile 完全无效。
你看到的“成功执行”只是语法通过,实际什么都没做。别再试了。
v$temp_space_header 才是查真实空闲空间的正确视图
别信 DBA_FREE_SPACE 或 DBA_TEMP_FILES 的 bytes 字段——它们只反映文件大小,不反映实际可分配的空闲 extent。真正能告诉你“还能不能分新临时段”的,是:
-
v$temp_space_header:显示每个 tempfile 的free_blocks(可用空闲区数)和used_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显示还有几十 GB,你也可能立刻遇到ORA-01652
重建 TEMP 表空间才是唯一可靠解法
临时文件一旦扩展,Oracle 不会自动收缩高位已分配的 extent,即使所有会话都结束。想真正腾出磁盘空间,必须新建 + 切换 + 删除旧表空间。关键动作顺序不能错:
- 新建临时表空间:
CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '/u01/oradata/ORCL/temp02.dbf' SIZE 2G AUTOEXTEND ON NEXT 100M MAXSIZE 16G; - 切换默认:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2;(注意:这不会影响当前已连接会话的临时表空间,只影响新登录用户) - 确认旧 TEMP 已无活跃使用:
SELECT sid, serial#, username FROM v$session WHERE tempseg_used > 0 AND tablespace = 'TEMP';(结果必须为空) - 删除旧表空间:
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES;(INCLUDING CONTENTS必须加,否则删不掉 tempfile 物理文件)
整个过程数据库无需重启,但必须确保没有后台作业正在跑大规模排序或建索引——否则切换后新会话可能因 temp2 尚未完全就绪而失败。
BLOB/LOB 操作是隐藏的长期占用源
如果你查 v$sort_usage 或 v$session 找不到明显大排序会话,但 v$temp_space_header.free_blocks 持续为 0,大概率是 LOB 相关操作(如 DBMS_LOB.CREATETEMPORARY、XMLType 处理、JSON 解析)在后台悄悄占着临时段不放。这类段不会出现在 v$sort_usage,但会锁住临时空间直到 session 断开或显式 DBMS_LOB.FREETEMPORARY。
临时缓解办法:ALTER SYSTEM KILL SESSION 'sid,serial#' 杀掉可疑会话;长期解法:代码中必须配对调用 FREETEMPORARY,且避免在长连接中反复创建临时 LOB。


















