SQL Server 的記憶體管理是一個龐大的主題,涉及特别多的概念和技術,例如常見的 Plan Cache、Buffer Pool、Memory Clerks 等。本文僅是管中窺豹,描述常見的記憶體管理相關概念。

在了解記憶體管理之前,通過 sys.dm_os_memory_clerks 視圖可以查詢記憶體的使用職責(Memory Clerks),也就是記憶體的消耗者。
SQL Server 中最主要的記憶體元件就是緩沖池(Buffer Pool, or Bpool)。緩沖池是一個 8KB 頁面的集合,任何大于 8KB 的記憶體塊都需要進行單獨配置設定管理,例如 COM Objects、CLR Code、Extended Stored Procedures、Large Cached Plan 等。
緩沖區管理器(Buffer Manager)負責從磁盤上的資料檔案中讀取資料頁(Data Page)和索引頁(Index Page),将頁資料放入 Buffer Pool 中作為資料緩存(Data Cache)。Buffer 指的是記憶體中的一個 Page,該 Page 的大小與資料頁或索引頁相同。
SQL Server 采用預讀機制(Read-ahead)從磁盤中讀取資料頁和索引頁至緩沖區中,以提高性能。預讀機制完全有系統内部控制,不需要進行任何配置和調整。
資料緩存(Data Cache)中使用哈希(Hashing)方式存儲頁資料。比如給定 DatabaseID-FileNumber-PageNumber 辨別符,通過哈希函數将辨別符存放到哈希表中。這樣,通過哈希表(Hash Table)提供的快速檢索功能,資料庫引擎僅需要較少的記憶體讀取就可以判斷目标頁是否存在于緩存中,如果不存在再從磁盤中讀入緩存。
SQL Server 會将那些一段時間未被引用的頁面緩沖位置标記為空閑頁,通過空閑頁連結清單進行管理。當需要新的緩沖頁時,将從連結清單頭擷取要使用的頁位址。
每個資料緩存的頁中都包含一塊表頭區域,包含該頁最後兩次被引用的相關資訊和狀态資訊,例如描述該頁是否為髒頁(Dirty Page)。髒頁(Dirty Page)指的是從磁盤讀取後的資料頁被修改過。引用資訊則用于實作資料緩存頁的頁面替換政策,它使用 LRU-K 算法。LRU-K 算法将有價值的緩沖區持有頁保留在活躍緩沖池中,而如果緩沖區持有頁的引用頻率不高,則這些緩沖區頁将被逐漸地釋放回空閑緩沖區清單中。
SQL Server 為每個 NUMA 節點都建立了一個 LazyWriter 線程,用于掃描與該節點關聯的緩沖區。LazyWriter 線程會進行周期性的睡眠和喚醒,當喚醒時将檢查空閑緩沖區清單的長度,如果低于某個門檻值,将掃描整個緩沖區。在掃描過程中,當發現頁的引用率較低時,将檢查髒頁訓示符。如果該頁是髒頁,則執行磁盤寫入操作。然後該頁将被釋放回空閑緩沖區清單中。
SQL Server 動态使用記憶體時,必須不斷地偵聽可用記憶體的數量,并且追蹤和監視記憶體的更改,以判斷何時增加或減少自身的總記憶體量。每當 SQL Server 中的記憶體增加或減少 1MB,或達到伺服器記憶體的 5% 時,将會産生事件通知。
檢查點(Checkpoint)線程也定期掃描緩沖區,并将髒資料頁寫入磁盤。檢查點與 LazyWriter 的差別在于,檢查點不會向空閑緩沖區清單添加空閑緩沖區。檢查點的唯一目的就是,確定将某一時刻前的頁面都寫入磁盤中,以便始終保持記憶體中的髒頁數量最小。
SQL Server 将檢查點的運作過程記錄到事務日志中,當 SQL Server 出現故障時,由于已寫入了某一時刻前的資料,可以減少恢複時間。
觸發檢查點的情況有:
手動觸發 CHECKPOINT 指令在指定資料庫上執行檢查點。
日志正在變慢,超過容量的 70%。觸發檢查點可以截斷日志并釋放日志空間。
預計需要較長的恢複時間。預計恢複時間比設定的 "Recovery Interval" 選項的值要長時。如果 "Recovery Interval" 設定為 1,意味着檢查點每分鐘一次。預設值為 0,意味着 SQL Server 将選擇合适的值,通常也是 1 分鐘。
請求正常關閉 SQL Server,并且不使用 NOWAIT 選項。
檢查點線程采用非順序的方式對緩沖區進行掃描。當找到一個髒頁時,會檢查該髒頁在磁盤上相鄰的頁面是否也是髒頁,以便組合進行 gather-write 大塊資料寫入,提高性能。
在 Buffer Pool 的緩沖區的使用元件中,除了資料緩存(Data Cache),另一個使用量最大的就是對過程與查詢計劃的緩存,也就是通常說的計劃緩存(Plan Cache)。
SQL Server 為處資料緩存外所有其他的緩存機制提供通用緩存架構,包括儲存方式和資源螢幕。儲存方式包括三種:
Cache Store:計劃緩存(Plan Cache)和行集(Rowset Clerk)為常見的 Cache Store。
User Store:中繼資料緩存(Metadata Clerk)即為一種 User Store。
Object Store/Memory Pool:SNI Pooling Network Buffer 即為一種 Object Store。
Cache Store 和 User Store 采用 LRU 機制來配置設定和釋放空間,使用 Clock 頁面置換算法來實作。而 Object Store 則隻是大塊的記憶體,不需要 LRU 機制。
Cache Store 使用哈希表來加快查詢速度,而 User Store 則未使用哈希表,Object Store 也未使用哈希表。
通過檢視 sys.dm_os_memory_cache_clock_hands 視圖,尤其是 removed_last_round_count 列,如果該值在急劇增加,那麼是出現記憶體壓力的顯著征兆。
<a></a>
在 SQL Server 中有大量的元件需要使用記憶體,為了確定每個元件都在有效的使用記憶體,SQL Server 使用 Memory Broker 分析與記憶體消耗相關的行為,并改善動态記憶體配置設定。
Memory Broker 可以在 Buffer Pool、Query Executor、Query Optimizer 等各種使用緩存的元件間排程記憶體配置設定。通過監視記憶體的需求與消耗,通過帶有回報和改進機制的動态配置設定算法,協調各元件間形成最佳的記憶體配置設定方式。
sys.dm_os_memory_clerks 該視圖描述 SQL Server 執行個體中正在使用記憶體的元件職責。
sys.dm_os_memory_objects 該視圖描述 SQL Server 目前配置設定的記憶體對象。
sys.dm_os_memory_nodes 該視圖描述配置設定的 NUMA Node 相關資訊。
sys.dm_os_memory_pools 該視圖顯示 Object Store 相關資訊。
sys.dm_os_memory_cache_counters 該視圖描述 Cache Store 和 User Store 的運作情況快照。
sys.dm_os_memory_cache_hash_tables 該視圖描述活躍的緩存資訊。
sys.dm_os_memory_cache_clock_hands 該視圖描述 Clock 頁面置換算法的相關資訊。
《人人都是 DBA》系列文章索引:
序号
名稱
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
本文轉自匠心十年部落格園部落格,原文連結:http://www.cnblogs.com/gaochundong/p/everyone_is_a_dba_sqlserver_memory_management.html,如需轉載請自行聯系原作者