SQL Server 性能調優(內存)


 

 

存儲引擎自調整... 1

sql server 是如何分配內存的... 1

32bit地址空間的限制... 2

用戶模式vas分配和virtualalloc. 3

boffer pool 分配內存(保留內存) 3

VAS調整... 3

AWE. 3

啟動參數-g. 4

診斷內存壓力... 4

內存相關計數器... 4

SQL Server :Buffer Manager. 4

buffer cache hit ratio. 4

page life expectancy. 5

Free Pages. 5

Free list stalls/sec. 5

lazy write/sec. 5

SQL Server:memory Manager. 5

total server memory target server memory. 5

memory grants outstanding. 6

memory grants pending. 6

內存相關的DMV. 6

內存相關問題... 6

分頁問題... 6

因為lock pages 沒有設置服務器最大內存導致系統不穩定... 7

701錯誤和 FAILED_VIRTUAL_RESERVE. 7

多實例下的內存設置... 7

總結... 7

 

內存的分配和使用在網上一直是討論的話題。對sql server 來說使用了內存但是不釋放是很正常的事情,和其他的應用程序是不一樣的,導致一些用戶認為sql server確實內存但事實並非如此。

存儲引擎自調整

sql server 2005開始,內存的管理就是動態的,與其他關系型數據庫不同使用已經調整好的內存空間。如plan cache 是全部的並且自動的,引擎控制根據當前數據庫的負載和其他活動信息來控制plan chache內存。sql server 雖然缺少內存的控制方法,但是還有有參數可以設置內存的,如操作系統的版本,內存的大小和處理器的體系結構。

sql server 是如何分配內存的

第一反應就是查看windows任務管理關於sql server 的內存使用情況,一看到sql server 占用了很大的內存就可能會認為sql server 缺少內存,但是缺少內存和占用很大內存其實是沒什么關系的。sql server是被設計為大內存使用的,如buffer cache,存放了大量的數據頁,為了減少io,提高性能。通常,不管你提供了多少內存sql server 都能使用光,除非你接到一個來自操作系統的memory low通知,sql server 就會自動調節減小內存,通知有2中:

memory high:通知sql server可以增加內存的使用量

memory low:通知sql server 釋放內存

如果windows 不通知,那么sql server 就不會增加或減少內存,在windows 2003 sql server 2005 以前的版本是沒有的。有一篇關於sqlos中內存的文章介紹了不同類型的內存壓力,大致如下:

 

 

文章地址:http://blogs.msdn.com/b/slavao/archive/2005/02/01/364523.aspx

sql server 最大內存使用量由以下幾點要素:

1.安裝的物理內存數量

2.操作系統的最大內存限制

3.sql server 體系結構,32b64b

4.sql server 配置項

5.sql server 版本



32bit地址空間的限制

對於sql server 32位最大的影響就是32位的地址空間,也就是最大4g而且包含內核模式和用戶模式。用戶模式和內核模式各2g。主要我們討論一下幾點

1.sql server 用戶模式如何分配內存

2.buffer pool的保留空間

3.用戶模式使用3g 內存

4.sql server 如何使用大於4g內存,data cache調用awe內存。

接下來主要講的都是32bit 下內存使用的限制和64bit關系不大。

用戶模式vas分配和virtualalloc

sql server 為用戶默哀是保留了2g的內存地址,sql server 用戶模式需要內存時,通過調用virtualalloc 分配內存並返回32位的指針,因為地址空間的限制,所以sql server 只能使用2g內存。

通過virtualalloc分配的內存並不一定是實際的物理內存,不管安裝了多少物理內存,sqlserver都是2g的地址使用空間。windows也保證sql server 和其他應用程序使用的內存,不會超過實際物理內存和頁面文件的總容量。如果總共安裝的內存少於2g,那么sql server 就會又物理內存的限制,sql server buffer pool的內存也不會超過安裝的內存數量。virtualalloc 分配的內存都是頁模式的,也就是如果出現內存壓力windows 就可以直接把內存寫入到磁盤中。

boffer pool 分配內存(保留內存)

如果sql server 請求大於8k的連續內存的時候,會使用多頁分配器分配內存。backup buffers 是非buffer pool分配的最大的一個,需要的內存是 maxtransfersize * backupbuffercount 在正常的備份下,需要16backup buffer,每一個buffer4m的內存。所以會吃掉64m的非buffer pool 內存。為了保證有住夠非buffer pool32bsql server 在啟動的時候會保留一部分內存。一旦有保留內存,那么buffer pool的內存空間會是安裝的空間減去保留的空間。對於20052008保留空間為 maxworkerthreads*0.5mb+256mb(默認保留空間大小)maxworkerthreads = processprcount-4+256。在2000 maxworkerthreads = 256,按這個計算保留空間至少是384MB,但是通常少於432mb。保留空間的參數在sql server 啟動參數內設置,標記為-g,可是適當在計算出來的結果上增加內存。sql server 一共2g的地址空間減去保留的,大概剩下1.6Gbuffer pool 使用。對於超過4gb的內存可以使用awe來分配內存。

