配置SQL Server去使用 Windows的 Large-Page/Huge-Page allocations
目錄表->頁表->物理內存頁
看這篇文章之前可以先看一下下面這篇文章
了解一下虛擬地址空間(VirtualAddressSpace,VAS)的概念
前幾天在論壇里遇到一個問題
其中提到一個可能性的原因,開啟了Large-Page allocations,看完文章之后就會知道,其實跟Large-Page allocations無多大關系
Large-Page allocations是什么來頭??
參考這篇文章:Configuring SQL Server to use Windows Large-Page allocations
今天,一個可改變控制的實現激使我去寫這篇文章,這個可改變的控制就是允許運行在Windows200864位服務器上的SQL Server 2005企業版上
使用跟蹤標志834,SQLSERVER會利用 Large-Page allocations去構建內存中的Buffer Pool。
下面是我對 Large-Page allocations的理解和這個Large-Page allocations對性能的提升
頁面分配
虛擬地址空間(VirtualAddressSpace,VAS)由很多的內存頁面組成。這些頁面有兩種大小,32位系統是小的頁面只有4KB大小(IA64位系統上是8KB)
64位系統上是大的頁面有2MB大小(IA64位系統上是16MB)。
虛擬地址空間(VirtualAddressSpace,VAS)是由頁面描述符表(簡稱頁表)這種結構來維護的,因此,每個虛擬地址空間在頁面描述符表里都有對應頁面表入口
(個人感覺類似於系統服務描述符表SSDT ,內核描述符表GDT/LDT)。硬件利用這個表將這些入口轉譯出可讀的格式,無論什么時候轉譯一個虛擬地址,
都必須去這張表找虛擬地址的入口。為了加快查找表上這些入口的速度,CPU維護了一塊緩存叫做:Translation Look-Aside Buffer (TLB)
TLB的工作方式類似於SQLSERVER的執行計划緩存,只要一個入口曾經被轉譯過下次就不需要再次轉譯,大頁的好處是提高TLB命中率,減少內核cpu消耗。
知道這個,就很容易去理解大的頁面和小的頁面對性能的差別。當一個進程的虛擬地址空間(VirtualAddressSpace,VAS)(每個進程只有一個虛擬地址空間,
虛擬地址空間=一個進程使用的內存)是由小的內存頁面構成的,那么在頁面描述符表里的入口就需要相應增加,同時TLB緩存的入口數也會相應增加。
舉個例子,有幾個虛擬地址空間需要被緩存,使用小頁面(一個頁面4KB)就需要在TLB中緩存更多的入口。更多的入口意味着無論什么時候接收到
一個新的轉譯請求,TLB的入口緩存就需要更多去循環利用。因此使用大頁面去分配虛擬地址空間在性能上會有一定的提升。

大的頁面2MB大小,小的頁面4KB大小,比如一個進程需要8MB內存,那么需要4個大頁面或者2000個小頁面
所以使用小頁面來分配虛擬地址空間,就需要在TLB緩存更多的入口,但是TLB緩存的大小是有限的!!
頁面分配和SQLSERVER
就像我早前提到過的跟蹤標志834,834跟蹤標志會強迫SQLSERVER進程虛擬地址空間使用大頁面去構建Buffer Pool。這個跟蹤標志
只能在64位SQLSERVER企業版,並且需要開啟 Lock Pages in Memory功能才能使用。
當SQLSERVER使用大頁面分配的時候,在SQL服務啟動時入口信息會被記錄在SQL ERRORLOG里
Large Page Extensions enabled.
Large Page Granularity: 2097152
Large Page Allocated: 32MB
Using large pages for buffer pool.
10208 MB of large page memory allocated.
如果SQLSERVER帳戶沒有Lock Pages in Memory的權限,就會在SQL ERRORLOG里記錄下錯誤信息
Cannot use Large Page Extensions: lock memory privilege was not granted.
這篇文章非常友好地闡述了大頁面分配和闡述了需要使用跟蹤標志834 並使用64位SQLSERVER企業版才能使用大頁面分配
注意:(1)不能在SQLSERVER運行的過程當中指定跟蹤標志834
DBCC TRACEON(834,-1)
正在忽略跟蹤標志 834。該跟蹤標志無效,或者只能在服務器啟動過程中指定。
DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。
只能在SQLSERVER啟動的時候加上啟動參數:834
(2)如果SQLSERVER的《max server memory》選項被設置為0,當SQLSERVER啟動的時候會占用整個服務器的所有物理內存
(3)服務器需要有8GB或以上的物理內存和操作系統並且必須是企業版才能使用大頁面分配
(4)可以使用下面SQL語句查看當前大頁面分配的內存
SELECT large_page_allocations_kb , locked_page_allocations_kb FROM sys.dm_os_process_memory

(5)如果系統符合大頁面分配,並且開啟了834跟蹤標志,那么當SQLSERVER啟動的時候會比較慢,可能需要幾分鍾時間
2009-06-04 14:20:31.14 Server Large Page Allocated: 32MB
2009-06-04 14:20:40.03 Server Using large pages for buffer pool.
2009-06-04 14:27:56.98 Server 2048 MB of large page memory allocated.
上面的時間顯示SQLSERVER用了7分鍾時間來分配頁面
總結:
為什麽SQLSERVER啟動的時候就占用了服務器的所有內存,其中的一個原因有可能是你開啟了跟蹤標志834符合SQLSERVER使用大頁面分配虛擬地址空間的要求,並且設置《max server memory》選項為0
相關文章
SQL Server and Large Pages Explained….
http://www.cnblogs.com/MYSQLZOUQI/p/5335649.html
如有不對的地方,歡迎大家拍磚o(∩_∩)o
2014-5-25補充
SQLSERVER2012新的內存管理器支持分配所有的大小。single page allocator和multi-page allocator都將退出歷史舞台
不論分配多大的內存大小,內存管理器都只有三種不同的內存模型:
1、普通頁
2、鎖定頁(locked pages,意思即是說通過設置組策略鎖定內存頁功能,把頁面鎖定在內存)
3、大內存頁(large pages)
上面3種頁面在SQLSERVER啟動的時候ERROR LOG里都會打印出來,當前使用的是哪種模式的內存
大內存頁的使用只存在於64位版的SQL Server中
1、新的內存管理器是完全支持NUMA的
2、虛擬地址空間的管理是完全動態的,特別是對32位的實例也是如此
3、內存管理器分配出去的內存都受max server memory控制
4、32位實例不再支持AWE
32位的SQLSERVER2012只能使用4GB物理內存,如果你需要使用更多的物理內存,必須要升級到64位版本

實際上,跑在Linux上的Oracle也有這個問題,在Linux上開啟huge page/large page的方法
1、/etc/sysctl.cnf 中增加vm.nr_hugepages參數來為大頁設定一個合理的值,值的單位為2MB,需要重啟Linux
2、echo 一個值到/proc/sys/vm/nr_hugepages中也可以臨時性的對大頁進行設定
具體參考:http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=403265328&idx=1&sn=b852e6ba4669c787de352c9823d05139&scene=0#wechat_redirect
本文版權歸作者所有,未經作者同意不得轉載。
