查TEMP表空间真实空闲空间应使用DBA_TEMP_FREE_SPACE视图,其中FREE_SPACE列(单位字节)反映实际可用空间,而非DBA_FREE_SPACE(仅适用于永久表空间);若FREE_SPACE接近0即真耗尽,需通过新增临时文件、杀占用会话并COALESCE释放碎片,同时优化SQL减少排序/哈希溢出。
查 TEMP 表空间真实空闲空间,别信 DBA_FREE_SPACE
ora-01652 报错时,很多人立刻跑 select * from dba_free_space 查 temp,结果看到“还有几百 mb”,就以为空间够——这是错的。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,说明真没空间了。
加文件比扩文件更安全,尤其对在线业务
临时文件设成 AUTOEXTEND ON 看似省事,但在高并发场景下容易引发 IO 争抢甚至挂起。更稳妥的做法是新增一个文件,而不是扩大已有文件:
• 新增文件命令:ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/oradata/db/temp02.dbf' SIZE 4G AUTOEXTEND ON NEXT 128M MAXSIZE 16G;
• 避免 MAXSIZE UNLIMITED:万一 SQL 出现笛卡尔积或全表扫描,几秒内可能打爆磁盘
• 已有文件开启自动扩展(慎用):ALTER DATABASE TEMPFILE '/u01/oradata/db/temp01.dbf' AUTOEXTEND ON NEXT 256M MAXSIZE 8G;
临时段卡住不释放?先杀会话再 COALESCE
有时 DBA_TEMP_FREE_SPACE.FREE_SPACE 显示极小,但 DBA_TEMP_FILES 里文件大小没满,说明临时段被长期占用未释放——这不是磁盘问题,而是会话残留或 SMON 卡住。
• 查谁在吃空间:SELECT s.sid, s.username, u.tablespace, u.segtype, u.blocks*8/1024 AS mb_used FROM v$sort_usage u, v$session s WHERE u.session_addr = s.saddr ORDER BY u.blocks DESC;
• 找到长时间不动且占用大的会话,直接杀:ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
• 再执行:ALTER TABLESPACE TEMP COALESCE;,强制合并碎片,无需重启
根本解法不是加空间,而是让 SQL 少用 TEMP
临时表空间爆满,90% 是由少数几个 SQL 引起的,比如含 ORDER BY、GROUP BY、哈希连接或大表 CREATE INDEX 的语句。盲目扩容只是掩盖问题:
• 先用 v$session + v$sort_usage 定位肇事 SQL
• 检查执行计划,看是否有大量 SORT 或 HASH JOIN 操作
• 调整内存参数(Oracle 11g 中仍有效):PGA_AGGREGATE_TARGET 设大些,减少磁盘排序概率
• 对大表关联,考虑加合适索引或改写为嵌套循环(NL)避免哈希溢出
临时段的释放依赖于会话正常结束或 SMON 清理,但 SMON 可能卡住;COALESCE 和杀会话是最快见效的手段,而真正防复发,得回到 SQL 本身——那些突然报错的“老查询”,往往就是数据量变大后暴露出来的性能债。











