在針對window 32位系統環境下,編者對SQL Server 2008進行了內存性能和I/O性能的監控和診斷,並作了分析。文中主要分三個模塊,分別爲:SQL Server 2008內存性能介紹、SQL Server 2008內存管理與系統視圖和SQL Server 2008的I/O性能診斷。node
內存相關概念算法
如下均是針對Window 32位系統環境下,64位的不在下面描述狀況下。sql
用戶模式和內核模式(user mode& kernel mode)數據庫
爲了防止用戶程序訪問並篡改操做系統的關鍵部分,Windows使用了2種處理器存取模式:用戶模式和內核模式。顧名思義,內核模式是給操做系統核心代碼和基本驅動用的,用戶模式給用戶應用程序。在內核模式下程序能夠訪問全部的內存和硬件,並使用全部的處理器指令。操做系統程序比用戶程序有更高的權限,使得系統設計者能夠確保用戶程序不會意外的破壞系統的穩定性。緩存
物理內存(Physical Memory)安全
即實際購買的內存的大小,內存條上的容量。CPU的地址線能夠直接進行尋址的內存空間大小,在32位操做系統平臺上,CPU的最大尋址空間爲4GB,也便可以支持最大4G的物理內存空間。在32位操做系統上即使你購買的是64G內存,也只能說擁有4GB的物理內存空間服務器
虛擬內存(Virtual Memory)網絡
若是計算機缺乏運行程序或操做所需的隨機存儲內存,則Windows使用虛擬內存進行補償。虛擬內存將計算機的RAM和硬盤上的臨時空間組合在一塊兒,當RAM不足時,虛擬內存將數據從RAM移動到稱爲「分頁文件」的空間中,將數據移入與移出分頁文件能夠釋放RAM,以便完成工做。架構
虛擬地址空間(Virtual Address Space,簡稱VAS)函數
在Windows系統中,任何一個進程都被賦予了其本身的虛擬地址空間,該虛擬地址空間覆蓋了一個至關大的範圍,對於32位系統的虛擬地址空間範圍從0x00000000~0xffffffff(4GB)。Windows採用分頁機制,將4G的地址空間分紅固定大小的頁,而且將虛擬地址中的每一頁映射到物理內存中。
在缺省的狀況下虛擬地址空間中的低2G,即0x0000000~0x7FFFFFFFF是用戶地址空間,而4G虛擬地址空間中的高2G即0x8000000~0xFFFFFFFF是分配給內核模式。實際上用戶進程擁有的虛擬地址空間只有2GB。
虛擬內存管理器(Virtual Memory Manager)
虛擬內存管理器負責虛擬地址空間和物理內存的地址映射,若是缺少足夠內存,則須要使用到page file文件來保持臨時數據也即虛擬內存,同時使用page table entry(PTE)來跟蹤每個地址映射關係。
到這裏爲止,64G的內存有60G都沒法訪問,豈不是浪費了,那怎麼辦?
/3GB和increaseUserVA
經過/3GB的方式,能夠減小內核模式佔用地址空間,從而增長SQL Server進程的地址空間。默認狀況下,用戶模式和內核模式各自佔用2G尋址空間,3G選項可使得SQL Server得到多1G的虛擬地址空間。
/3GB開關用法:
在Boot.ini文件中修改其中的段落便可
或者使用bootcfg命令
在Windows Server 2008中能夠運行BCDEdit命令,加以調整。
物理地址擴展PAE(Physical Address Extension)
物理地址擴展(PAE)是32位Intel CPU的一種擴展,這樣能夠在32位系統上支持最大64G的物理內存,即4GB以上物理內存容許將更多物理內存映射爲應用程序的虛擬地址空間。
使用方式,在Boot.ini文件中修改其中的段落便可:
在Windows Server 2008操做系統下也能夠經過如下命令執行
/PAE和/3GB
二者的目標是不一樣的,又能夠在一樣的地方進行配置,因此不免產生疑惑,簡單的來講就是若是計算機可用物理內存超過16GB,就須要確保boot.ini文件中沒有/3gb參數便可。
地址窗口化擴展插件AWE(Address Windowing Extensions)
AWE是Windows的內存管理功能的一組擴展,它可以使應用程序使用的內存量超過經過標準32位尋址可以使用的2~3G內存。AWE容許應用程序獲取物理內存,而後將非分頁內存的視圖映射到32位地址空間。雖然32位地址空間限制爲4GB,可是非分頁內存卻能夠遠遠大於4GB。
在SQL Server 2008下,能夠登陸SQL Server Management Studio,找到相應的數據庫實例,點擊右鍵選擇屬性,而後在「選擇頁」中點擊內存,在服務器內存選項中,複選使用AWE分配內存便可。
SQLServer的內存管理
SQL Server 主要的內存組件是緩衝池。其中高速數據緩衝區用以把數據從磁盤加載到內存中,實現數據的高速讀寫。而過程高速緩衝區則用來存儲相應的執行計劃,減小編譯過程,也是高速緩衝倉庫的主要構成部分。用戶倉庫高速緩衝是用戶倉庫的主要組成本部分。對象倉庫則僅僅是內存塊組成的內存池,不須要進行LRU或成本計算例如SQL Server網絡接口(SNI)利用對象存儲倉庫做爲網絡緩衝池。
SQL Server 內存管理器由一個三層的層次結構組成。該層次結構的底層爲內存節點。下一層由內存 Clerk、內存緩存和內存池組成。最後一層由內存對象組成。這些對象一般用於在 SQL Server 實例中分配內存。
內存節點(sys.dm_os_memory_nodes)提供低級分配器的界面和實現。在NUMA中內存節點和CPU節點能夠對應起來的,在 SQL Server 中,只有內存 Clerk 可訪問內存節點。
內存 Clerk(sys.dm_os_memory_clerks) 訪問內存節點界面以分配內存。內存節點還會跟蹤 Clerk 分配的內存以進行診斷。分配大量內存的每一個組件,都必須使用 Clerk 界面來建立其本身的內存 Clerk 並分配其所有內存。各組件會在 SQL Server 啓動時建立其相應的 Clerk。
內存對象(sys.dm_os_memory_objects)是指多個堆。它們所提供的分配的粒度比內存 Clerk 所提供的分配的粒度更精細。SQL Server 組件使用內存對象,而不使用內存 Clerk。內存對象使用內存 Clerk 的頁分配器接口來分配頁。內存對象不使用虛擬內存接口或共享內存接口。根據分配模式的不一樣,組件能夠建立不一樣的內存對象類型來分配任意大小的區域。
SQL Server的緩衝池只提供8KB的內存塊;大於8KB的大內存塊需求是被單獨管理的,且通常是直接從操做系統或者說是從緩衝池外獲取到的,此外只有數據高速緩衝頁面才能使用AWE內存,而且須要單獨跟蹤。
SQLServer的內存方面的系統視圖
sys.dm_os_memory_cache_clock_hands 返回特定緩存時鐘的每一個指針的狀態。提供給用戶關於每一個緩存存儲區和用戶存儲區的時鐘指針信息——指針是否正在轉動、圈數、被移除的條目數量等。此視圖對於查找當前時鐘指針的狀態以及時鐘指針的移動歷史很是有用。
sys.dm_os_memory_cache_counters 返回緩存運行情況的快照。提供有關已分配的緩存條目、緩存條目的使用狀況以及內存源的運行時信息。提供給用戶每一個存儲區的總結信息——使用的內存數量、條目數、正在使用的條目數。用戶可使用該視圖找到緩存的內存使用,以及一個緩存中的條目數量。
sys.dm_os_memory_cache_hash_tables 針對 SQL Server 實例中的每一個活動緩存返回一行。即用戶關於緩存存儲區的散列表信息——最大、最小、平均桶長等。此視圖對於查找緩存存儲區中每一個緩存表的每一個散列桶的條目分佈很是有用。
sys.dm_os_memory_cache_entries 返回有關緩存中全部條目的信息。使用此視圖可對緩存條目進行跟蹤,直至它們的關聯對象。還可以使用此視圖獲取有關緩存條目的統計信息。
sys.dm_os_sys_info返回一組有關計算機和有關 SQL Server 可用資源及其已佔用資源的有用雜項信息。
sys.dm_os_sys_memory 從操做系統返回內存信息。SQL Server 受操做系統級別的外部內存條件和基礎硬件物理限制的約束並對其有所響應。肯定整個系統的狀態是評估 SQL Server 內存使用量的重要方面。
sys.dm_os_virtual_address_dump則返回有關調用進程的虛擬地址空間中的頁範圍的信息。
DBCC MemoryStatus命令提供了SQL Server的當前內存狀態的快照,也能夠做爲咱們分析內存瓶頸的重要依據。
內存壓力
對於SQL Server佔用內存資源的監控主要集中在頁面吞吐能力、頁面錯誤和可用內存上上,對虛擬內存的監控,則重點在於分頁文件的使用率上。下面提供了幾種對象、計數器和相應的閾值及描述。
SQL Server提供的sys.dm_os_performance_counters計數器視圖,主要對緩衝區管理器和內存管理器的一些計數器進行監控,好比頁面的生存週期、檢查點、惰性寫入器和緩衝命中率等指標。
如下爲緩衝池內數據庫緩衝池中各個數據庫的分佈狀況。
如下爲返回當前數據庫中每一個對象的緩存頁計數,加以適當的修改咱們也能夠獲得數據緩衝池中對象數據頁和索引頁的分佈狀況。
下爲緩衝池中前十位消耗內存最大的內存組件。
咱們須要重點關注的內存組件爲如下:
sys.dm_exec_cached_plans針對 SQL Server 爲了加快查詢執行而緩存的每一個查詢計劃返回一行。能夠用此動態管理視圖來查找緩存的查詢計劃、緩存的查詢文本、緩存計劃佔用的內存量,以及從新使用緩存計劃的計數。一樣咱們還能夠和sys.dm_exec_sql_text聯合起來進一步加工獲取到緩衝最大的前10條SQL。
CACHESTORE_SQLCP—SQL執行計劃(臨時緩存計劃、自動參數化計劃和預編譯計劃)
CACHESTORE_OBJCP—對象計劃(存儲過程、函數、觸發器等執行計劃)
CACHESTORE_PHDR—Bound Trees是在SQL Server中代數化的結構過程,被用於視圖、約束和默認值。
CACHESTORE_XPRO是預約義的系統存儲過程,這裏僅包含實現過程的函數名稱和DLL名稱。
如下SQL用來確認在緩衝區外進行分配了內存的內部組件(即經過多頁分配器請求內存),藉以瞭解內存是否存在壓力。
sys.dm_exec_cached_plans針對 SQL Server 爲了加快查詢執行而緩存的每一個查詢計劃返回一行。能夠用此動態管理視圖來查找緩存的查詢計劃、緩存的查詢文本、緩存計劃佔用的內存量,以及從新使用緩存計劃的計數。一樣咱們還能夠和sys.dm_exec_sql_text聯合起來進一步加工獲取到緩衝最大的前10條SQL。
I/O性能診斷
SQL Server性能很是依賴於I/O子系統。除非你的數據庫適合物理內存,SQL Server常常地會有數據庫頁面進出緩存池。這樣就發生了實質的I/O流量。一樣,在事務被明確的提交前,日誌記錄須要寫入磁盤。SQL Server爲各類目的可使用tempdb,例如存儲中間結果,排序,保持行的版本或其餘。因此好的I/O子系統對於SQL Server性能很是重要。
I/O的性能取決於如下一些方面:
磁盤類型包括IDE、SATA、SCSI、SAS、Fibre Channel drive等類型,其中IDE、SATA通常用在我的電腦上。
同時爲了在數據安全、數據性能和數據容量之間作平衡,又發展出了RAID,RAID是一種把多塊獨立的磁盤按不一樣的方式組合起來造成一個硬盤組,從而提供比單個硬盤更高的存儲性能和提升數據備份技術。RAID主要包括RAID0~RAID7等幾個規範,經常使用的RAID類型爲RAID0、RAID一、RAID5,RAID10。
此外根據鏈接方式不一樣還能夠分爲:Direct Attached Storage(DAS),Storage Area Networks(SAN),Fibre Channel Storage Area Networks,iSCSI Storage Area Networks。
吞吐量和IOPS指標
吞吐量主要取決於陣列的架構,光纖通道的大小以及硬盤的個數。陣列的架構與每一個陣列不一樣,但也都存在內部帶寬,不過在通常狀況下,內部帶寬都設計的很充足,不是瓶頸所在。其次是光纖通道對數據流量的影響,爲了達到1GB/s的數據流量要求,咱們必須使用1GB*8=8GB的光纖卡,也能夠用4塊2GB的光纖卡。實際上是硬盤的個數,能夠參考如下指標計算方式,假設爲了知足1GB的數據流量要求,所必須的磁盤個數。
IOPS(Input/Output Operations Per Second),即每秒進行讀寫(I/O)操做的次數,多用於數據庫等場合,衡量隨機訪問的性能。
決定IOPS的主要取決於陣列的算法、cache命中率以及磁盤個數。Cache命中率取決於數據的分佈、Cache Size的大小、數據的訪問規則,以及Cache的算法。
磁盤的限制,每一個磁盤能處理的IOPS是有限制的,一般狀況下每一個磁盤的最大IOPS是肯定的,好比IDE和SATA硬盤的IOPS大體在100之內(咱們可使用HD Tune工具進行IOPS測試),並且IOPS的測試結果與測試方式(例如隨機讀寫和順序讀寫、讀和寫的比例、傳輸數據庫尺寸的大小、磁盤的數量)有很大關係,儘管如此磁盤的IOPS指標仍是對咱們評估磁盤的壓力和是否可以知足系統的性能需求有着必定的指導意義。
假設如今的業務需求是10000 IOPS,120塊SCSI磁盤,那麼在不一樣的Cache命中率、不一樣的讀寫比例狀況下,不一樣的RAID級別對每塊磁盤的IOPS需求是多少呢?
Raid 0 –每一個磁盤的I/O計算= (讀+寫) /磁盤個數
Raid 1 --每一個磁盤的I/O計算= [讀+(2*寫)]/2
Raid 5 --每一個磁盤的I/O計算= [讀+(4*寫)]/磁盤個數
Raid 10 --每一個磁盤的I/O計算= [讀+(2*寫)]/磁盤個數
此外當吞吐率超過85%時,會出現I/O瓶頸,所以單個磁盤IOPS計算規則爲
((10000*(1-Cache命中率)*讀比例)+10000*寫比例*RAID係數)/磁盤數/0.85
即每塊磁盤的IOPS大約在200左右便可知足RAID0、RAID五、RAID10的要求。
此外,關於SQL Server的部署通常規劃和建議以下:
操做系統和SQL Server單獨構建在RAID1的磁盤鏡像上;出於高速和安全的原則,日誌文件須要單獨安裝在RAID1/RAID10上;tempdb文件最好放在RAID0上,而數據文件出於安全、性能、容量、成本的綜合考慮通常則使用RAID5。
在微軟的technet上有一篇關於存儲的最佳實踐top 10(Storage Top 10 Best Practices)是這麼要求的:
1. 瞭解SQL Server的IO特性和應用系統的IO需求規格。
2. 使用更多/更快的磁盤驅動以獲取良好的性能
3. 不要過分優化存儲,簡單的設計一般可以提供良好的性能和靈活性。
4. 部署前驗證配置。能夠用SQLIO之類的工具模擬測試。
5. 始終把日誌文件放在RAID10/RAID1上。
6. 把日誌文件和數據文件從物理磁盤上隔離。
7. 認真考慮TempDB的數據配置。
8. 在數據文件的數量和CPU的容量之間平衡。
9. 不要忽視SQL Server的基礎。
10.不要忽視存儲的配置
對於SQL Server佔用I/O資源的監控主要集中在磁盤響應時間、隊列長度、磁盤讀寫和傳輸速度上。下面提供了幾種對象、計數器和相應的閾值及描述。
Sys.dm_io_virtual_file_stats可以返回數據和日誌文件的 I/O 統計信息,這也爲咱們從總體上了解各磁盤和數據庫的吞吐量和等待時間有了一個直觀的認識。
sys.dm_io_pending_io_requests則對應SQL Server 中每一個掛起的 I/O 請求,咱們將sys.dm_io_pending_io_requests和Sys.dm_io_virtual_file_stats關聯起來,則能夠查看當前是否有等待的IO,而後進行去定位和識別。