當前位置:編程學習大全網 - 源碼下載 - 如何在SQLServer中分析deadlocktrace

如何在SQLServer中分析deadlocktrace

首先,我們來看壹個簡單的例子。這個大結構非常簡單:

1,process-list顯示兩個進程之間存在死鎖:process60fb88和process 11902 c8。

2.vistim-list顯示進程60fb88被選為受害者。

2.下面的資源列表顯示了兩個進程爭奪並導致死鎖的資源。

[html]查看純文本

& lt死鎖& gt

& lt受害者名單& gt

& ltvictim process id = " process 60 FB 88 "/& gt;

& lt/受害者列表& gt

& lt進程列表& gt

& ltprocess id = " process 60 FB 88 " task priority = " 0 " logused = " 0 " wait resource = " KEY:9:72057597664231424(7506 ff 9 b 7 b 0d)" wait time = " 4376 " ownerId = " 2656658629 " transaction name = " SELECT " last trans started = " 2014-04-09t 23:065433Net SqlClient數據提供程序" hostname = " bodcprodvsql 128 " hostpid = " 10088 " loginname = " PROD \ s-propdata " isolation level = " read committed(2)" xactid = " 2656658629 " current db = " 9 " lock time out = " 4294967295 " client option 1 = " 67108866

& ltexecutionStack & gt

& ltframe proc name = " " line = " 9 " stmt start = " 336 " STM tend = " 874 " SQL handle = " 0x 030009003 d00 da 3a 6087 c 0182 a 200000010000000000 "/>

& ltframe proc name = " " line = " 20 " stmt start = " 1022 " STM tend = " 1206 " SQL handle = " 0x 03000900941f 284 ed 5929 e 00 ABA 2000000010000000000 "/>

& ltframe proc name = " " line = " 9 " stmt start = " 464 " STM tend = " 642 " SQL handle = " 0x 03000 a 006502 e 0715 df 5 af 00 ABA 200000010000000000 "/>

& ltframe proc name = " " line = " 4 " stmt start = " 224 " STM tend = " 420 " SQL handle = " 0x 01000 a 00 b 6 FCA 934509742900 b 00000000000000000 "/>

& lt/execution stack & gt;

& ltinputbuf & gt

DECLARE @logText NVARCHAR(MAX)

EXEC integrated service _ ProcessLatestCommand @ log text OUTPUT

選擇@ logText & lt/input buf & gt;

& lt/process & gt;

& ltprocess id = " process 11902 c8 " task priority = " 0 " logused = " 232 " wait resource = " KEY:9:72057596808265728(ed 2e 944 bef F9)" wait time = " 4379 " ownerId = " 2656658630 " transaction name = " UPDATE " lastranstarted = " 2014-04-09t 2Net SqlClient數據提供程序" hostname = " bodcprodvsql 128 " hostpid = " 1 0088 " loginname = " PROD \ s-propdata " isolation level = " read committed(2)" xactid = " 2656658630 " current db = " 9 " lockTimeout = " 4294967295 " client option 1 = " 67108866

& ltexecutionStack & gt

& ltframe proc name = " " line = " 22 " stmt start = " 1230 " STM tend = " 1496 " SQL handle = " 0x 030009003d 00 da 3a 3fa 6087 c 0182 a 2000000010000000000 "/>

& ltframe proc name = " " line = " 20 " stmt start = " 1022 " STM tend = " 1206 " SQL handle = " 0x 03000900941f 284 ed 5929 e 00 ABA 2000000010000000000 "/>

& ltframe proc name = " " line = " 9 " stmt start = " 464 " STM tend = " 642 " SQL handle = " 0x 03000 a 006502 e 0715 df 5 af 00 ABA 200000010000000000 "/>

& ltframe proc name = " " line = " 4 " stmt start = " 224 " STM tend = " 420 " SQL handle = " 0x 01000 a 00 b 6 FCA 934509742900 b 00000000000000000 "/>

& lt/execution stack & gt;

& ltinputbuf & gt

DECLARE @logText NVARCHAR(MAX)

EXEC integrated service _ ProcessLatestCommand @ log text OUTPUT

選擇@ logText & lt/input buf & gt;

& lt/process & gt;

& lt/process-list & gt;

& lt資源列表& gt

& ltkey lock hob tid = " 72057597664231424 " dbid = " 9 " object name = " " index name = " " id = " lockc 99859500 " mode = " X " associated objectid = " 72057597664231424 " >

& lt所有者列表& gt

& ltowner id = " process 11902 c8 " mode = " X "/& gt;

& lt/owner-list & gt;

& lt服務員名單& gt

& ltwaiter id = " process 60 FB 88 " mode = " S " request type = " wait "/& gt;

& lt/waiter-list >

& lt/key lock & gt;

& ltkey lock hob tid = " 72057596808265728 " dbid = " 9 " object name = " " index name = " " id = " lock 2f 4de 2d 00 " mode = " S " associated objectid = " 72057596808265728 " >;

& lt所有者列表& gt

& ltowner id = " process 60 FB 88 " mode = " S "/& gt。

& lt/owner-list & gt;

& lt服務員名單& gt

& ltwaiter id = " process 11902 c8 " mode = " X " request type = " wait "/& gt;

& lt/waiter-list >

& lt/key lock & gt;

& lt/resource-list & gt;

& lt/deadlock & gt;

以下是詳細分析。

1,受害者列表沒什麽可分析的。

2.進程列表中每個進程的詳細信息非常重要。

wait resource = " KEY:9:72057597664231424(7506 ff 9 b 7 b 0d)"

