SQL Server 性能調優(一)——從等待狀態判斷系統資源瓶頸


經過DMV查看當時SQL SERVER全部任務的狀態(sleeping、runnable或running)

200五、2008提供瞭如下三個視圖工詳細查詢:

DMV
    

用處

Sys.dm_exec_requests
    

返回有關在SQL Server中執行的每一個請求的信息,包括當前的等待狀態

Sys.dm_exec_sessions
    

對於每一個經過身份驗證的會話都返回相應的一行。此時圖是服務器範圍的視圖。此視圖首先能夠查到服務器負荷

Sys.dm_exec_connections
    

返回與SQL Server 實例創建的鏈接有關的信息以及每一個鏈接的詳細信息

 

Sys.sysprocesses是爲了向後兼容,因此建議使用以上3個DMV。

 

另外還有一個DMV:sys.dm_os_wait_stats能夠返回從SQL Server啓動以來全部等待狀態的等待數和等待時間。是個累積值。

 

一、  LCK_XX類型:

若是SQL Server常常有阻塞發生,會常常看到以「LCK_」開頭的等待狀態:

等待狀態
    

說明

LCK_M_BU
    

正在等待獲取大容量更新鎖(BU)

LCK_M_IS
    

等待獲取意向共享鎖(IS)

LCK_M_IU
    

等待獲取意向更新鎖(IU)

LCK_M_IX
    

等待意向排它鎖(IX)

LCK_M_RIn_NL
    

等待獲取當前鍵值上的NULL鎖以及當前剪和上一個鍵之間的插入範圍鎖

LCK_M_RIn_S
    

等待獲取當前鍵值上的共享鎖以及當前鍵和上一個鍵之間的插入範圍鎖

LCK_M_RIn_U
    

等待獲取當前鍵值上的更新鎖以及當前鍵和上一個鍵之間的插入範圍鎖

LCK_M_RIn_X
    

等待獲取當前鍵值上的排他鎖以及當前鍵和上一個鍵之間的插入範圍鎖

LCK_M_RS_S
    

等待獲取當前鍵值上的共享鎖以及當前鍵和上一個鍵之間的共享範圍鎖

LCK_M_RS_U
    

等待獲取當前鍵值上的更新鎖以及當前鍵和上一個鍵之間的共享範圍鎖

LCK_M_RX_S
    

等待獲取當前鍵值上的共享鎖以及當前鍵和上一個鍵之間的排他範圍鎖

LCK_M_RX_S
    

等待獲取當前鍵值上的共享鎖以及當前鍵和上一個鍵之間的排他範圍鎖

LCK_M_RX_U
    

等待獲取當前鍵值上的更新鎖以及當前鍵和上一個鍵之間的排他範圍鎖

LCK_M_RX_X
    

等待獲取當前鍵值上的排他鎖以及當前鍵和上一個鍵之間的排他範圍鎖

LCK_M_S
    

等待獲取共享鎖

LCK_M_SCH_M
    

等待架構修改鎖

LCK_M_SCH_S
    

等待獲取架構共享鎖

LCK_M_SIU
    

等待共享意向更新鎖

LCK_M_SIX
    

等待獲取共享意向排他鎖

LCK_M_U
    

等待更新鎖

LCK_M_UIX
    

等待更新意向排他鎖

LCK_M_X
    

等待排他鎖

二、  PAGEIOLATCH_X與WRITELOG:

在緩存池中的數據頁面,爲了同步多用戶併發,SQL Server會對內存的頁面加鎖。不一樣的是,加的是latch(輕量級的鎖),而不是lock。

若是發生PAGEIOLATCH類型的等待時,SQL Server必定是在等待某個I/O動做的完成。若是常常出現這類等待,說明磁盤速度不能知足要求,已經成爲SQL Server的瓶頸。

PAGEIOLATCH_X最多見的分兩大類:PAGEIOLATCH_SH和PAGEIOLATCH_EX,PAGEIOLATCH_SH:常常發生在用戶正想要訪問一個數據頁面,而同時SQL Server卻要把頁面從磁盤讀往內存。說明內存不夠大,觸發了SQL Server作了不少讀取頁面的工做,引起了磁盤讀的瓶頸。此時是內存有瓶頸。磁盤只是內存壓力的副產品。

PAGEIOLATCH_EX:常常發生在用戶對數據頁面作了修改。SQL Server要向磁盤迴寫的時候。意味着寫的速度跟不上。這和內存沒直接關係。

WRITELOG:和磁盤有關的另外一個等待狀態,正在等待寫日誌記錄,意味着寫入速度也明顯跟不上。

