身為管理軟體開發者,我們日夜與 SQL Server 打交道,卻鮮少從架構視角審視其內核設計。本文以架構師視角,追蹤一條 SQL 陳述式從客戶端發送、網路傳輸、協議解碼、關係引擎解析優化、執行計畫生成、查詢執行、儲存引擎存取、緩衝區管理、鎖/交易/日誌協調、惰性寫入、檢查點恢復的完整生命週期,揭示 SQL Server 內核模組化、分層、高併發、高可靠的設計精髓。
歷史脈絡:從 Sybase 到自主重寫
- 1988 Sybase SQL Server 1.0 (OS/2) → Microsoft 聯合銷售。
- 1994 Microsoft 與 Sybase 分道揚鑣,Microsoft 取得原始碼授權獨立演進。
- 1995 SQL Server 6.0:Microsoft 首個自主版本。
- 1999 SQL Server 7.0:內核完全重寫,引入列級鎖、統一配置單元、新儲存格式、自動化管理,奠定現代架構基石。
- 2000/2005/2008... 持續演進:64位、CLR 整合、Always On、Columnstore、In-Memory OLTP、ADR、智能查詢處理。
完整請求處理管線 (Pipeline)
第 0 層:網路協議與 TDS (Tabular Data Stream)
- 客戶端庫 (ODBC/OLE DB/ADO.NET/SNI) 將命令編碼為 TDS 封包:Token-based 協議,確保請求/回應配對、跨平台互通。
- 傳輸層:Shared Memory / Named Pipes / TCP/IP / VIA (已棄用)。
- 伺服器端 Open Data Services (ODS):
— 監聽 Endpoint、管理連線池 (Pooling/建立/銷毀/閒置清理)
— 讀緩衝區接收 TDS → 解碼 → 交給關係引擎
— 寫緩衝區批次發送結果集/訊息/狀態 (Token 流控)
設計精妙:非同步 I/O + 緩衝區管線,吸收網路抖動,解耦接收與處理。
第 1 層:關係引擎 — 解析、優化、計畫生成
- 命令剖析器:語法檢查、規範化、語法樹構建。失敗即報錯 (語法錯誤/物件不存在)。
- 命令優化器:
— 關係代數等價轉換 (Join Reorder、Predicate Pushdown、Aggregation Pullup...)
— 成本模型估算:CPU、I/O、記憶體、行數 (統計資訊為核心輸入)
— 搜尋策略:啟發式/動態規劃,在極短時間內找到「足夠好」的計畫 (非窮舉)。
— 輸出:最佳執行計畫 (邏輯運算子樹)。
- SQL 管理器:將邏輯計畫轉為物理執行計畫,處理權限檢查、約束、觸發器、預設值、計算欄位等執行時綁定邏輯。
第 2 層:查詢執行器 — 協調執行
- 迭代器模型:每個物理運算子 (Scan/Seek/Join/Aggregate/Sort/Spool...) 實作
Open/GetRow/Close 介面,以資料流水線方式逐行流動 (非物化中間結果,除非 Spool/Sort/Hash Join Build)。
- 協調子系統:
— 交易管理器 (顯性/隱性交易、隔離級別、鎖耦合)
— 鎖管理器 (S/X/U/IS/IX/SIU... 列/頁/表/資料庫/應用鎖、死鎖偵測)
— 索引管理器 (B+ Tree 導航、分頁分裂/合併、填充因子)
— 頁面/緩衝管理器 (見下層)
— CPU 排程器 (SOS Scheduler、Worker、Quantum、可搶佔/非搶佔等待)
第 3 層:儲存引擎 — 物理存取與持久化
- 存取方法管理器:依執行計畫決定掃描/搜尋路徑,發起頁面/索引頁請求。
- 緩衝區管理器 (Buffer Pool Manager) —— 核心樞紐:
— 頁面快取 (8KB 頁、統一配置單元、資料/索引/TEXT/圖文混存)
— 預讀:依存取模式非同步預載後續頁面 (大型掃描關鍵)
— LRU-K 替換策略:平衡熱頁保留與冷頁淘汰
— 頁面錯誤處理:缺頁 → 非同步 I/O 發起 → Worker 等待 (PAGEIOLATCH) → 完成喚醒
— 檢查點:定期刷髒頁至資料檔,推進復原 LSN
- 列管理器 / 索引管理器:列儲存格式 (固定/變長/稀疏/壓縮/Columnstore)、B+ Tree 維護、統計資訊採樣。
- 交易管理器 + 鎖管理器:ACID 保證核心。
— 寫前日誌 (WAL):日誌記錄必須先於資料頁持久化
— 鎖相容性矩陣、鎖升級、死鎖犧牲者選擇 (成本最低)
- 日誌管理器:
— 循環 VLF 寫入、強制刷新 (Flush to LSN)
— 檢查點、備份/還原、Always On/複寫/鏡像 讀取日誌
— 崩潰恢復:Redo (前滾已提交) + Undo (回滾未提交)
- 惰性寫入器:背景執行緒,批次刷髒頁,平衡記憶體壓力與 I/O 暴發。
關鍵設計模式總結
| 模式 | 體現位置 | 效益 |
| 管線與 Token 流控 | TDS / ODS 讀寫緩衝區 | 非阻塞、背壓、請求回應配對 |
| 分層解耦 | 關係引擎 / 查詢執行器 / 儲存引擎 | 單一職責、可獨立演進、單元測試 |
| 迭代器/資料流水線 | 查詢執行器物理運算子 | 記憶體效率、並行度、早期終止 (TOP) |
| WAL + 檢查點 | 日誌管理器 / 緩衝區管理器 | ACID、快速恢復、最小化資料遺失 |
| 自適應資源管理 | 緩衝區 LRU-K、鎖升級、SOS 排程器 | 無需人工調校即可應對多樣負載 |
給架構師的啟示
- 通用介面屏蔽複雜度:ODBC/ADO.NET 屏蔽 TDS,正如 Windows API 屏蔽內核、DirectX 屏蔽硬體。
- 緩衝區即杠桿:讀/寫緩衝區、Buffer Pool、版本存放區、日誌緩衝——所有高效能系統的核心都是「用空間換時間、用非同步換吞吐」。
- 統計驅動決策:優化器依賴統計資訊,架構系統同樣需要「觀測數據」驅動自動調優 (Automatic Tuning)。
- 失敗領域隔離:頁面錯誤、死鎖、日誌滿、TempDB 壓力——每種失敗都有局部化處理路徑,不波及整體可用性。
SQL Server 內核是教科書級的資料庫系統工程實踐。研讀其架構,不僅能寫出更高效的 SQL,更能啟發我們設計自有管理平台的核心骨架。