Oracle 19c TEMP表空间不自动收缩是设计行为,临时文件扩展后高位extent不会释放;查真实占用需联合v$sort_usage和dba_temp_files,唯一可靠解法是重建TEMP表空间并严格按顺序执行。

临时表空间不会自动收缩,哪怕所有会话都结束,文件大小仍保持峰值状态——这是磁盘被占满的根源。
查清谁在用、用了多少 v$sort_usage 和 dba_temp_files
别只看“TEMP 表空间使用率 95%”,得定位真实消耗源。两个视图必须一起看:v$sort_usage 显示当前活跃会话的排序段占用,dba_temp_files 显示物理文件实际尺寸。
-
v$sort_usage返回空?说明没活跃排序,但文件可能仍卡在历史最大值(Oracle 不自动 shrink tempfile) -
dba_temp_files中bytes远大于maxbytes?说明启用了 autoextend 且已撑到上限,但没设MAXSIZE或设得过大 - 执行
SELECT tablespace_name, file_name, bytes/1024/1024 AS mb FROM dba_temp_files,确认单个 tempfile 是否已达 32GB 限制(老版本 Oracle 的硬上限)
临时文件不缩容,coalesce 无效,得用 resize 或重建
ALTER TABLESPACE TEMP COALESCE 对临时表空间基本没用——它只合并相邻空闲区,而 temp 文件的“空闲”是逻辑概念,物理文件尺寸不会变。真正能减小磁盘占用的操作只有两个:
- 用
ALTER DATABASE TEMPFILE '/path/to/temp01.dbf' RESIZE 2048M手动压回合理值(前提是当前实际使用远低于该值,否则报 ORA-03297) - 新建临时表空间 + 切换默认 + 删除旧文件:先
CREATE TEMPORARY TABLESPACE temp_new ...,再ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_new,最后DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES - 注意:
RESIZE不能小于当前已使用的最大块(v$temp_extent_pool.bytes_cached),得先 kill 掉占用者或等其释放
避免下次再爆:关掉无节制 autoextend 或设严 MAXSIZE
很多 DBA 一见告警就 AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED,结果几个月后 tempfile 长到 100GB 占满 LVM。这不是扩容,是埋雷。
- 生产环境禁用
UNLIMITED,强制设MAXSIZE 10G或20G(根据历史峰值 + 20% 冗余) - 如果业务确实需要更大空间,优先加新 tempfile:
ALTER TABLESPACE TEMP ADD TEMPFILE '/u02/temp02.dbf' SIZE 5G,而不是把单个文件越拉越大 - 监控脚本里别只查
free_percent,要加一条:SELECT file_name, bytes/1024/1024, autoextensible, maxbytes/1024/1024 FROM dba_temp_files,盯住maxbytes是否接近磁盘剩余空间
ORA-01652 报错时,先别急着扩,先看是不是 SQL 本身能优化
报 ORA-01652: unable to extend temp segment 时,80% 情况下不是空间不够,而是某条 SQL 排序量异常大——比如没走索引的 ORDER BY、全表扫描后 DISTINCT、或未绑定变量的即席查询。
- 查
V$SQL找sorts_disk > 1000且executions > 1的语句:SELECT sql_id, sql_text, sorts_disk, disk_reads FROM v$sql WHERE sorts_disk > 1000 ORDER BY sorts_disk DESC - 检查执行计划是否走了
SORT-AGGREGATE或SORT-JOIN,配合DBMS_XPLAN.DISPLAY_CURSOR('sql_id')确认 - 临时缓解可调高会话级
sort_area_size(不推荐长期用),但根本解法是加索引、重写 SQL、或加物化视图预聚合
临时表空间的“大”往往不是配置问题,而是某条 SQL 在反复制造碎片;文件“不缩”也不是 bug,是 Oracle 的设计选择——你得主动干预,而不是等它自己收拾干净。


