三、  PAGELATCH_X:SQLServer爲了解決在插入數據時,到了物理層的插入衝突,因此引入了另外一類頁面上的latch:PAGELATCH,當一個任務要修改頁面時,它必須先申請一個EX的latch。只有獲得這個,才能修改頁面的內容。因爲數據頁的修改都是在內存中完成,因此時間應該很是短,能夠忽略不計。而PAGELATCH只是在修改過程當中纔出現,因此生存週期應該很短,若是出現了,說明:一、SQLServer沒有明顯的內存和磁盤瓶頸。二、應用程序發來大量的併發語句在修改同一張表。而設計及用戶業務邏輯使得這些修改都集中在同一個頁面,或者數量很少的幾個頁面,成爲Hot Page,一般在OLTP系統上出現比較多。三、這種瓶頸沒法經過提升硬件配置解決,只能經過修改表設計或者業務邏輯,讓修改分散,提升併發性。

對於Hot page的緩解方法:

(1)、換一個數據列建彙集索引,而不要在Identity的字段上,同一時間插入有機會分散到不一樣的頁面上。

(2)、若是必定要在Identity的字段上建彙集索引,建議在其餘某個列上建若干個分區。

四、  Tempdb上的PAGELATCH:

數據庫不只在數據頁面修改的時候加latch,在數據文件的系統頁面上,例如SGAM、PFS和GAM頁面發生修改的時候,也會加latch。有時候也會成爲系統瓶頸。

在建立新表須要分配空間時,SQLServer同時要修改SGAM、PFS和GAM頁面,把已分配的頁面標誌成已使用,因此這些頁面都會有所修改。但在tempdb中,這種操做會併發、反覆。數據頁的hot能經過調整表設計來緩解。對此的解決方法:

一、  創建與cpu數量相同的tempdb文件,而且大小要相同,這樣能平均分配壓力。

二、  嚴格防止tempdb空間用盡。防止自動增加時把其中一個文件增加,破壞平均分配。

三、  可使用sp_helpfile來查看文件信息。

五、  其餘資源等待:

一、  LATCH_X:

(1)、某個先前的任務出現了訪問越界異常,SQLServer強制終止了任務,可是沒有徹底將它申請的資源釋放乾淨。使其成爲孤兒。後面的資源就被阻塞。只要打開SQLServer日誌文件(errorlog),看看有沒有出現過Access Violation問題,可是通常沒法從用戶層面通常沒法解決,只有重啓服務器才能解決。

(2)、同時發生其餘資源瓶頸,如內存、線程調用、磁盤等,而latch等待只是一個衍生的等待。

(3)、當某個數據文件空間用盡,作自動增加的時候,同一個時間點只能有一個用戶任務能夠作文件自動增加動做,其餘任務必須等待。

(4)、在一些特殊狀況下,有多是SQLServer本身沒有處理好併發同步,沒有使用比較優化的算法,使得用戶比較容易遇到等待,一些補丁就曾修復過這類問題。

通常等待都是由其餘問題衍生出來,首先要檢查SQLServer是否健康運行。是否有出現過任何異常。是否有其餘資源瓶頸。

二、  ASYNC_NETWORK_IO(NETWORK_IO:2000的叫法):

此等待狀態出如今SQLServer已經把數據準備好,可是網絡沒有足夠的發送速度跟上,因此SQLServer的數據沒地方存放。

(1)      出現這種狀況通常不是數據庫的問題,調整數據庫配置不會有大的幫助。

(2)      網絡層的瓶頸固然是一個可能的緣由:對此要考慮是否真有必要返回那麼多數據?

(3)      應用程序端的性能問題,也會致使SQLServer裏的ASYNC_NETWORK_IO等待。若是見到了這個類型的等待,就要檢查應用程序的健康情況,也要檢查應用是否有必要想SQLServer申請這麼大的結果集。

三、  和內存有關的等待狀態:

當用戶任務申請內存暫時申請不到的時候,會出現一些特殊的等待狀態:

COEMTHREAD/SOS_RESERVEDMEMBLOCKLIST/RESOURCE_SEMAPHORE_QUERY_COMPLIE

若是在DMV上看到這些狀態,就要確認SQLServer是否存在內存瓶頸。

四、  SQLTRACE_X:

對於繁忙的SQLServer,開啓SQL Trace會產生負面影響。若是出現這種等待,除非無可奈何,否則應該馬上中止蒐集SQL Trace

六、  最後一道瓶頸:許多任務處於runnable狀態:

若是出現這種狀態,證實不少任務能夠運行但沒在運行。

Sys.dm_exec_requests/sys.sysprocesses的status列,反映了當前全部任務的狀態,若是看到好多狀態是runnable,那就要嚴肅對待,正常的SQLServer哪怕很是忙,也不該該常常看到runnable,連running的狀態都不該該不少。

若是沒有報17883/17884之類的警告,出現很是多的runnable任務可能有兩種緣由:

(1)、SQLServer CPU使用率接近100%,真的沒有足夠的cpu來及時處理用戶的併發任務。此時應該優化最耗CPU資源的語句或者應用,或者加CPU

(2)、SQLServer CPU使用率並不高,小於50%。這時檢查sys.dm_exec_requests的task_state列,會發現不少runnable狀態。由於SQLServer除了lock和latch以外,還有一種更輕量級的同步資源:spin lock(自旋鎖)。自旋:一些不會發生長時間等待的同步資源,SQLServer會選擇讓線程在cpu上稍微等待一下,而不會將cpu資源讓出來。

