在 SQL Server 的儲存引擎架構中,閂鎖 扮演著至關重要的角色。它們是輕量級的同步物件,專門用於保護記憶體內部資料結構(如資料頁、系統頁面)免受多執行緒並發存取時的競爭衝突。本文將系統性地介紹閂鎖的必要性、核心模式、三大分類,以及實戰中的監控與疑難排解技巧。
自 SQL Server 7.0 引入行級鎖以來,閂鎖便成為不可或缺的機制。若無閂鎖保護,多執行緒在記憶體中並發修改同一資料結構時,極易發生遺失更新 問題。閂鎖本質上類似於多執行緒程式設計中的臨界區,但更進一步:它允許多執行緒並發讀取 共享資料結構(如記憶體中的資料頁),僅在寫入時要求獨佔存取。
關鍵區別在於:鎖 作用於邏輯層面,依交易隔離等級保護資料庫內容(資料列、資料表),支援共享、更新、排他、意圖等模式,並具備死鎖偵測與解決機制;閂鎖 則作用於物理層面,協調執行緒對記憶體資料結構的存取,模式更細緻(含 Keep、Destroy),不支援死鎖偵測(靠嚴謹程式碼避免),且無法透過 Hint 或隔離等級直接控制。
SQL Server 定義了六種閂鎖模式,彼此相容性各異:

SQL Server 將閂鎖分為三類,各自對應特定的等待類型前綴,可透過 DMV 監控:
當緩衝集區的頁面讀寫操作未完成(即與儲存子系統未同步)時使用。等待類型前綴為 PAGEIOLATCH_。高等待通常暗示儲存子系統瓶頸。
SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'PAGEIOLATCH_%'

保護緩衝集區中頁面不被並發執行緒破壞,防止記憶體中發生遺失更新。等待類型前綴為 PAGELATCH_(注意無 "IO" 字樣,代表記憶體內部競爭)。
SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'PAGELATCH_%'

常見熱點:PAGELATCH_UP、PAGELATCH_EX 於系統頁面(PFS、GAM、SGAM)常見於高併發插入場景(如身分識別欄位熱點),可透過分割資料表、使用 SEQUENCE 或啟用 TF 1118 緩解。
保護緩衝集區以外的共享資料結構(如鎖管理器、排序記憶體、資料庫啟動結構)。等待類型前綴為 LATCH_,概況見 sys.dm_os_wait_stats,詳細統計請查 sys.dm_os_latch_stats。
SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'LATCH_%'
SELECT * FROM sys.dm_os_latch_stats

SQL Server 2014 內部使用 163 個非緩衝區閂鎖。著名範例 FGCB_ADD_REMOVE 保護檔案群控制區塊,若其等待居高不下,通常意味著頻繁的自動成長操作——建議預先調整檔案大小、關閉自動成長或設定合理增長增量。
對於極短、高頻率的共享結構存取(如鎖管理器的雜湊桶),閂鎖的上下文切換開銷過大。SQL Server 引入自旋鎖:執行緒在 CPU 上「忙碌等待」(自旋)一小段時間,避免進入 SUSPENDED 狀態。自 SQL Server 2008 R2 起引入指數退避機制,自旋一段時間後睡眠並逐漸增加睡眠間隔,平衡 CPU 消耗與回應延遲。鎖管理器的 LOCK_HASH 自旋鎖即典型應用。
閂鎖是 SQL Server 高併發效能的基石。理解其模式、分類與監控 DMV,能幫助 DBA 快速定位記憶體爭用、I/O 瓶頸與系統頁面熱點,進而制定精準的優化策略(如調整檔案群配置、優化索引設計、控制自動成長)。