正常情況下,排序、雜湊連線、建立索引等操作使用完 TEMP 表空間後,SMON 會自動釋放暫存段。但實務常遇到:暫存段未釋放、TEMP 近 100% 使用、甚至重啟資料庫仍無法釋放。主因通常為:大型排序超出 TEMP 空間、長時間交易持有暫存段、SMON 清理延遲、或暫存段標記異常 (ORA-600/ORA-7445 相關)。
資料庫重啟時 SMON 會完整掃描並釋放所有暫存段。缺點:生產環境通常不允許隨意停機。
ALTER TABLESPACE temp INCREASE 1;
ALTER TABLESPACE temp INCREASE 0;
透過微調表空間儲存參數,促使 SMON 重新檢視暫存段並嘗試釋放。無需停機,成功率中等。
SELECT s.username, s.sid, s.serial#, s.sql_address, s.machine, s.program,
u.tablespace, u.segtype, u.contents
FROM v$session s, v$sort_usage u
WHERE s.saddr = u.session_addr;
ALTER SYSTEM KILL SESSION 'sid,serial#';
注意:殺 Session 會回滾未提交交易,務必確認業務影響,必要時通知應用端。
ALTER TABLESPACE TEMP COALESCE;
合併相鄰空閒區塊,釋放連續空間供後續使用。
SELECT ts#, name FROM sys.ts$;
-- 假設 TEMP 的 TS# = 3
ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME DROP_SEGMENTS LEVEL 4';
-- LEVEL = TS# + 1 (即 3+1=4)
原理:觸發內部追蹤事件,直接要求 SMON 清理指定 TS# 的暫存段,效果即時且不影響其他 Session。
SELECT UPPER(f.tablespace_name) "表空間名",
d.tot_grootte_mb "表空間大小(M)",
d.tot_grootte_mb - f.total_bytes "已使用(M)",
TO_CHAR(ROUND((d.tot_grootte_mb - f.total_bytes)/d.tot_grootte_mb*100,2),'990.99') "使用%",
f.total_bytes "空閒(M)",
f.max_bytes "最大區塊(M)"
FROM (
SELECT tablespace_name,
ROUND(SUM(bytes)/1024/1024,2) total_bytes,
ROUND(MAX(bytes)/1024/1024,2) max_bytes
FROM sys.dba_free_space
GROUP BY tablespace_name
) f,
(
SELECT dd.tablespace_name,
ROUND(SUM(dd.bytes)/1024/1024,2) tot_grootte_mb
FROM sys.dba_data_files dd
GROUP BY dd.tablespace_name
) d
WHERE d.tablespace_name = f.tablespace_name
ORDER BY 4 DESC;
V$TRANSACTION + V$SESSION_LONGOPS 找出長跑 SQL,優化或拆分。PGA_AGGREGATE_TARGET:適度增大 PGA 可減少落盤排序,降低 TEMP 壓力。