可使用DBCC SQLPERF(SPINLOCKSTATS)查看。

在2005上的64位SQLServer,當內存比較充裕時,會緩存不少執行計劃,同事緩存不少執行計劃安全上下文。在memory clerk裏,用TokenAndPermUserStore表示,當這段內存比較大時,併發用戶會容易遇到一種叫MUTEX的自旋鎖。能夠參考:http://suppot.microsoft.com/kb/927396。這種問題只在安全上下文緩存得太多時才容易發生,因此按期執行一下如下語句有效防止,並且對系統總體性能也沒什麼壞的影響:

DBCC FREESYSTEMCACHE(TokenAndPermUserStore)

也能夠以-T4618和-T4610啓動SQLServer,讓SQLServer使用另外一種緩存管理機制。

聽說2008已經改進,不容易出現自旋鎖。

七、  小結:

用戶請求的什麼週期:

一、  客戶端向SQLServer發出請求指令,通過網絡層,SQLServer接收到。

在這一步中,若是指令比較長,或者比較多,會影響SQLServer接受的速度。

二、  SQLServer對收到的指令進行語法、語義檢查,編譯,生成新的執行計劃,或者找到緩存的計劃重用:這一步耗費資源的種類比較多:

l  CPU:作檢查、編譯、生成計劃都須要計算,這一步耗費CPU資源比較多,尤爲是指令複雜的時候。

l  內存:對於很是長的IN子句或者由幾萬、幾十萬語句組成,要花費很是大的內存,主要使用stolen內存,對於32位系統來講是很緊張的。通常會出現這些等待狀況:CMEMTHREAD/SOS_RESERVEDMEMBLOCKLIST/RESOURCE_SEMAPHORE_QUERY_COMPILE,或者701錯誤。

l  表上的架構鎖(schema lock):在編譯時,要防止對該架構進行修改。若是併發很高,那麼會產生阻塞。

l  在SQLServer確認是否有線程的執行計劃可用時,要在內存中進行搜索。可能會產生自旋鎖。

三、  運行指令:

在等到執行計劃以後,就進入運行階段,用到的資源最多。在這一步要作不少事情:

(1) 、SQLServer首先爲指令的運行申請內存。

若是同時須要執行不少指令,可能會在內存上遇到困難,一般會見到:RESOURCE_SEMAPHORE_開頭的等待狀態。

(2) 、若是發現要訪問的數據不在內存中。

要講數據從磁盤讀到內存,若是發現內存沒有足夠的空閒頁面存放全部數據,還要作內存整理和paging動做,騰出足夠的空間放數據。一般簡單的等待狀態是:PAGEIOLATCH_X。

(3) 、按執行計劃,掃描或者seek內存中的數據頁面,講執行須要處理的記錄找出來。這一步須要申請各類各樣的鎖,以實現事務隔離。一般會引發阻塞,以LCK_開頭的那些。

(4) 、指令可能還要作一些鏈接或者計算工做(sum、max、sort等)

            這一步主要使用CPU。

(5) 、根據指令內容、執行計劃和數據量,SQLServer可能還會在tempdb建立一些對象,存放臨時表、表變量,幫助作join、sort等。

此時有可能出現tempdb瓶頸。

(6) 、若是指令須要修改數據記錄,SQLServer會修改內存緩衝區裏的頁面內容。

因爲對象在內存中,不會觸發磁盤寫入,但因爲修改同一頁面,容易致使PAGELATCH_X的等待狀態。

(7) 、若是指令發生數據修改,在提交事務以前,SQLServer必須將相應的日誌記錄按照順序寫入日誌文件。若是瞬間日誌量太大,會出現WRITELOG的等待狀態。

(8) 、將結果集返回給客戶端:獲得結果後,SQLServer會把結果集放到輸出緩存中,等客戶端把結果集所有取走。指令才結束。若是數據集太大,會致使網絡交互太多。此時容易出現:ASYNC_NETWORK_IO等待狀態。

以上的動做都要在SQLOS中首先獲得一個Worker/thread,而後還要排上scheduler,在CPU上運行。

l  SQLServer全部的Worker都在忙本身的事情,就會等待,能夠看到等待狀態是0x46(UMSTHREAD)。而sys.dm_os_schedulers.work_queue_count的值會不等於0

l  成功拿到worker,但在scheduler又要等待其餘Worker,這時看到狀態是runnable,而sys.dm_os_schedulers.runnable_tasks_count>1。

l  拿到scheduler,進入running狀態,若是很是耗CPU,會出現cpu使用率高的現象。

l  遇到性能問題,查看sys.dm_exec_requests這類DMV對找到問題頗有幫助。
---------------------
做者:發糞塗牆
來源:CSDN
原文:https://blog.csdn.net/dba_huangzj/article/details/7607844
版權聲明:本文爲博主原創文章,轉載請附上博文連接!算法

相關文章
相關標籤/搜索