把和SQL Server記憶體和AWE相關問題的基本內容整理了一下。
1. SQL Server記憶體基本概念
在涉及SQL Server記憶體時有幾個比較重要的術語:
Buffer Pool (BPool)
SQL Server使用的幾個分散的地址空間,內部進程使用,包括儲存編譯,執行計畫,建立索引,申請指標。
MemToLeave
SQL Server在啟動時就保留的連續地址空間,供進程空間內的大於8KB的外部組件用,諸如擴充過程,COM/OLE自
動化組件,串連伺服器等。
Reserved
保留的地址空間,以供未來使用。
Committed
進程現在使用的地址空間,可能是物理RAM也可能是分頁檔空間。
Allocation
把記憶體資源給消費者。
SQL Server在初始化過程中幹了些什嗎?
1. 計算並保留MemToLeave
SQL7.0是256M,SQL Server 2000是384M,2005和2008是256M(感謝nzperfect的提醒)。
2. 檢查OS支援的最小實體記憶體和VAS,分配以下空間:
a)buffer頭
b)BPool
c)對BPool跟蹤的array
3. 把LazyWriter歸零
LazyWriter定期檢查BPool,看是要增加還是縮減。(因為大概要間隔60秒,所以看上去比較懶。。。真形象)
4. 釋放保留的MemToLeave,保證MemToLeave地址空間連續
SQL Server不會在一上來就保留Min Server Memory,但只要系統一旦達到Min Server Memory設定就不會再次低
於那個設定。對於Intel系統,SQL Server至少會留4MB記憶體。如果達不到,那麼SQL Server就會將記憶體釋放給OS
。如果沒需求SQL Server不會亂吃記憶體,不過一般情況下也不會吐記憶體出來,為了避免效能明顯下降。
2. VAS與AWE
當SQL Server可用的記憶體在3-4GB以下,SQL Server可以完全用Virtual Address Space(虛擬位址空間,VAS)
。2G為使用者模式用,2G為系統(核心模式)用。就是說在這種情況下SQL Server最多用2GB記憶體(當然因為還有
其他應用程式,一般只能用不到2G,比如1.6G)。例如在我的32位測試機上,運行DBCC MemoryStatus,結果如
下:
Memory Manager KB
VM Reserved 1683800
VM Committed 293084
保留的virtual address space為1.68GB左右,佔用的為290MB左右。
對於3G以上記憶體的機器就要用AWE(Address Windowing Extensions),允許映射到額外的記憶體上,上限64GB。
應用了AWE,從Task Manager看,SQL Server進程始終只用了256MB記憶體,被AWE用的記憶體不顯示。所以看SQL
Server佔用的記憶體最方便的方法是在效能監控器(Performance Monitor)中的SQLServer: Memory Manager -
Total Server Memory (KB)。
也可以通過DBCC MEMORYSTATUS或如下查詢來查看:
SELECT * FROM sys.dm_os_performance_counters
WHERE counter_name IN ('Target Server Memory (KB)','Total Server Memory (KB)')
Target Server Memory (KB)就是最多可以吃多少,Total Server Memory (KB)就是目前吃了多少。
SQL Server進程佔用率也可以用下面的查詢:
SELECT *
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = 'RING_BUFFER_RESOURCE_MONITOR'
啟用AWE有三步:
1. 在boot.ini內增加/pae 允許Windows Server訪問更多記憶體(最多16GB)
2. 給SQL Server進程賦予“Lock Pages in Memory”
3. 將配置中的“AWE Enabled”設定為1
對於Windows Server 2003,如果啟用了AWE,SQL Server總是會使用它並動態管理。在啟動時它會分配用作啟動
工作負載的記憶體,接著就會看自己的需求有多少記憶體吃多少,直到到達“Max Server Memory”。如果SQL Server
遇到記憶體壓力,會儘可能釋放記憶體,直到“Min Server Memory”。
建議設定“Max Server Memory”以保證其他進程有記憶體用,對於32GB記憶體的可以留2G,對於64GB記憶體的可以留4G
。如果同時有多個執行個體存在,更需要防止一個執行個體吞掉了過多記憶體。
AWE對於64位機器不是必須的。不過還是建議給運行SQL Server進程的使用者帳號“Lock Pages in Memory”許可權,
防止SQL Server記憶體不夠寫就寫到磁碟上。對於64位伺服器,預設使用AWE,所以如下查詢可能會返回非零值:
Select sum(awe_allocated_kb) / 1024 as [AWE allocated, Mb]
From sys.dm_os_memory_clerks
目的是避免working set trimming。
3. SQL Server記憶體問題
當配置SQL Server時,知道它如何應對記憶體壓力非常重要。記憶體壓力分為兩大類:VAS和實體記憶體。實體記憶體壓
力直接從OS就可以看出來,因此也可以稱作外部記憶體壓力。也可能是它自己的進程導致的,因此也可以稱作內部
記憶體壓力。
SQLOS管理記憶體壓力的整體架構如下:
Resource Monitor
/ | \
Low Physical Internal/External Low VAS High Physical Internal/External |
Resource Monitor(RM)是一切的核心,一有動靜馬上獲知,廣播到memory clerks。
先暫時整理到這裡。
之所以研究這個問題是由於一個case,客戶的64位SQL Server會出現AWE Allocated突然從6G(MAX Server
Memory)跌到2G(Min Server Memory),再過了數個小時之後SQL Agent出現Virtual Memory Too Low導致任務
失敗。我研究了很長時間也沒有獲得結論,只好Escalate掉。目前樓上Team的工程師懷疑是系統的問題導致強制
回收記憶體,讓客戶使用perfmon log和adplus(ADPlus 是 Microsoft 產品支援服務 (PSS) 提供的一個工具,它
可以解決停止回應(掛起)或失敗(崩潰)的任何進程或應用程式的問題。)收集系統的資訊。
還有另外一個也是和記憶體有關的case,客戶機器的4G記憶體莫名其妙地被SQL Server進程吃掉了2.9G,但進程佔用
的CPU佔用,想知道是為什麼。這個現在正在幫忙收集資訊中。客戶好像關於這個瞭解的比我還少,能稍微
最近做的一個記憶體緊張一個Report Viewer最佳化一個Data Mining都沒能解決在拖了很久之後只好Escalate,真受
打擊。。。好吧,專心做剩下的Discuz!NT的case,知道自己幾量重後只好用努力來彌補了。
參考內容:
SQL Server 2005 and AWE Memory
http://www.jimmcleod.net/blog/index.php/2008/06/03/sql-server-2005-and-awe-memory/
AWE related
http://blogs.msdn.com/slavao/archive/2005/11/15/493019.aspx
http://blogs.msdn.com/slavao/archive/2005/04/29/413425.aspx
http://support.microsoft.com/kb/918483
SQLOS's memory manager: responding to memory pressure
http://blogs.msdn.com/slavao/archive/2005/02/19/376714.aspx
SQL Server Memory
http://www.sqljunkies.ddj.com/Tutorial/0D4FF40A-695C-4327-A41B-F9F2FE2D58F6.scuk
Slava Oks's WebLog
http://blogs.msdn.com/slavao/archive/tags/default.aspx