ora-01652错误本质是临时表空间无法分配连续128个数据块,主因包括真实空间不足、碎片化严重或会话长期占用未释放;需用dba_temp_free_space查真实空闲,禁用dba_free_space,优先新增tempfile扩容,并结合sql优化与pga调优治本。
ora-01652 报错不是“空间绝对不够”,而是数据库在临时表空间里找不到连续的 128 个数据块——这可能是真没空间,也可能是碎片太多、或某个会话霸占着不放。直接加文件能救急,但不查根因,下次照样爆。
查真实空闲空间别用 DBA_FREE_SPACE
临时表空间不走 DBA_FREE_SPACE,查它永远返回空或误导结果。你看到“还有 500MB”,其实根本没法用。
- 查真实可用空间:
SELECT FREE_SPACE/1024/1024 AS mb_free FROM DBA_TEMP_FREE_SPACE WHERE TABLESPACE_NAME = 'TEMP' - 查每个临时文件是否可扩展:
SELECT FILE_NAME, AUTOEXTENSIBLE, MAXBYTES/1024/1024 AS max_mb FROM DBA_TEMP_FILES - 如果某文件
AUTOEXTENSIBLE = 'NO',哪怕FREE_SPACE显示有 800MB,只要下一个排序需要连续 1MB(128×8KB),就立刻报错
加临时文件比扩现有文件更安全
对在线业务影响最小的方式是新增 TEMPFILE,而不是 RESIZE 或 AUTOEXTEND ON 已有文件——后者可能触发 IO 尖峰甚至挂起。
- 新增文件(推荐):
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 - 绝对别写
MAXSIZE UNLIMITED:一个笛卡尔积 SQL 可能在 3 秒内打爆整块磁盘
临时段卡住不释放?先杀会话再 COALESCE
有时 DBA_TEMP_FREE_SPACE.FREE_SPACE 极低,但 DBA_TEMP_FILES 里文件大小又没满——说明临时段被长期占用,不是磁盘问题,是会话残留或 SMON 卡住。
- 查谁在吃空间:
SELECT s.sid, s.username, 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
ORA-01652 往往是症状,不是病根。看执行计划里有没有 HASH JOIN、SORT ORDER BY、HASH UNIQUE,尤其注意 TempSpc 列——如果显示几百 MB 甚至几 GB,说明这个 SQL 本就不该这么跑。
- 强制走索引避免排序:
/*+ INDEX(t idx_col) */ - 拆分大关联:把 5 表 JOIN 拆成两步,中间结果物化到 GTT
- 检查是否误用了
MERGE JOIN CARTESIAN(常见于缺驱动条件的远程表查询) - 确认 PGA 设置是否合理:
SHOW PARAMETER pga_aggregate_target;太小会频繁落盘,太大则挤占 SGA
最常被忽略的一点:临时段的“空闲”是逻辑空闲,不是物理释放。即使 SQL 执行完,只要会话没断,那段空间就一直被标记为“可用但未归还”。所以监控不能只看 FREE_SPACE 数值,得结合活跃会话和历史峰值一起看。