VAS調整

對於4g的內存,系統可以修改內核的地址空間使用率把1:1,變為1:3。這個叫做4g調整,這樣就減少了內核模式下的地址空間,導致了PTE減小,pte是虛擬內存和物理內存的映射,一但減小,sql server 總共可使用的內存也就背減少了。所以在調整的時候要謹慎。在windows 2008下可以使用bcdedit /set 命令設置increaseuserva 可以設置從 2048 3072的值。在2000 2003 可以使用/3g的標簽來開啟。

AWE

如果安裝了超過了4個的內存,那么就可以使用awe,當然windows 必須支持才能使用。開啟pae,系統最多能夠使用64G內存。在內存分配上因為使用virtualalloc分配內存會有限制,那么就改用allocateuserphysicalpage來分配內存,一旦被分配那么內存頁被鎖住,無法交換到交換文件。當啟用awe后所有的datacache使用過awe分配內存還有就是 plancache也是。要啟用awe那么pae就必須被設置,還有在sql server awe enabled 參數sql server 的啟動用戶必須有lock pages 權限。因為awe內存無法被交換出去,所以設置最大內存數量很偶必要,使得sql server 內存使用量得到限制,不會無限期的增長影響其他應用程序和系統內存的使用問題。在系統中如果你的內存少於16g,你可以使用前面提到的awe+4gt的方式,但是不推薦因為如果你一旦設置了4gt,windows 可管理內存從64g下降到了16g yinwei 4gt減少了pte的大小。

啟動參數-g

sql server 啟動的時候會分配一部分保留內存,保留內存對buffer pool 來說是比較小的。很多的內存是從buffer pool上分配而不是從保留空間中分配,因此基本上不會有問題,但是隨着日積月累應用程序變的越來越復雜,默認的保留空間已經無法滿足需求那么就通過-g參數配置。因為不合適的空間大小和保留空間的碎片問題,導致無法請求到連續的內存空間。查看sys.dm_os_virual_address_dump 動態性能視圖可以查看可用的虛擬地址空間。關於確定可用地址空間可以看相關文章:http://sqlblogcasts.com/blogs/christian/archive/2008/01/07/sql-servermemtoleave-vas-and-64-bit.aspx

保留空間的碎片問題是最難處理的,如果你打電話到微軟技術支持,他們給的建議就是升級到64b,因為64b的虛擬地址空間是8t,不會不夠如果你不想那么就加大你的保留空間地址。

 

診斷內存壓力

sql server 內存不足的時候,那么data cache 存儲的數據就少,查詢不能在內存中請求到數據,那么就請求io,放入內存,這些數據又很快的被清出內存,需要的時候有繼續從io讀進來,這個就是buffer pool 滾筒。buffer pool 滾筒會照成io過高,就會誤認為是io的問題,其實是內存不足的問題。

內存相關計數器

有一些重要等待和內存使用率相關的性能計數器,但是要記清楚並沒有一個計數器就能夠表明內存壓力的,一個簡單的計數器快照並不能說明問題。內存壓力的診斷需要一段時間的跟蹤。

SQL Server :Buffer Manager

又很多有用的計數器都是這 buffer manager 對象下面,可以幫助發現buffer pool滾筒的問題。

buffer cache hit ratio

buffer cache hit ratio一般情況下在oltp中要高於95%,在olap中要高於90%。可惜的是沒有關於這個性能指標相關的解釋,和這個值是如何影響預讀機制的。如果這個指標的值有巨大的下降那么就說明有問題。這個不能說明內存壓力和sql server 健康指數。

page life expectancy

page life expectancy是頁生命周期,也就是一個數據頁在內存中的時間。在以前sql server 2000 4g的內存已經很大了,sql server buffer pool的大小是1.6g,如果sql server 從磁盤上讀取1.6g的數據也只要5分鍾,但是今天64g的內存是主流,如果從磁盤一下子讀取50g的內存,會嚴重的沖擊io。當存在大量的查詢掃描表,讀入新的數據頁,導致生命周期值下降也不是不正常的。這個值必須長期的監視來分析問題。

Free Pages

free pages是內存中空頁的數量,不要接近於0。這個值說明查詢能否在其他查詢不是放內存的情況下,快速的分配內存的主要依據。如果free pages 很少,頁生命周期很短,並且伴隨着空頁爭用(free list stalls/sec)的情況那么很有可能導致內存壓力。

