文章編號: 832524 - 上次校閱: 2007年4月25日 - 版次: 1.6

SQL Server 技術公告-如何解決死結

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中


全部展開 | 全部摺疊

SQL Server 技術資訊公告

這個問題中涵蓋的主題: 如何解決死結

目標

識別、 疑難排解,並建議解決死結的方案。

簡介

本文將探討死結的狀況,並提供步驟說明如何解決死結。每一個死結可能會不同,而且可能會因幾個不同的環境變數。這份文件中提供的資訊可以幫助您找出並解決死結。

案例研究

在一個案例] 研究我們檢查有六個運算子的 911 系統。在尖峰活動期間 Microsoft Visual Basic 前端應用程式正在使用經驗中斷的連線。因為中斷連線的運算子必須 re-input 資料。對於 911 系統運作一天 24 小時,每週,7 天這種行為是不被接受。

死結是什麼?

當兩個時,就會發生死結系統伺服器處理序識別碼 (SPID) 等候資源和兩個處理程序可以前進,因為其他處理序使它無法取得資源。

鎖定管理員 ’s 執行緒會檢查死結。當鎖定管理員 ’s 死結偵測演算法偵測到死結時,鎖定管理員會選擇其中一個 SPID 為犧牲者。鎖定管理員啟始 1205年錯誤訊息,傳送至用戶端,並鎖定管理員殲敵 SPID。殺光 SPID 釋放資源,並允許繼續其他的 SPID。殺光是死結的犧牲者的 SPID 是什麼會導致 Visual 基本前端應用程式經驗的中斷的連線。

在設計良好的應用程式前端應用程式應該為 1205年錯誤補漏白、 重新連線到 SQL Server 並再重新送交易。

雖然死結可以最小化,它們無法完全避免。這就是為什麼前端應用程式應該被設計來處理死結。

如何識別死結

步驟 1

若要識別死結,您必須先取得記錄檔資訊。如果您懷疑死結時,您必須蒐集資訊 (SPID) 以及死結中涉及的資源。若要執行此動作將新增-T1204 和 SQL Server-T3605 啟動參數。若要將這些兩個啟動參數請依照下列步驟執行:
  • 啟動 SQL Server 企業管理員。
  • 選取,然後以滑鼠右鍵按一下 [伺服器]。
  • 按一下 [內容]。
  • 按一下 [啟動參數
  • 在 [啟動參數] 對話方塊輸入 -T1204參數 文字中方塊,然後再按一下 [新增]
  • 在 [參數] 文字方塊中輸入 -T3605,然後再按一下 [新增]。
  • 按一下 [確定]

當停止並再重新啟動 SQL Server 啟動參數會生效。

-T1204 啟動參數會收集處理程序和資訊時死結偵測演算法遇到死結的資源。-T3605 啟動參數將此資訊寫入至 SQL Server 錯誤記錄檔。

-T1205 啟動參數會收集資訊死結演算法會檢查一個死結發生死結時,不為每次。您沒有使用-T1205 啟動參數。

如果您使用了-T1205 啟動參數,下列是會在 SQL Server 錯誤記錄檔的輸出範例:

2003-05-14 11:46:26.76 spid4     Starting deadlock search 1
2003-05-14 11:46:26.76 spid4     Target Resource Owner:
2003-05-14 11:46:26.76 spid4      ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x43CAB580) Value:0x42bdf340
2003-05-14 11:46:26.76 spid4      Node:1       ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x43CAB580) Value:0x42bdf340
2003-05-14 11:46:26.76 spid4     
2003-05-14 11:46:26.76 spid4     End deadlock search 1 ... a deadlock was not found.
2003-05-14 11:46:26.76 spid4     ----------------------------------
2003-05-14 11:46:31.76 spid4     ----------------------------------
2003-05-14 11:46:31.76 spid4     Starting deadlock search 2


有時候,您可能無法停止並重新啟動 SQL Server。在這種情況下您可以使用查詢分析將執行下列命令以啟用死結追蹤旗標。

附註如此一來,您可以立即收集在死結的相關資訊。"-1"表示所有的 SPID。

dbcc traceon (1204, 3605, -1)
go
dbcc tracestatus(-1)
go

步驟 2

接下來,您必須收集 SQL Profiler 追蹤。如果開啟死結追蹤旗標就會出現大部分所需的資訊但不是一定。比方說個案研究中追蹤旗標輸出識別 sp_cursoropen 系統預存程序和一個"UPDATE tblQueuedEvents 設定 notifyid = 3 ResynchDate"陳述式已參與死結。不幸的是,您不知道 sp_cursoropen 系統預存程序的定義。 您也沒有完整的 UPDATE 陳述式因為它已被截斷。

