oracle临时表空间100%占用却不显示活跃排序会话是正常设计行为,因已分配的tempfile空间不自动收缩;alter database tempfile resize常因高位存在未释放extent而失败(ora-03297);v$temp_space_header可查真实空闲量,但空闲块不连续时仍无法缩容;shrink tempfile受限严格且rac下不可靠;重建temp表空间(建新→切默认→确认v$sort_usage为0→删旧)是最小风险方案;禁用event 10061等非支持手段。

临时表空间显示 100% 占用但查不到活跃排序会话?这不是 bug,是 Oracle 的设计行为 —— 已分配的 tempfile 空间不会自动收缩,哪怕所有排序都结束了。
为什么 ALTER DATABASE TEMPFILE ... RESIZE 常失败
执行 ALTER DATABASE TEMPFILE '/path/to/temp01.dbf' RESIZE 1G 报 ORA-03297 是最常见现象。原因不是“没空闲空间”,而是高位存在未释放的 extent(即使逻辑上已空闲)。Oracle 检查 resize 边界时,只要该位置之后有任意一个已分配的区,就拒绝缩容。
- 先确认真实空闲范围:查
v$temp_space_header,不是dba_free_space SELECT tablespace_name, file_id, round((free_blocks * block_size)/1024/1024) free_mb FROM v$temp_space_header;- 如果
free_mb很大但RESIZE仍失败,说明空闲块不连续,高位被“钉住” - 别依赖
coalesce:临时表空间不支持ALTER TABLESPACE ... COALESCE
Oracle 11g+ 的 SHRINK TEMPFILE 能用吗
能,但受限严格:必须确保该 tempfile 当前无任何 session 正在使用它,且 shrink 目标不能低于其“高水位”(即最后一个已分配 extent 的末尾)。实际生产中几乎无法满足。
- 查谁在用:
SELECT sid, serial#, username, program FROM v$session WHERE tempseg_used > 0 AND tablespace = 'TEMP'; - 即使结果为空,也可能有隐式占用(如并行查询、物化视图刷新)
-
ALTER TABLESPACE temp SHRINK TEMPFILE '/u01/oradata/ORCL/temp01.dbf' KEEP 512M;多数情况下直接报错或无效果 - 该命令在 RAC 环境下更不可靠,官方文档明确标注“best effort only”
重建 TEMP 表空间是最小风险方案
无需重启库,全程在线,但关键点在于“切换时机”和“旧空间清理条件”。跳过任一检查,可能引发 ORA-01652(无法扩展临时段)。
- 新建临时表空间:
CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '/u01/oradata/ORCL/temp02.dbf' SIZE 2G AUTOEXTEND ON NEXT 512M MAXSIZE 16G; - 切默认:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2; - 等旧 TEMP 彻底“冷下来”:
SELECT COUNT(*) FROM v$sort_usage WHERE tablespace = 'TEMP';必须返回 0 - 删旧表空间:
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES;—— 少INCLUDING CONTENTS会失败 - 注意:临时表空间不能只剩一个 tempfile 后再删它;必须先建新、再切、再删整个表空间
别碰 EVENT 10061 或 DROP_SEGMENTS
这些诊断事件曾被当作“急救手段”,但 Oracle 官方已在 12c 后标记为非支持路径。强行触发可能导致临时段元数据损坏,后续出现 ORA-00600 内部错误。
-
ALTER SESSION SET EVENTS 'immediate trace name DROP_SEGMENTS level 4';只对特定 ts# 有效,且要求实例处于 QUIESCE 状态 - 在 19c+ 上该事件已被弃用,执行后无日志、无反馈、也无实际释放
- 真正有效的“紧急释放”只有两种:重启库(SMON 清理),或重建 TEMP(推荐)
重建 TEMP 表空间看着步骤多,其实核心就三步:建新、切默认、删旧。最容易被跳过的其实是中间那个“确认无会话使用旧 TEMP”的等待 —— 有人看到 v$sort_usage 为空就立刻删,结果某后台作业刚提交一个大排序,瞬间报错。留出 2–3 分钟静默期,比反复重试安全得多。











