ora-01652报错时v$sort_usage为空但dba_temp_files显示100%使用率属正常现象,因临时表空间已分配空间不自动释放;需先确认是否存在blocks>0且status='active'的真实活跃会话,而非盲目kill或重启;若确为smon未及时清理的高位extent残留,重建临时表空间(新建→切换→迁移→删除)是最可靠在线解决方案。
ora-01652 报错、v$sort_usage 为空但 dba_temp_files 显示 100% 使用率——这不是 bug,是 oracle 临时表空间的正常行为:已分配空间不自动回收。重启数据库最彻底,但不是唯一解;手动杀进程也未必管用,关键得看“谁真占着、谁只是标记残留”。
查清楚到底有没有活会话在用 TEMP
别一看到使用率 100% 就急着 kill 或重启。先确认是不是真有活跃排序在跑:
-
v$sort_usage和v$session关联查,重点看blocks > 0且status = 'ACTIVE'的会话 - 如果
v$sort_usage返回空,但v$temp_space_header中free_blocks = 0,大概率是高位 extent 没释放,属于“已分配但空闲”,不是真占用 - 执行
SELECT * FROM v$tempseg_usage WHERE session_num NOT IN (SELECT sid FROM v$session)—— 若有结果,才是孤儿临时段(需 SMON 清理)
为什么手动 kill 会话后空间还不释放
kill 只是断开会话连接,不等于立刻释放临时段。Oracle 要等 SMON 进程下一次轮询(默认每 5 分钟)或触发合并动作才能回收。更麻烦的是:
- 客户端网络中断但服务器 socket 未超时,会话状态可能卡在
INACTIVE,last_call_et > 3600才算可疑 - 并行查询、分布式事务残留会让 SMON 获取
ST锁失败,直接跳过清理 - kill 后若应用重连并立即发起新排序,可能直接写到旧 tempfile 高位,导致
RESIZE失败(ORA-03297)
重启数据库是最稳妥的强制清理方式
SMON 在实例启动时一定会做全量临时段扫描和清理,这是 Oracle 官方文档明确保证的行为。但注意:
- 必须是
SHUTDOWN IMMEDIATE+STARTUP,ABORT后启动虽快,但可能跳过部分清理逻辑 - 如果数据库不能停,就别强求“重启”——此时重建临时表空间比等 SMON 更可控
- 重启前建议先执行
ALTER TABLESPACE temp COALESCE,哪怕只触发一次合并,也可能顺带唤醒 SMON 清理
重建 TEMP 表空间比 resize 或 shrink 更可靠
ALTER DATABASE TEMPFILE ... RESIZE 和 SHRINK SPACE 在多数场景会失败,因为 Oracle 不允许把 tempfile 缩到已有 extent 下方。真正能释放磁盘空间的只有:
- 新建临时表空间:
CREATE TEMPORARY TABLESPACE temp_new ... - 切换默认:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_new - 迁移用户:
ALTER USER xxx TEMPORARY TABLESPACE temp_new(检查dba_users确保无遗漏) - 删旧空间:
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES(缺INCLUDING CONTENTS就不会删物理文件)
整个过程在线完成,但必须避开建索引、大排序窗口期,否则新 TEMP 尚未就绪就可能报 ORA-01652。