SQL Profiler 可以取得完整的陳述式中,除了陳述式的執行計劃。SQL Profiler 追蹤也有鎖定事件的 「 死結 」,並對於死結鏈結。「 死結 」 對應-T1204 旗標,而 「 死結鏈結 」 對應之-T1205 旗標。開啟死結追蹤旗標和 SQL Profiler 追蹤執行期間的死結發生應可提供您您必須要有疑難排解死結的資料。在這種情況下,並且在其他,執行 SQL Profiler 會變更執行夠,以避免死結的時機。因此,您通常會擷取死結資訊與追蹤] 旗標,然後再執行 SQL Profiler。

疑難排解死結

就會發生死結之後就可以使用 sqldiag 公用程式,並使用 SQL Profiler 收集死結的相關資訊。在 SQLDiag.txt 檔案輸出,尋找一個 「 等候的圖形 」 項目。A"等候-圖形 」 項目表示發生死結。

下列是使用時,可能會看到 SQL Server 錯誤記錄檔中的輸出的範例-T1205 啟動參數。

2003-05-05 15:11:50.80 spid4    Wait-for graph
2003-05-05 15:11:50.80 spid4    Node:1
2003-05-05 15:11:50.80 spid4    ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x33AE1538) Value:0x193
2003-05-05 15:11:50.80 spid4    Victim Resource Owner:
2003-05-05 15:11:50.80 spid4    ResType:LockOwner Stype:'OR' Mode: X SPID:60 ECID:0 Ec:(0x1F1BB5B0) Value:0x193
2003-05-05 15:11:50.80 spid4    Requested By: 
2003-05-05 15:11:50.80 spid4    Input Buf: RPC Event: sp_cursoropen;1
2003-05-05 15:11:50.80 spid4    SPID: 55 ECID: 0 Statement Type: EXECUTE Line #: 1
2003-05-05 15:11:50.80 spid4    Owner:0x1937f2a0 Mode: S        Flg:0x0 Ref:1 Life:00000000 SPID:55 ECID:0
2003-05-05 15:11:50.80 spid4    Grant List 0::
2003-05-05 15:11:50.80 spid4    KEY: 8:1653632984:2 (da00ce043a9e) CleanCnt:1 Mode: U Fl ags: 0x0
 
2003-05-05 15:11:50.80 spid4    Node:2
2003-05-05 15:11:50.80 spid4    ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x33AE1538) Value:0x193
2003-05-05 15:11:50.80 spid4    Requested By: 
2003-05-05 15:11:50.80 spid4    Input Buf: Language Event: Update tblQueuedEvents Set NotifyID = 2, ResynchDate
2003-05-05 15:11:50.80 spid4    SPID: 60 ECID: 0 Statement Type: UPDATE Line #: 1
2003-05-05 15:11:50.80 spid4    Owner:0x1936e420 Mode: X        Flg:0x0 Ref:0 Life:02000000 SPID:60 ECID:0
2003-05-05 15:11:50.80 spid4    Grant List 0::
2003-05-05 15:11:50.80 spid4    KEY: 8:1653632984:1 (2d018af70d80) CleanCnt:1 Mode: X Flags: 0x0


您在 「 等候的圖形"] 項目中有節點 1 及節點 2。在每個節點中,您可以授與區段和要求區段。授與區段是 「 授與清單,」,而要求區段是在 「 要求依 」。
每個節點中可以識別下列作業:
  • SPID。
  • 代表 SPID 正在執行指令。
  • 資源。
  • 在資源上的鎖定模式。

比方說節點 1 授與] 清單中的 SPID 55 必須被授與更新鎖定,模式: 資源 KEY 的 U,: 8:1653632984:2。8 = DBID 1653632984 = ObjectID 和 2 = Indid。若要取得資料庫識別碼,執行 sp_helpdb 預存程序。若要取得資料表,執行下列程式碼:
select * from sysobjects where id = 1653632984


若要取得索引,執行下列程式碼:
select * from sysindexes where indid = 2 and id = 1653632984

如果 IndexId 等於 2,您知道此索引為非叢集索引。SPID 55 已執行的命令已 sp_cursoropen 預存程序。

節點 2 [授與] 清單中的 SPID 60 已授與獨占鎖定模式: 資源 KEY 的 X,: 8:1653632984:1。 8 = DBID 1653632984 = ObjectID 1 = Indid。這是在同一個資料表,但索引 1 是叢集的索引。執行 SPID 60 的命令為:
Update tblQueuedEvents Set NotifyID = 2, ResynchDate

等於 1 的 IndexId 是叢集的索引。

值等於 2 的 IndexId 為非叢集索引。

附註死結是非常機密的時間。

接下來,要求依 [節點] 1 中的 SPID 55 要求共用的鎖定模式: 上 IndexId S = 1。在節點 2 要求者,SPID 60 要求獨占鎖定模式: IndexId 的 X,= 2。因為這些鎖定要求會發生在同一時間,就會發生死結。每個 SPID 授與鎖定會阻礙要求的鎖定,無法繼續。

下表顯示鎖定相容性圖表。如需有關鎖定相容性的詳細資訊,請參閱 SQL Server 2000 線上叢書 》 中的 < 鎖定相容性 > 主題]。

