程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 淺談SQL Server對於內存的管理(3)

淺談SQL Server對於內存的管理(3)

編輯:關於SqlServer

32位SQL Server的內存瓶頸

由文章前面所述的一些基本原理可以看出,由於32位的SQL Server使用的是VAS進行地址分配,因此尋址空間被限制在4GB,這4GB還要有一半分給Windows,使得Buffer Pool最多只能用到2G的內存,這使得32位SQL Server即使有多余的物理內存,也無法使用。

解決辦法之一是通過減少Windows默認占用的2G到1G,使得SQL Server可以使用的內存變為3G。這個可以通過在Windows Server 2008中的命令行鍵入 BCDEdit /set設置increaseuserva選項,設置值為3072MB,對於Windows Server 2003來說,需要在boot.ini中加上/3gb啟動參數。

另一種辦法是使用AWE(Address Window Extension)分配內存。AWE通過計算機物理地址擴展(Physical Address Extension PAE),增加4位,使得32位的CPU尋址范圍增加到2的36次方,也就是64GB。基本解決了尋址范圍不夠的問題。

VirtualAlloc和AllocateUserPhysicalPages

VirtualAlloc 和AllocateUserPhysicalPages是SQL Server向Windows申請內存所使用的方法。在默認情況下,SQL Server所需要的所有內存都會使用VirtualAlloc去Windows申請內存,這種申請是操作系統層面的,也就是直接對應的虛擬內存。這導致一個問題,所有通過VirtualAlloc分配的內存都可以在Windows面臨內存壓力時被置換到虛擬內存中。這會造成IO占用問題。

而使用AllocateUserPhysicalPages所申請的內存,直接和更底層的頁表(Page Table)進行匹配,因此使用這個方法申請的內存不會被置換出內存。在32位SQL Server的情況下,通過開啟AWE分配內存,buffer pool中的data cache部分將會使用這個函數,而MemToLeave部分和Buffer Pool中的另一部分內存(主要是執行計劃緩存)依然通過VirtualAlloc進行內存分配。

因此在開啟通過AWE分配內存之前,SQL Server首先需要對應的權限,否則就會在日志中報錯,如圖10所示。

10
圖10.開啟AWE卻沒有開啟對應權限報錯

我們可以在組策略裡設置啟動SQL Server的賬戶擁有這個權限,如圖11所示。

11
圖11.鎖定內存頁(Lock Page In Memory)

64位SQL Server的問題

64位Windows基本已經不存在上述的內存問題,但是依然要注意,在默認情況下,64位的SQL Server使用的依然是VirtualAlloc 進行內存分配,這意味著所有分配的內存都會在Windows面臨壓力時將頁置換出去,這很可能造成抖動(Buffer Pool Churn),這種情況也就是SQL Server Buffer Pool中的頁不斷的被交換進硬盤,造成大量的IO占用(可以通過sys.dm_exec_query_memory_grants這個DMV查看等待內存的查詢),因此64位SQL Server將Buffer Pool中的Date Page通過AllocateUserPhysicalPages來進行內存分配就能避免這個問題。與32位SQL Server不同的是,64位SQL Server並不需要開啟AWE,只需開啟如圖11所示的“Lock Page In Memory”就行了。

但這又暴漏出了另一個問題,因為SQL Server鎖定了內存頁,當Windows內存告急時,SQL Server就不能對Windows的內存告急做出響應(當然了Buffer Pool中的非data cache和MemToLeave部分依然可以,但往往不夠,因為這部分內存相比Data Cache消耗很小),因為SQL Server的特性是內存有多少用多少,因此很有可能在無法做出對Windows低內存的響應時造成Windows的不穩定甚至崩潰。因此開啟了”Lock Page In Memory”之後,要限制SQL Server Buffer Pool的內存使用,前面圖2中已經說了,這裡就不再細說了。

還有一個問題是當Buffer Pool通過AllocateUserPhysicalPages分配內存時,我們在任務管理器中看到的sqlservr.exe占用的內存就僅僅包含 Buffer Pool中非Data Cache部分和MemToLeave部分,而不包含Data Cache部分,因此看起來有可能造成sqlservr.exe只占用了幾百兆內存而內存的使用是幾十G。這時我們就需要在Perfmon.exe中查看 SQL Server:Memory Manager\Total Server Memory計數器去找到SQL Server真實占用的內存。

總結

本文講述了SQL Server對內存管理的基本原理和SQL Server對內存使用所分的部分,對於SQL Server性能調優來說,理解內存的使用是非常關鍵的一部分,很多IO問題都有可能是內存所引起的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved