MAXSIZE 或磁碟滿,導致 ORA-01652: unable to extend temp segment-- 查詢正在使用暫存段的會話
SELECT s.username, s.sid, s.serial#, s.sql_id, s.machine, s.program,
su.tablespace, su.segtype, su.contents, su.blocks * 8192 / 1024 / 1024 AS used_mb
FROM v$session s, v$sort_usage su
WHERE s.saddr = su.session_addr
ORDER BY used_mb DESC;
-- 關聯 SQL 全文
SELECT sql_text FROM v$sql WHERE sql_id = '&sql_id';
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- 或標記待終止 (交易回滾中)
ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;
ALTER TABLESPACE temp COALESCE; -- 整理碎片,釋放未使用區塊
-- 若 COALESCE 無效,嘗試 RESIZE 暫存檔 (需檔案有足夠空閒空間)
ALTER DATABASE TEMPFILE '/path/temp01.dbf' RESIZE 2G;
當正常會話結束但暫存段未釋放 (如實例崩潰、強制關機、Bug),需用內部事件清理:
-- 1. 確認 TEMP 表空間 ts#
SELECT ts#, name FROM sys.ts$ WHERE name = 'TEMP';
-- 假設 ts# = 3
-- 2. 執行清理事件 (需 SYSDBA,建議離峰時段)
ALTER SESSION SET EVENTS 'immediate trace name DROP_SEGMENTS level 4';
-- level = ts# + 1 = 4
注意:此操作會掃描並刪除該表空間所有無主暫存段,可能產生大量 REDO/UNDO,執行期間短暫影響效能。
| 參數/設定 | 建議值/策略 | 說明 |
|---|---|---|
| 暫存檔自動擴展增量 | NEXT 640K (預設常為 64K) | 減少頻繁擴展的元資料爭用與碎片 |
| MAXSIZE | 設定合理上限 (如 50G/100G),避免佔滿磁碟 | 啟用 AUTOEXTEND ON MAXSIZE 50G |
| PGA_AGGREGATE_TARGET / MEMORY_TARGET | 依實體記憶體設定 (如 8G/16G) | 讓排序/雜湊盡量在記憶體完成,減少 TEMP 寫入 |
| WORKAREA_SIZE_POLICY | AUTO (預設) | 自動管理工作區大小 |
| _smm_max_size (隱含參數) | 單一操作最大工作區 (建議 100M~200M) | 防止單一巨大排序佔滿 TEMP,需諮詢 Oracle Support |