鎖定相容性圖表
摺疊此表格展開此表格
要求模式SUIX六個X
意圖共用 (IS)是的是的是的是的是的
共用 (S)是的是的是的
更新 (U) 是的是的
意圖獨佔 (IX)是的是的
與意圖獨占 (SIX) 共用 是的
獨占 (X)


接下來,藉由查看輸出,識別 ObjectId 1653632984 作為 tblQueuedEvents] 表格,並取得輸出表格的 sp_help 預存程序。在資料表上共有兩個索引。兩個索引已 ix_tblQueuedEventsPK_tblQueuedEventix_tblQueuedEvents ResynchDate 上的叢集的索引,PK_tblQueuedEvent 主索引 EventSID 上唯一的非叢集索引。

SQL Profiler 追蹤程式無法擷取死結發生。請記住死結是非常時間相依。SQL Profiler 的額外負荷可能加入一些時間至其中一個處理程序的執行,並且,就會阻止 SQL Profiler 在死結的情況下取得。不過,它未提供您可用來疑難排解問題的資訊。找到完整的更新 tblQueuedEvents 陳述式會類似下列:

Update tblQueuedEvents Set NotifyID = 2, ResynchDate = '5/7/2003 10:44:16' where eventSID = 73023
您也會發現,執行計劃。您還沒有完整 sp_cursoropen 預存程序陳述式,但您沒有足夠的資訊來建議解決死結的解決方案。

以下是執行計劃。

附註讀取這個特定的執行計劃從右至左、 至上。

StmtText                                                      
				                                                                           
				   
				                                  
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
				
Update tblQueuedEvents Set NotifyID = 2, ResynchDate = '5/7/2003 10:44:16'
				where eventSID = 73023                                                     
				   
				                    
|--Clustered Index
				Update(OBJECT:([SOTS].[dbo].[tblQueuedEvents].[ix_tblQueuedEvents ]),
				SET:([tblQueuedEvents].[NotifyID]=[@1],
				[tblQueuedEvents].[ResynchDate]=[Expr1004]))  
     |--Top(1)                                                                 
				                                                                           
				   
				               
           |--Compute Scalar(DEFINE:([Expr1004]=Convert([@2])))                
				                                                                           
				   
				                
                 |--Index
				Seek(OBJECT:([SOTS].[dbo].[tblQueuedEvents].[PK_tblQueuedEvents]),
				SEEK:([tblQueuedEvents].[EventSID]=[@3]) 

建議您如果要解決死結方案

請注意 UPDATE 陳述式在叢集的索引上執行叢集的索引更新。因此,非叢集索引和叢集的索引必須同時更新。叢集的索引 ix_tblQueuedEvents 且非叢集的索引是 PK_tblQueuedEvents。若要進行更新 UPDATE 陳述式必須取得這兩個索引上的獨佔鎖定。這些兩個索引都是死結中涉及的索引。從檢閱 SQL Profiler 追蹤,您做不會看到在 WHERE 子句中使用 [ResynchDate 任何查詢。所有陳述式非常明確,而且它們用在 WHERE 子句中的 [EventSID。叢集索引的較佳的選擇就是 EventSID。使用此資訊和與客戶討論,我們發現 ResynchDate 索引是舊,且不必要。我們建議客戶在 ResynchDate,放下 ix_tblQueuedEvents 索引,它們讓 PK_tblQueuedEvent 叢集的索引。這解決死結狀況。

這是牽涉到鎖定的死結案例的只有一個範例。死結也可以牽涉到平行處理原則,並牽涉到執行緒。它們可以涉及一、 兩個、 三個,或多個 SPID 及資源。與任何的死結情況中,您必須取得 –T1204 啟動參數輸出和 SQL Profiler 追蹤識別、 疑難排解,並解決死結。死結的狀況會涉及不同的處理程序和資源。因此,解決方案而異從個案。您可以用來解決死結的一般方法包括:
  • 新增和卸除索引。
  • 正在加入索引提示。
  • 修改應用程式存取類似的模式中的資源。
  • 移除像觸發程序交易中的活動。 預設情況下,觸發程序是交易式。
  • 讓交易儘可能縮短。

額外讀取

如需有關的死結的詳細資訊,請造訪下列 Microsoft 網站:

http://msdn2.microsoft.com/en-us/library/Aa213040 (http://msdn2.microsoft.com/en-us/library/Aa213040)

http://msdn2.microsoft.com/en-us/library/aa213042(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213042(SQL.80).aspx)

http://msdn2.microsoft.com/en-us/library/aa213028(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213028(SQL.80).aspx)

http://msdn2.microsoft.com/en-us/library/aa937573(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa937573(SQL.80).aspx)

http://msdn2.microsoft.com/en-us/library/aa213041(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213041(SQL.80).aspx)

這篇文章中的資訊適用於:
  • Microsoft SQL Server 2000 Standard Edition
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:832524? (http://support.microsoft.com/kb/832524/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。