查v$sort_usage才能准确识别真正占用TEMP段的会话,因v$session中status='INACTIVE'可能仍挂载未释放的临时段;需关联查询确认segtype、blocks及mb_used,超100MB且last_call_et>3600即属异常占用。

查 v$sort_usage 才知道谁真占着 TEMP 段
只看 v$session 里的 status = 'INACTIVE' 容易误判——空闲会话可能刚做完大排序,tempseg_used 还挂着没清。必须关联 v$sort_usage 确认是否真在用临时段:
SELECT s.sid, s.serial#, s.username, u.tablespace, u.segtype, u.blocks * 8 / 1024 AS mb_used FROM v$sort_usage u JOIN v$session s ON u.session_addr = s.saddr WHERE u.tablespace = 'TEMP' ORDER BY u.blocks DESC;- 如果
mb_used> 100 MB 且会话已空闲超 1 小时(last_call_et > 3600),基本就是僵尸 -
segtype = 'LOAD'表示是索引创建或直接路径插入;'SORT'是排序或哈希连接,前者释放更慢
KILL SESSION 后卡在 “KILLED” 状态怎么办
执行 ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE 后,v$session.status 变成 'KILLED' 但 v$sort_usage 不清空,说明会话没真正退出,临时段还锁着。这不是网络断开就能自动清理的:
- 立刻查对应 OS 进程:
SELECT p.spid FROM v$session s JOIN v$process p ON s.paddr = p.addr WHERE s.sid = <sid>;</sid> - 在操作系统层用
kill -9 <spid></spid>干掉进程(Linux)或orakill <inst><spid></spid></inst>(Windows) - 杀完再等 30 秒,检查
v$sort_usage是否为空;若仍有残留,说明 SMON 卡住,需手动触发合并:ALTER TABLESPACE TEMP COALESCE;
DBA_TEMP_FREE_SPACE 显示 free_space ≈ 0,但文件没满
这说明不是磁盘空间真没了,而是碎片化严重:大量小块空闲区,但凑不出连续 128 块来满足一次排序请求。此时加文件或扩文件都无效:
- 先确认碎片:
SELECT tablespace_name, file_id, blocks, bytes/1024/1024 AS mb FROM dba_temp_free_space WHERE tablespace_name = 'TEMP';—— 若blocks列数值分散、最大值很小,就是碎片 -
COALESCE只对 ONLINE 表空间有效,且仅合并相邻空闲区,不释放磁盘空间 - 如果表空间含多个 tempfile,
COALESCE效果有限;此时重建 TEMP 更可靠(新建 → 切换默认 → 确认无使用 →DROP TABLESPACE TEMP INCLUDING CONTENTS AND DATAFILES)
别信 DBA_FREE_SPACE 查 TEMP 空间
DBA_FREE_SPACE 对临时表空间完全无效,它只返回永久表空间的空闲块信息。用它查 TEMP,结果全是误导:
- 正确视图是
DBA_TEMP_FREE_SPACE:SELECT tablespace_name, free_space/1024/1024 AS free_mb, allocated_space/1024/1024 AS alloc_mb FROM dba_temp_free_space; - 重点看
free_space字段(单位字节),不是百分比;接近 0 才代表真紧张 - 如果
free_space很小但v$sort_usage为空,问题不在会话,而在临时文件高位有未释放的 extent,RESIZE会报ORA-03297,只能重建
临时段不会自动收缩,哪怕所有会话都退出了,文件大小也纹丝不动;而“清理”的本质,是让 Oracle 能重用那些已标记为空闲的块——这依赖会话正常退出、SMON 正常工作、以及没有跨文件的碎片阻塞。任何跳过 v$sort_usage 直接删文件或强杀的操作,都可能留下不可见的段头损坏。


















