V$SORT_SEGMENT显示已分配未归还的排序段extents总量,非实时占用;V$TEMPSEG_USAGE定位当前活跃会话的临时段使用;ORA-1652需结合v$sql与历史AWR分析源头SQL。

查 V$SORT_SEGMENT 看当前排序段分配总量
临时表空间的物理分配单位是排序段(sort segment),每个实例启动后首次执行磁盘排序时自动创建一个,关库才释放。它不随会话结束而销毁,所以 V$SORT_SEGMENT 显示的是“已分配但尚未归还给操作系统的 extents 总量”,不是实时占用。
执行以下语句可看到当前排序段中已用、空闲和总计 extents 数:
SELECT tablespace_name, used_extents, free_extents, total_extents FROM V$SORT_SEGMENT;
注意:used_extents 并非当前活跃排序量,而是自实例启动以来累计分配过、且尚未被 Oracle 内部回收的 extents —— 即使所有会话都空闲,这个值也可能不为 0。
- 若
free_extents持续接近 0,说明排序段长期未收缩,可能需重启实例或检查是否有长事务/异常会话持续占着段 -
total_extents=used_extents+free_extents,但该总数不会自动缩减,除非重建临时表空间
用 V$TEMPSEG_USAGE 查谁在用、用了多少块
V$TEMPSEG_USAGE 是唯一能定位“此刻哪个会话正在消耗临时空间”的视图。它反映的是当前活跃的临时段使用情况,每行对应一个会话的一次排序/哈希操作。
常用查询:
SELECT s.sid, s.serial#, s.username, u.tablespace, u.segtype, u.blocks * 8192 / 1024 / 1024 AS mb_used FROM v$tempseg_usage u JOIN v$session s ON u.session_addr = s.saddr WHERE u.contents = 'TEMPORARY';
关键点:
-
blocks是以 Oracle 数据块为单位,乘以db_block_size(通常 8192)才得字节数;直接看blocks容易误判实际用量 -
segtype值为DATA表示临时表,INDEX表示临时索引,LOB_DATA或LOB_INDEX表示临时 LOB —— 不同类型对空间压力模式不同 - 该视图只显示“已分配且尚未释放”的段;一旦排序完成、结果返回客户端,对应行就从视图中消失
ORA-1652 报错时怎么快速定位源头 SQL
当应用报 ORA-1652: unable to extend temp segment,说明临时空间已无法满足新分配请求。此时 V$TEMPSEG_USAGE 可能已清空(因失败会话已断开),需回溯最近的活跃排序操作。
推荐组合查法:
SELECT sql_id, sql_text, elapsed_time, disk_reads FROM v$sql WHERE sql_id IN ( SELECT sql_id FROM v$tempseg_usage WHERE session_num > 0 ) ORDER BY disk_reads DESC;
更稳妥的做法是提前开启 AWR 快照并配置基线,因为:
-
V$SQL中的disk_reads包含所有磁盘 I/O,不单指临时表空间读写 - 真正导致爆
TEMP的 SQL 往往是ORDER BY+ 大结果集、GROUP BY高基数列、或未走索引的UNION ALL合并 - 临时段分配发生在执行阶段,但
V$SESSION_LONGOPS对排序类操作支持有限,不能依赖它抓实时卡点
为什么监控不到“刚释放”的空间?
Oracle 临时表空间的释放是懒惰的(lazy):排序结束后,临时段所占 extents 并不立即归还给文件系统,而是标记为“可重用”,保留在 V$SORT_SEGMENT 的 free_extents 中供后续排序复用。这避免了频繁分配/释放带来的 latch 争用,但也导致监控数据滞后。
这意味着:
- 即使所有会话都空闲,
V$SORT_SEGMENT.free_extents可能仍远小于total_extents - 临时文件(
dba_temp_files)的物理大小不会自动缩小,ALTER DATABASE TEMPFILE ... RESIZE必须手动触发,且只能缩到当前实际使用的最大水位线下 - 想真正“清空”历史膨胀痕迹,必须重建临时表空间(换名 → 切默认 → 删除旧 → 重建 → 切回),否则
free_extents永远不会归零
最常被忽略的一点:监控脚本如果只查 V$TEMPSEG_USAGE 就认为“没人在用 TEMP”,却没结合 V$SORT_SEGMENT 看底层段是否已严重碎片化或长期驻留,容易误判容量余量。