當前進程正在等待的資源。通常我們可以在資源列表中看到相同的信息。使用以下sql查詢,等待的資源是什麽:

下面用的Hobtid是heap或者b樹id的縮寫。有關詳細信息,請參見sys.partotions的說明。

[sql]查看普通副本

選擇o.name,i.name

從系統分區p

在p.object_id = o.object_id上聯接sys.objects o

在p.object_id = i.object_id上聯接sys.indexes i

並且p.index_id = i.index_id

其中p.hobt_id = 72057597664231

名字名字

-

匹配服務主鍵_匹配者標識

從結果中我們可以知道,等待的資源是壹個表MatchService的主鍵PK_Matcher_ID。再看另壹個進程的waitresource,可以知道等待資源是同壹個表的另壹個索引。到目前為止,我們已經找到了直接導致死鎖的資源。

同時可以看到兩個進程,壹個是x鎖,壹個是s鎖。因此,可以判斷表上的修改語句和查詢語句之間發生了死鎖。

另外,在上面的例子中可以清楚地看到keylock導致的死鎖,所以對應的對象(sys。partitions包含所有分區中每個分區的壹行)可以通過查詢分區來找到。

數據庫中的表和大多數類型的索引。)。但是有時候其他類型的資源也會死鎖,比如pagelock,wait resource = " page:9:1:28440841 "。9是dbid1是fileid28440841是pageid。在這種情況下,使用以下語句查詢相應的資源:

[sql]查看普通副本

DBCC·特雷西恩(3604)

DBCC頁(9,1,28440841)

DBCC溯源(3604)

從返回的元數據中找到對應的objectId:objectId。

3.看看進程中的inputbuf。該標簽表示進程正在運行的語句,因此對於定位死鎖非常重要。但是這裏有壹個問題,比如

在上面的例子中,inputbuf是壹個存儲過程,其中嵌套了很多其他存儲過程,但是inputbuf是用戶直接發送的sql,我們需要找出哪個直接導致死亡。

鎖定語句並進行優化,從而解決或減少死鎖。從此我們有了導致死鎖的語句被inputbuf中的語句調用的信息,導致死鎖的語句壹定是表。

MatchService的修改語句。如果存儲過程很簡單,DBA就能夠找到直接導致死鎖的sql,分析過程到此結束。如果存儲過程很復雜,那麽

需要進壹步分析。

4.現在讓我們仔細看看標記executionStack。ExecutionStack顯示了發生死鎖時inputbuf進行的壹系列調用。

sql .上面的例子中有4個sql。同時,仔細觀察上面的例子可以發現,兩個進程的executionStack是完全壹樣的,所以考察壹個就夠了。此外,

如果procname不為空,則直接獲得sql,但上面示例中的標記為空。

此後,我們希望在executionStack中顯示所有sql。使用下面的sql找出內存中對應sqlhandle的sql。需要註意的是

但是如果死鎖已經過去了壹段時間,sqlhandle可能已經從內存中清除了,此時無法查找。而sqlhandle是

Varbinaryd,所以查詢時不能用引號。

還有壹個有趣的點:和其他編程語言壹樣,棧頂的是最直接的錯誤,後面的錯誤都是錯誤下壹級的錯誤(這個解釋可能有點

亂,寫過代碼的同學都能理解。所以在存儲過程調用前面提到的存儲過程的情況下,executionStack中第壹項是直接導致死鎖的sql,第二項是調試。

加上這個sql的sql,以此類推,最後壹個理論上是inputbuf中的sql。

[sql]查看普通副本

選擇sql_handle作為句柄,

SUBSTRING(st.text,(QS . statement _ start _ offset/2)+1,

((CASE qs.statement_end_offset

當-1時,則DATALENGTH(st.text)

否則qs.statement_end_offset

END-QS . statement _ start _ offset)/2)+1)作為文本

來自sys.dm_exec_query_stats AS qs

交叉應用sys . DM _ exec _ SQL _ text(QS . SQL _ handle)作為st

其中SQL _ handle = 0x 030009003 d00 da 3 fa 6087 c 0182 a 20000010000000000

按sql_handle排序

- -

0x 030009003d 00 da 3a fa 6087 c 0182 a 20000001000000000000 select

TOP 1 @matcherQueueID = lhs。匹配器服務_匹配器隊列_ID,

@ Root Operation UID = Root _ Operation _ UID FROM

MatcherService_MatcherQueue lhs其中lhs。處理狀態

= '匹配'或lhs。Processing_State = 'MATCHED '排序依據

上次執行日期

0x 030009003d 00 da 3 fa 6087 c 0182 a 20000001000000000000

從GEDemo.dbo.OperationLog中選擇Top 1 @ ticket ID = operation log _ ID

其中@ Root Operation UID = Root _ Operation _ UID,Status = 0

按工序排序Log_ID ASC

0x 030009003d 00 da 3 fa 6087 c 0182 a 20000001000000000000

UPDATE matcher service _ matcher queue SET Last _ Execution _ Date =

GETDATE(),其中matcher service _ matcher queue _ ID = @ matcher queue ID

註意,似乎壹個sql_handle有三個語句,因為這三個sql屬於同壹個存儲過程。

如果壹個sql_handle包含許多語句,比如壹個長存儲過程,那麽我們還可以使用壹個強大的信息:在

線條

標簽。該語句顯示了哪個sql直接導致了死鎖。如果壹個語句包含許多表,則需要結合死鎖資源來確定哪個表或。

索引的數據被死鎖。

  • 上一篇:qt助手手機版安卓版Qt助手安卓版
  • 下一篇:為什麽有的人QQ網名字體粗 那是怎麽弄的
  • copyright 2024編程學習大全網