當我們在SSMS裡執行下面的SQL語句清空SQLSERVER的緩存的時候,我們會在SQL ERRORLOG裡看到一些資訊

大家可以看到cachestore、object plans、sql plan、bound tress等名詞
那麼這些名詞是什麼意思呢?是什麼功能元件呢?這篇文章為大家介紹SQLSERVER Buffer Pool,大家就會知道了
翻譯自:
原文大意
在網上有非常多的文章、部落格、文章介紹記憶體配置和記憶體的一些情況,但是依然給大家帶來了太多的誤解。
這些文章都有講到SQLSERVER 記憶體、虛拟記憶體、AWE功能還有其他的一些介紹我個人認為不能很好地對SQLSERVER記憶體方面的各個
性能計數器有很好的了解
在這篇文章裡,我會着重講解BufferPool的一些機制,例如你的資料頁面和索引頁面在SQLSERVER的記憶體裡是怎麽存放的
在性能螢幕裡你能夠使用這些知識去判斷目前BufferPool的狀态。
(當我談論到頁面的時候,我隻談論資料頁面和索引頁面。對于事務日志記錄,有一個特别的日志管理器我将會在
另一篇文章裡講述日志記錄是如何寫入到日志檔案的)
首先讓我們來看一下一些Buffer Pool 的一些相關概念。一個簡單的Buffer Pool 概念圖就像下圖那樣
POOLS AND CACHE STORES
緩沖池會通常會緩存同類的、無狀态的資料。所有類型的資料在緩存池中會被視為平等的
例如:連接配接池或者網絡緩沖區
Cache stores
通常被用作緩存狀态資料和提供一組記憶體配置設定接口給不同的客戶重用。
例如存儲過程緩存會分為幾個不同的cache stores
1、第一種用來存儲ad-hoc類型SQL 執行計劃
2、第二種用來存儲存儲過程、函數、觸發器等的執行計劃
3、第三種用來存儲擴充存儲過程的執行計劃
The Free List
SQLSERVER會維護着一個最小數量的空閑頁面記錄在空閑清單裡以能夠最快處理傳入的請求。
SQLSERVER會盡量在空閑清單裡維護着空閑頁面的數量(“Min Free“ 在 DBCC MEMORYSTATUS 的輸出裡面)
的計算是根據 Buffer Pool的大小和傳入的請求數(頁面平均壽命,在緩存裡面頁面的壽命就是一個名額)
大家在運作 DBCC MEMORYSTATUS
的時候有沒有留意他的輸出結果,實際上每一個節就是一個cache store
了解: cache:緩存 store:店鋪 在SQLSERVER Buffer Pool裡有很多這樣的緩存店鋪(cache store),而每家店鋪賣的東西是不一樣的,更有趣的是每家店鋪裡 隻賣同一樣商品
對緩存頁面進行寫操作和釋放操作
SQLSERVER使用LRU()去計算在Buffer Pool裡的頁面壽命
MYSQL和ORACLE也是使用的LRU算法來清除緩存
基本上,當一個頁面每引用一次,計數器就會上升,當lazy writer 程序将頁面請出緩存的時候,計數器也會降下來
其他工作線程在特定時刻(例如當一個異步I/O發生的時候)會檢查目前Buffer Pool的記憶體狀态確定對新的請求有足夠
數量的空閑頁面可用。如果空閑的緩存不夠,那麼會有兩件事情發生:
事件一:如果 Buffer
Pool的上限已經達到了(這個上限是根據 “max server memory”和目前作業系統的可用記憶體來的)
這兩個都會反映在SQL Server Memory Manager:Target Server Memory 這個計數器)
lazywriter 程序會清除部分 Buffer Pool 緩存
lazywriter 程序清除Buffer Pool 緩存的幾種政策:
1、他會跟蹤自上次清除緩存時沒有被清除的頁面,這一次進行清除
2、根據頁面最後一次被引用的時間,如果太久沒有引用則清除
3、資料頁面是否是髒頁,如果是髒頁面則刷入到磁盤中
清除完畢之後會修改Free List,告訴Free
List目前有哪些空閑的頁面,如果事務日志記錄還沒有寫入到磁盤,那麼髒頁是不會被刷入的直到事務日志記錄
已經寫入磁盤
事件二:如果 Buffer
Pool還沒有達到上限
那麼SQLSERVER送出更多的預留頁面( reserved pages 向作業系統申請更多的記憶體)到Buffer
Pool裡,而不是像剛才那樣,
清除一些頁面讓這些清除後的頁面重新回歸到Free List
這就是為什麽Page Life Expectancy 這個計數器在一台瓶頸很小的伺服器裡會非常高的原因(因為系統還有很多記憶體)
資料頁面不需要被請出 Buffer Pool。
而且Process:Private Bytes (sqlservr.exe) 和SQL Server Memory Manager: Total
Server Memory 會一直增長,即使在一台伺服器上
活動比較少
刷寫資料頁面和釋放資料頁面的三個線程
(一)Lazywriter 線程
Lazywriter 線程是一個系統線程,他會将一批在buffer pool裡的髒頁刷出并修改buffer pool的Free List
Lazywriter 線程的主要工作是維護空閑清單
(二)Checkpoint 線程
Checkpoint 線程也是一個系統線程,他會在一定時間裡喚醒并檢查每個資料庫是否超過了Recovery interval
他的主要工作是把髒資料頁面刷到磁盤,以便在資料庫還原的時候減少事務日志undo和redo的事務數,然而,Checkpoint 不會
去更新Free List
(二)Eager Write 線程
Eager Write 線程是一個特别的寫機制用作 non-logged 的I/O操作,例如BULK INSERT和SELECT
INTO.
這個線程的目的是避免一種叫做Buffer Pool 的無用物(當發生大容量的資料操作例如BULK INSERT的時候,
讀入到Buffer Pool裡的這些資料頁面一般不太可能重用),是以當完成大容量操作之後會由Eager Write 線程将
這些資料頁面進行清除
Eager Write 線程和Lazywriter 線程的差別:
Lazywriter 線程:當作業系統中可用記憶體不足或者buffer pool已經達到上限 ,而有新請求需要使用資料頁面的時候,Lazy writer
線程才會觸發,是以叫Lazy
而Lazy writer在清除資料頁面的時候,會等事務日志記錄flush到磁盤之後才會将資料頁面flush到磁盤
在 NUMA系統裡面,每一個NUMA節點都會有一個 Lazywriter線程
Eager Write 線程:做完大容量操作之後,會馬上進行資料頁面清除工作,是以叫Eager(勤奮)
總結
文章簡單介紹了Cache Store的來曆和SQLSERVER Buffer Pool的結構,希望對大家了解SQLSERVER Buffer
Pool有幫助
如有不對的地方,歡迎大家拍磚o(∩_∩)o