Oracle 19c临时表空间暴涨典型原因包括:1. PGA_AGGREGATE_TARGET过小导致排序溢出;2. ORDER BY/GROUP BY/DISTINCT等操作处理超大结果集;3. 物化视图快速刷新或并行查询大量占用临时段;4. 应用连接未关闭或事务未提交致临时段无法释放;5. 全局临时表或哈希连接持续写入。

临时表空间暴涨的典型原因有哪些
Oracle 19c 临时表空间(TEMP)持续增长,通常不是因为“数据存进去了”,而是因为会话正在使用大量排序、哈希连接、物化视图刷新、并行 DML 或全局临时表(GLOBAL TEMPORARY TABLE)写入 —— 这些操作都依赖 TEMP 表空间分配的临时段(temp segment),且段不会在语句结束就立即释放,而要等会话断开或显式清理。
常见诱因包括:
- 长时间未关闭的应用连接(尤其 JDBC 默认不自动 close
Statement或ResultSet),导致其占用的临时段无法回收 -
ORDER BY、GROUP BY、DISTINCT等操作处理超大结果集,且 PGA_AGGREGATE_TARGET 设置过小,迫使 Oracle 把中间结果溢出到TEMP - 物化视图快速刷新(
DBMS_MVIEW.REFRESH)或在线重定义(DBMS_REDEFINITION)过程中大量使用临时空间 - 并行查询(
/*+ PARALLEL */)开启后,每个并行进程都独立申请临时段,总用量呈倍数上升
如何确认是谁在占用临时空间
别急着删文件或重启实例,先定位活跃的“空间大户”。核心是查 V$SORT_USAGE 和 V$SESSION 关联视图:
SELECT s.sid, s.serial#, s.username, s.program, u.tablespace, u.blocks * 8 / 1024 AS mb_used FROM v$sort_usage u JOIN v$session s ON u.session_addr = s.saddr ORDER BY u.blocks DESC;
注意:blocks 是 Oracle 数据块数,乘以 db_block_size(通常是 8192)得字节数;上面示例按 8KB 块算成 MB。
关键点:
- 如果
username是NULL,说明是后台进程(如 SMON、PMON)或内部操作,需结合program和sql_id进一步查V$SQL - 若同一
sid长期存在且mb_used持续上涨,大概率是应用未正确关闭游标或事务未提交/回滚 -
V$TEMPSEG_USAGE在 19c 中已弃用,必须用V$SORT_USAGE
临时表空间能直接 shrink 吗
不能对临时表空间执行 ALTER TABLESPACE ... SHRINK SPACE —— 这个命令只适用于永久表空间。临时表空间的“释放”逻辑完全不同:
- 临时文件(
tempfile)本身不支持 shrink,但可以RESIZE到更小值,前提是文件末尾没有活跃的区(extent) - 更安全的做法是:先清空所有会话级临时段(
ALTER SESSION SET CURRENT_SCHEMA = ...不起作用,必须 kill 会话或等其退出),再执行ALTER DATABASE TEMPFILE '<path>' RESIZE <size> - 如果临时文件已损坏或无法 resize,可新建临时表空间,切换默认,再删除旧的:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE <new_tbs>,之后DROP TABLESPACE <old_tbs> INCLUDING CONTENTS AND DATAFILES
特别提醒:DROP TABLESPACE ... INCLUDING CONTENTS AND DATAFILES 会直接删操作系统文件,务必确认无任何会话还在用该表空间(查 V$TEMP_SPACE_HEADER 的 USED_BLOCKS 应为 0)。
怎么预防临时表空间反复暴涨
治标靠清理,治本靠配置与规范:
- 调高
PGA_AGGREGATE_TARGET(比如从 1G 调到 4G),减少内存不足导致的磁盘溢出;同时监控V$PGASTAT的bytes_processed和extra_bytes_read/written,后者高说明频繁 IO - 应用层避免无限制
SELECT *+ORDER BY,改用分页(OFFSET ... FETCH)或加索引覆盖排序字段 - 定期检查长事务(
V$TRANSACTION.START_TIME超几小时的),配合V$SESSION找出源头 - 禁用非必要并行:在初始化参数中设
PARALLEL_DEGREE_POLICY = MANUAL,或对特定 SQL 加NO_PARALLELhint
最易被忽略的一点:Oracle 19c 默认启用 AUTO_TEMPORARY_TABLESPACE,如果 DBA 创建了多个临时表空间但没指定默认,Oracle 可能轮询使用,导致监控误判 —— 务必用 SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME = 'DEFAULT_TEMP_TABLESPACE' 确认当前默认值。


















