DB_BLOCK_SIZE 決定 (通常 8K)。同一表空間內多個段的 Extent 交錯分布,隨著建表/刪表/截斷,原本連續的自由空間被切碎。雖 DBA_FREE_SPACE 總和顯示數百 MB,但找不到足夠大的連續 Extent 滿足 NEXT 擴展,導致 ORA-01653 甚至 ORA-01654。
Bhaskar Himatsingka & Juan Loaiza 提出,後被 Locally Managed Tablespace (LMT) 內建實現。核心規則:
| # | 規則 | 實作方式 |
|---|---|---|
| 1 | 同表空間內所有段使用統一 Extent 大小 | CREATE TABLESPACE ... EXTENT MANAGEMENT LOCAL UNIFORM SIZE 10M (或 AUTOALLOCATE) |
| 2 | 段層級不指定 INITIAL/NEXT/PCTINCREASE | 建表時省略 storage 子句,完全由表空間預設值繼承 |
| 3 | Extent 大小依段大小分級 (三級制) | 小表 64K/1M、中表 10M、大表 100M~1G;段 Extent 數控制在 1024 內 |
| 4 | 優先使用 LMT | 8i 起預設;字典管理表空間 (DMT) 已棄用 |
| 5 | 監控持續增長段的 Extent 計數 | 超 1024 考慮移至大 Extent 表空間或分區 |
| 6 | 超大段 (4G~128G) 獨立表空間 + 分區 | 提升管理彈性與平行查詢效能 |
| 7 | 暫存段用 TEMPORARY 表空間 | CREATE TEMPORARY TABLESPACE temp ... |
| 8 | 回滾段 (Undo) 視負載決定是否用 OPTIMAL | 現代建議改用 Undo Tablespace 自動管理 |
| 9 | 嚴禁用戶物件放入 SYSTEM | 避免字典爭用、碎片汙染 |
| 10 | 資料檔大小 = Extent 整數倍 + 1 Block (LMT +64K) | 避免檔案尾部殘留不可用空間 |
| 11 | 統一 Extent 表空間勿手工整理 | 重組反而可能降低效能;非統一才用 Exp/Imp |
| 12 | 線上移動表/重建索引 | ALTER TABLE ... MOVE TABLESPACE ..., ALTER INDEX ... REBUILD |
舊文獻建議 EXPORT COMPRESS=Y 將所有資料壓縮進單一 Extent。實測:
CREATE TABLE t (
id NUMBER,
data VARCHAR2(2000)
) PCTFREE 20 PCTUSED 40 TABLESPACE users;
(100 - PCTFREE)% 滿度後,不再接受新 INSERT,留給 UPDATE 原地擴展。PCTFREE 5~10PCTFREE 15~25PCTFREE 10 (預設) 或 20 較保險PCTUSED% 才重新列入 FREELIST 供 INSERT 使用。PCTFREE 20 / PCTUSED 40 (預留 20%,跌至 40% 才重用)。LMT + SEGMENT SPACE MANAGEMENT AUTO (10g 預設) 使用位圖追蹤區塊可用空間,完全忽略 PCTFREE/PCTUSED,自動最佳化插入位置,消除 Row Migration 風險,**強烈建議所有新建表空間啟用 ASSM**。
-- 1. 表空間使用率與最大連續自由空間
SELECT tablespace_name,
ROUND(100 * (1 - free_mb / total_mb), 2) AS pct_used,
max_free_mb
FROM (
SELECT tablespace_name,
SUM(bytes)/1024/1024 AS total_mb
FROM dba_data_files GROUP BY tablespace_name
) a
JOIN (
SELECT tablespace_name,
SUM(bytes)/1024/1024 AS free_mb,
MAX(bytes)/1024/1024 AS max_free_mb
FROM dba_free_space GROUP BY tablespace_name
) b USING (tablespace_name)
ORDER BY pct_used DESC;
-- 2. 段 Extent 計數 TOP 20 (關注 > 1024)
SELECT owner, segment_name, segment_type, extents
FROM dba_segments
WHERE extents > 500
ORDER BY extents DESC
FETCH FIRST 20 ROWS ONLY;
-- 3. Row Migration 統計 (ANALYZE 後查詢)
SELECT chain_cnt, avg_row_len, blocks
FROM dba_tables
WHERE owner = 'APP' AND chain_cnt > 0
ORDER BY chain_cnt DESC;
max_free_mb、段 Extent 數、Row Migration,提前擴容或移動。ALTER TABLE ... MOVE PARTITION 線上維護。