前言:I/O 子系統的關鍵地位
Oracle I/O 子系統是資料庫核心組件,許多系統瓶頸源於磁碟 I/O,CPU 大量時間消耗於等待 I/O 完成。設計時需平衡三大因素:
- 儲存容量:最小磁碟容量規劃
- 可用性:如 24x7 不間斷服務
- 效能:I/O 吞吐量與系統回應時間
基本 I/O 設計:條帶化
使用作業系統 (LVM) 或硬體條帶化分散 I/O。條帶化兩大要素:
- Stripe Depth (條帶深度/單元大小):單一條帶大小
- Stripe Width (條帶寬度) = Stripe Depth × 條帶組磁碟數
Oracle 建議 Stripe Depth 介於 256KB~1MB。最佳值取決於:I/O 請求大小、並發 I/O 數量、物理條帶邊界與區塊大小邊界對齊、系統可管理性。
I/O 請求大小相關參數
DB_BLOCK_SIZE:單塊 I/O 大小,也用於多塊 I/O 計算
- OS Block Size
- Maximum OS I/O Size
DB_FILE_MULTIBLOCK_READ_COUNT:與 DB_BLOCK_SIZE 乘積決定全表掃描最大 I/O(預設 8)
SORT_AREA_SIZE、HASH_AREA_SIZE
並發度與 Stripe 策略
- 低並發系統:確保同一磁碟不發生重複單一 I/O。平均 I/O 請求大小應 < Stripe Width × Stripe Depth,避免單磁碟二次 I/O。
- 高並發系統 (OLTP):採用粗顆粒條帶,Stripe Depth > 單一 I/O 大小,通常設計為 n × DB_BLOCK_SIZE (n>1)。磁碟以佇列方式並行處理多 I/O,低成本應對高並發。但若並發不足易產生磁碟熱點。
- DSS 系統:同樣受益於粗顆粒,但 Stripe Depth 較小,n < DB_FILE_MULTIBLOCK_READ_COUNT。
- 細顆粒設計:可獲得最佳回應時間。
物理條帶邊界與區塊大小邊界對齊
若物理條帶顆粒與區塊大小一致,單一 I/O 可能分散至兩物理 I/O,非 OLTP 最優。建議 Stripe 為 2×Block 大小。具體建議:
- 隨機讀寫:2×Block Size
- 循序讀取:2×DB_FILE_MULTIBLOCK_READ_COUNT×DB_BLOCK_SIZE
可管理性
LVM 便於配置所有磁碟條帶,單卷通常提供良好效能,但需搭配 RAID (如 RAID 1) 確保可用性;單卷故障意味著所有卷遺失。
擴展性考量
資料增長需易於擴展儲存空間。
手工分布 I/O(無條帶化環境)
- 檢查磁碟與檔案大小,估算儲存需求
- 預估各檔案 I/O,區分高/低 I/O 檔案,分布至不同磁碟組
迷思破解:將 Index 與 Data 分離並不恰當。事務中先訪問索引再訪問表,屬順序操作,同磁碟無競爭。
何時需分割檔案
當 I/O 需求無法滿足時。熱點常發生於 Table、Index、Temp Tablespace,多因 SQL 不佳,優先 SQL Tuning。其他建議:
- Redo Log 高 I/O:獨立磁碟或分布多磁碟,提升可用性;條帶化儲存,避免 RAID 5。
- Archived Redo Log 歸檔慢:檢查歸檔進程與 LGWR 競爭。
最佳實踐總結
- 條帶化所有磁碟
- 移動歸檔檔案至不同磁碟
- 移動線上 Redo Log 至獨立磁碟
- 使用 Oracle Managed Files (OMF) 獲益更多
資料區塊大小選擇指南
- 8KB 適合大多數系統
- OLTP 可用更小區塊;DSS 可用更大區塊
讀取場景
- 行小、隨機存取 → 較小區塊
- 行小、循序存取 → 較大區塊
- 行小、複雜存取 → 較大區塊
- 行大、含 LOB → 較大區塊
寫入場景
- 高並發 OLTP 用大區塊:須謹慎設定
INITRANS、MAXTRANS、FREELISTS(若用自動段空間管理可忽略 FREELISTS)
- 不確定時用 8KB;大量 LOB 可 >8KB
小結
小區塊減少鎖競爭,適合隨機存取,但中繼資料開銷大、不適合大行、易產生行鏈。大區塊存儲更多資料、減少管理開銷、適合循序存取與 LOB,但空間浪費大、不適合 OLTP 索引(易產生葉子塊競爭)。