ora-01652 表示临时段分配失败,因需128个连续块但temp表空间无足够空闲区域;应查dba_temp_free_space而非dba_free_space,关注free_space字节值;扩容优先新增临时文件而非盲目扩展,同时定位高消耗sql并清理残留会话。

ORA-01652 不是磁盘空间告急的警报,而是临时段分配失败的明确拒绝——它说明当前操作需要 128 个连续块,但 TEMP 表空间里找不到这么一块空闲区域。
查真实空闲空间别看 DBA_FREE_SPACE
很多人一报错就跑 SELECT * FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'TEMP',看到“还有几百 MB”就松口气,结果重跑 SQL 还是报错。这是因为 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列(单位字节),不是百分比,也不是估算值 - 如果
FREE_SPACE接近 0,说明真没空间了;如果还有几百 MB 但依然报错,大概率是碎片化严重,而非总量不足
加文件比扩文件更稳,尤其不能开 AUTOEXTEND ON MAXSIZE UNLIMITED
临时文件自动扩展在高并发下容易引发 IO 尖峰甚至挂起,且 MAXSIZE UNLIMITED 在遇到笛卡尔积或全表扫描类 SQL 时,几秒内就能打爆磁盘。稳妥做法是新增一个独立文件:
- 新增命令:
ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/oradata/db/temp02.dbf' SIZE 4G AUTOEXTEND ON NEXT 128M MAXSIZE 16G; - 已有文件如需开启自动扩展,务必设上限:
ALTER DATABASE TEMPFILE '/u01/oradata/db/temp01.dbf' AUTOEXTEND ON NEXT 256M MAXSIZE 8G; - 切勿对生产环境主临时文件盲目
RESIZE,可能触发锁等待;新增是最安全的扩容路径
会话卡住不释放?先杀再 COALESCE
有时 DBA_TEMP_FREE_SPACE.FREE_SPACE 显示极小,但 DBA_TEMP_FILES 里文件大小没满,说明临时段被长期占用未释放——常见于长事务、PL/SQL 中未关闭的游标,或 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; - 找到长时间不动、MB_USED 很大的会话,直接杀:
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; - 再执行:
ALTER TABLESPACE TEMP COALESCE;—— 强制合并碎片,无需重启实例
根本解法不在扩容,而在定位肇事 SQL
临时表空间爆满,90% 是由少数几个 SQL 引起的,比如含 ORDER BY、GROUP BY、哈希连接或大表 CREATE INDEX 的语句。盲目加文件只是把问题往后推。
- 用
v$session和v$sort_usage关联找出高消耗会话和对应sql_hash_value - 通过
v$sql查原始 SQL:SELECT SQL_TEXT FROM v$sql WHERE HASH_VALUE = :hash_value; - 重点检查执行计划中是否出现
TEMP TABLE TRANSFORMATION、SORT-AGGREGATE或大量HASH JOIN,这些是 TEMP 消耗大户
临时段碎片、会话残留、SQL 写法三者常交织在一起,单独处理任一环节都可能治标不治本。最易被忽略的是:COALESCE 后若不杀掉残留会话,碎片很快又回来;而杀会话前不确认 SQL 是否可中断,可能引发业务异常。











