sqlserver阻塞定位

很多人都遇到過這樣的情況,當網站達到一定的訪問量,數據庫就會成爲瓶頸,進而引起阻塞。

有人認爲這可能就是硬件的極限了,於是想辦法增加硬件設備。而我本人認爲問題的元兇可能是性能不高的sql腳本,引起了阻塞。

如果你和我有相同的看法,那我們就一起想辦法找出問題的源頭。

案例1.

某一天我被告知,我們的書城網站不能訪問了,我馬上查看,發現書城的有兩臺iis服務器均顯示service unavailable,我初步斷定是sqlserver數據庫發生了阻塞,因爲同一套程序使兩臺iis服務器同時當機的可能性不大。

要知道是否發生了阻塞,當然要看master庫的sysprocess表,看看是否有什麼進程堵住了別的進程,語句如下:

Select * from master..sysprocesses where blocked > 0

很快我發現,有一個blocked = 51 堵住了很多進程(查看blocked列可見),果然和我的判斷吻合;爲了進一步找出發生阻塞的語句,我用到的如下的語句

dbcc inputbuffer(51);

結果如下:

EventType      Parameters            EventInfo            

------------------------------------------------

RPC Event      0                          p_Book_content;1

從上面就可以看出是p_Book_content (是個存儲過程)引起的阻塞,但是這個過程裏面同時對多個表進行了操作,到底是那個語句出了問題呢?

下面我們再來進一步定位阻塞的位置:

Sp_lock

結果如下(大部分數據略)

Spid        dbid        objid              indid       type   resource   mode      status

-------------------------------------------------------------------------------------------------

51           14           206623779     0         TAB                    X            WAIT

52           14           0                   0            DB                       S            GRANT

53           14           0                   0            DB                       S            GRANT

。。。

。。。

。。。

現在我們來看看spid = 51 這行, mode = X 表示排它鎖, status = WAIT表示正在等待(即被阻塞了),dbid = 14 是數據庫的id,objid = 206623779 是被鎖的對象id,我們可以通過下列函數得到數據庫和表:

Select db_name(@dbid) -----》book_db

select object_name(@objid) -------》 t_book

即book_db庫的t_book表被鎖住了,這時候再回投仔細檢查 p_Book_content 存儲過程,發現只有一個語句對t_book進行了操作:

update t_book set hitcount = hitcount + 1 where bookid = @bookid

這個語句的作用是更新書本的點擊次數,爲什麼上面這個語句會引起阻塞呢?我認爲最可能的情況應該是同時訪問的人過多,同時對錶進行過多的update操作引起的,所以最終改用別的方式,不再實時對t_book表進行update操作,而是每次訪問都先insert一條記錄到一箇中間表中,然後再用一個作業,每隔10分鐘定時更新書本的點擊次數,如此改進之後,此問題終於圓滿解決了。

相關資料在book online可以找到, 關鍵字: sp_lock , sysprocesses , dbcc inputbuffer , db_name(), object_name()

 注:原來發在csdn的,現在荒蕪了,挪到這邊來栽培一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章