Free list stalls/sec

Free list stalls/sec每秒空頁等待的數量,如果一段時間內都在0以上那么說明可能存在內存壓力。

lazy write/sec

lazy write/sec 就是每秒寫入磁盤的次數。如果發生量很大並且生命周期很短,free page 很少,但是 free list stall/sec 量很大,那么就是發生內存壓力了。



SQL Server:memory Manager

SQL Server:memory Manager對象內對內存的消費和內存管理的問題提供了很重要參考

total server memory target server memory

2個計數器代表了當前sql server 使用的總共內存和sql server 想要用的內存。如果 target server memory超過了total server memory,也是內存壓力的重要標志。sql server 會減少內存的需求來接近服務的可用內存,或者通過最大服務器內存配置,所以當內存出現壓力問題的時候不應該第一時間去查看這2個計數器

memory grants outstanding

該值是現實多少進程已經成功的獲取了內存的授權。在一段時間內,業務高峰期,如果該值過低,那么標志可能存在內存壓力,特別是 memory grants pending 也比較高的情況下。

 memory grants pending

該值是有過少進程正在等待內存的授權。如果為非0,那么說明需要調整或者優化負載或者增加內存。

 

內存相關的DMV

和內存相關的等待和非buffer pool 內存分配的信息,從dmv中獲取。

sys.dm_exec_query_memory_grants 可以查看正在等待授權的查詢,特別是大內存的授權

sys.dm_os_memory_cache_counter multi_pages_kb 顯示了多頁分配的內存分配

sys.dm_os_sys_memory 合計了系統當前內存,緩沖,cache,多頁分配分配的內存。

sys.dm_os_memory_clerks 顯示相關管理內存的書記進程,如 buffer pool 大內存的使用並且結合 MEMORYCLERK_SQLQERESERVATIONS 可以發現buffer pool 內存不住

 

內存相關問題

通常的一些問題可以被分為3種:錯覺,錯誤配置,正在的問題。大量的疑似內存問題的最后其實只有一小部分才是真正的問題。

分頁問題

sql server 重要的組件被page out了,會在error log 中出現一個信息a significant part of SQL Server process memory has been paged out對於 worksettrim通常是下列的情況:

1.當沒啟用lock pages的時候,不正確的最大服務器內存的設置

2.windows 中系統緩沖,被用來處理非緩存的io操作,如復制文件。

3.硬件驅動問題導出使用過多的內存。

最有效的阻止方法是,開啟lock pages,文章:http://support.microsoft.com/kb/918483講述了64b sql server 發生workset trim的根本原因。

 

因為lock pages 沒有設置服務器最大內存導致系統不穩定

如果sql server開啟了 lock pages 但是 最大服務服務內存又沒設置,sql server 會吃光所有的服務器的可用內存。當windows 內存緊張會向通知sql server 內存壓力,但是buffer pool working set 都不會被交換頁面文件。這樣會導致windows crash。如果最大內存數設置的過大也會造成同樣的情況。

 

701錯誤和 FAILED_VIRTUAL_RESERVE

sql server 申請一個連續的vas失敗,就會返回701錯誤和答應出需求大小的信息。這個錯誤只會發生在32bsql server32b sql server vas十分有限。這個錯誤和buffer pool 沒有什么關系主要是大於8k內存分配的時候出現。解決辦法就是使用-g啟動參數,修改sql server保留空間。

 

多實例下的內存設置

sql server 如果多實例安裝在單個機器上或者一個故障轉移能減少license的購買。當一台服務器上有多個實例,那么設置min_server_memory max_server_memory 很重要,根據每個實例的負載,避免出現內存沖突的情況。根據先前提到過的性能指標和dmv 對內存使用情況監測,設置一個合理的最大內存和最小內存數。在多實例情況下,建議把最小內存數也設置上,因為如果有最小內存數,那么sql server 申請內存的時間會減少。如果最小內存數沒有設置,sql server 可能會自願減少內存的使用率而導致性能下降。

 

總結

在內存上面 32b 64b 又很大的不同,如果負載較高那么就是用64b6號那天sql server 2012發布,還沒去看聯機文檔,但是聽朋友說201232b不在支持awe,也就是說如果大內存那么就用64b64b內存方面很有優勢。這篇主要講了內存的狀況,總結到這里我已經明顯的感覺到,常見問題遠沒有原理來的重要。troubleshooting只是原理的一種應用而已。關於資源的都講完了,cpu,內存,io,下一篇會講講miss indexmiss index 也是會引起 cpu,內存,io 的異常狀況。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM