介紹資料庫等待隊列(上)
本篇文章的目的就是為協助DBA,開發人員以及其他與使用資料庫的人員闡述什麼是資料庫等待隊列。
效能最佳化的已經變得越來越重要了,隨著SQL Server 2005推出之後,裡麵包含了很多的動態管理檢視(DMV)和函數,所以,我們很有必要如何使用這些動態管理對象來協助我們進行效能的診斷與排除。
對於效能而已,我們一個最可以感知的現象就是:SQL Server的響應變慢了,而且伺服器的資源開始被不正常的消耗。面對這些問題,分析等待隊列是我們的第一步,只有知道資料庫為什麼慢,為什麼耗費過多的資源,我們才能對症下藥。
在接下來的內容中,將會講述如何分析OLTP應用中的等待隊列。當然,大家在此基礎之上進一步的去研究和深入的學習。
在此之前,我們來看看與效能相關的幾個內容,這樣便於我們後續內容的展開,首先說說什麼是總體的回應時間。
總體回應時間介紹
大家知道,在SQL Server 2000及之前的版本中,我們必須採用很多類似廣撒網的方式來設定很多不同的計數器和工具來捕獲和分析發生效能瓶頸的原因。我們常常使用的工具包括profiler traces,效能計數器,網路嗅探器,還有一些第三方的診斷工具。不可否認,使用這些工具可以協助我們找到問題的癥結,但是所花費的時間和精力都是非常多的。
我們常常會問這樣的問題:資料庫引擎在等待什麼,從而導致效能下降?,其實,當我們使用工具來分析效能問題的時候,就是在試圖去找出這些答案。另外,當我們把問題解決之後,終端使用者最為關注的結果就是:總體的回應時間是多少,或者說,發送的查詢的回應時間是多少。
所謂總體的回應時間,就是發送一個請求之後,一直到接收到響應,這個過程的時間。例如,現在使用者通過應用程式發送了一個請求給資料庫,去擷取資料。那麼總體的回應時間就:
其實,從嚴格的意義上說,總體回應時間還包含資料發送給應用程式之後,應用程式處理資料,展示資料花的時間,但是,我們這裡的重點是研究資料庫的等待,所以,我們就不考慮應用程式方面的時間問題。
下面就言歸正傳,我們來看看等待的問題。
什麼是等待統計資料
採用微軟官方的說法就是:當在SQL Server內部產生 一個請求的時候,由於某些原因,這個請求不能被立刻的處理,於是系統就讓這個請求進入等待的狀態。SQL Server內部的引擎會跟蹤請求等待所花的時間,並且在這些等待的時間基於資料庫執行個體進行彙總,並且把這些資訊儲存在記憶體中。
可能上面的講法有點生硬,我們就舉個簡單的例子。如,當我們運行一個查詢的時候,SQL Server由於CPU或者其他資源被佔用而無法及時的處理我們的查詢請求,那麼此時,我們的請求就必須要等那些資源被釋放之後才能繼續進行。在這段期間,我們的查詢請求就會被掛起,被放在等待隊列中,並且SQL Server內部引擎中回去儲存一些記錄,來標示這個查詢請求的等待類型,或者說,因為什麼而導致了等待。
大家可以看看下面的圖:
藉助這個圖,我們就非常好理解了,我這裡暫時不過過多的解析,以後我們再說。
從上面的討論就可以知道:如果我們可以利用資料庫引擎內部儲存的等待統計資訊來分析,那麼在準確度上面會比之前有很多的改進。
等待類型的分類
既然我們要用內部的等待統計資訊來分析問題,那麼首先就要得知道:到底有哪些等待類型。
在SQL Server中,等待類型有很多,為了便於使用和管理,這些等待類型又是被進行了分類的,所以,下面,我們就來看看等待類型的分類。
說出來可能有點嚇人:在SQL Server內部,可以跟蹤大約400多個等待類型。如此眾多的等待類型,可以讓我們感受到:發生等待的原因真是太多了,如果靠我們自己“小米+步槍”的方式去分析,會花費多少精力。
儘管有如此眾多的等待,其實我們常常用到的,或者我們關注的等待就只有很少的一部分,如那些與資源爭奪相關的等待:CPU,I/O,記憶體等。下面,我們就介紹我們常常使用的四大等待類型的分類:
資源等待(Resource waits):這類型的等待發生的情境是這樣的:當某個背景工作執行緒要去訪問謀一份資源的時候,但是此時,這個資源被其他線程佔用。在這種等待分類中,我們常常看到的典型的,如鎖,閂鎖,和網路。
訊號等待(Signal waits):某個背景工作執行緒在等待CPU可用所花費的時間。在SQL Server中,如果某個背景工作執行緒運行所需要的資源全部已經準備好了,此時,它就要被運行,但是CPU每次只能運行一個線程,那麼,那些已經就緒的背景工作執行緒就會被放在稱之為runnable的隊列中,等待CPU時鐘的到來,然後被運行。此時,可以知道,如果這類的等待時間多長,那麼就說明CPU有壓力,因為要被啟動並執行線程不缺任何的資源,就差被CPU去執行了。
隊列等待(Queue waits):這種分類的等待發生的情境是這樣的:一個背景工作執行緒很閑,等待有任務教給它。那麼,這裡就有一點要說明的就是:在資料庫中,有個背景工作執行緒池,我們的向資料庫發送的每個請求,都是交給背景工作執行緒,然後這些線程去啟動並執行。舉個例子,你要去圖書館借書,在圖書館中有很多的圖書管理員,這些管理員我們就稱之為“背景工作執行緒”。當我們發起一個借書的請求之後,這個請求就被交給圖書管理員,然後由他們去找書。如果圖書館總是沒有人借書,或者借的人很少,那麼這些管理員就閑置。這種類型的等待常常與系統的背後任何相關,可以用來分析死結等情況。
外部等待(External waits):很好理解,當SQL Server背景工作執行緒要等待外部某個事件事件的發生然後才去運行,在事件發生之前就要等待,如採用linked server查詢,需要等到結果過了之後才能繼續進行。
此文為了回複懸賞區中的“介紹資料庫等待隊列".