捕獲和記錄SQL Server中發生的死鎖

2021-09-07 21:57:31 字數 3812 閱讀 3402

經帶在論壇上看到有人在問怎麼捕獲和記錄死鎖資訊,在這裡,我將自己的一些心得貢獻出來,與大家分享,也請各位指正。

我們知道,可以使用sql server自帶的profiler工具來跟蹤死鎖資訊。但這種方式有乙個很大的敝端,就是消耗很大。據國外某大神測試,profiler甚至可以佔到伺服器總頻寬的35%,所以,在乙個繁忙的系統中,使用profiler顯然不是乙個好主意,下面我介紹兩種消耗比較少的方法。其中第二種的消耗最小,在最繁忙的系統中也可使用。第一種最為靈活,可滿足多種應用。

方法一:利用sql server**(alert+job)

具體步驟如下:

1.首先使用下面的命令,將有關的跟蹤標誌啟用。

sql code

dbcc traceon (3605,1204,1222,-1)

說明:3605 將dbcc的結果輸出到錯誤日誌。

1204 返回參與死鎖的鎖的資源和型別,以及受影響的當前命令。

1222 返回參與死鎖的鎖的資源和型別,以及使用了不符合任何 xsd 架構的 xml 格式的受影響的當前命令(比1204更進一步,sql 2005及以上可用)。

-1 以全域性方式開啟指定的跟蹤標記。

以上跟蹤標誌作用域都是全域性,即在sql server執行過程中,會一直發揮作用,直到sql server重啟。

如果要確保sql server在重啟後自動開啟這些標誌,可以在sql server服務啟動選項中,使用 /t 啟動選項指定跟蹤標誌在啟動期間設定為開。(位於sql server配置管理器->sql server服務->sql server->屬性->高階->啟動引數)

在執行上面的語句後,當sql server中發生死鎖時,已經可以在錯誤日誌中看到了,但還不夠直觀(和其它資訊混在一起)。(ssms -> sql server例項 -> 管理 -> sql server日誌)

2.建表,存放死鎖記錄

sql code

use[cole]--cole是我的示例資料庫,你可以根據實際情況修改。 gocreatetable deadlocklog ( id intidentity (1, 1) notnull, logdate datetime, processinfo varchar(10), errortext varchar(max) ) go

3.建立job

新建乙個job(假設名稱為deadlockjob),在"步驟"中新建一步驟,隨便寫乙個步驟名稱,資料庫為"cole"(見2.建表),在"命令"欄中輸入以下語句:

sql code

--新建臨時表 ifobject_id('tempdb.dbo.#errorlog') isnotnulldroptable #errorlog createtable #errorlog (id intidentity (1, 1) notnull, a datetime, b varchar(10), c varchar(max)) --將當前日誌記錄插入臨時表 insertinto #errorlog exec master.dbo.sp_readerrorlog --將死鎖資訊插入使用者表 insert deadlocklog select a, b, c from #errorlog where id >= (selectmax(id) from #errorlog where c like'%deadlock encountered%') droptable #errorlog

4.新建警報

在"新建警報"窗體的"常規"選項卡中,進行以下設定:

名稱:可根據實際自行命名,這裡我用deadlockalert

型別:選擇"sql server效能條件警報"

物件:sqlserver:locks

計數器:number of deadlocks/sec

例項:_total

計數器滿足以下條件時觸發警報:高於

值:0設定完成後,應該如下圖所示:

在"響應"選項卡中,選中"執行作業",並選擇步驟3中我們新建的作業(即deadlockjob)

到這裡為止,我們已經完成了全部步驟,以後,你就可以隨時查詢deadlocklog表,來顯示死鎖資訊了。

方法二:利用伺服器端跟蹤。

具體實現步驟如下:

1.編寫如下指令碼,並執行

sql code

-- 定義引數 declare@rcintdeclare@traceidintdeclare@maxfilesizebigintset@maxfilesize=5-- 初始化跟蹤 exec@rc= sp_trace_create @traceid output, 0, n'e:\dblog\deadlockdetect', @maxfilesize, null--此處的e:\dblog\deadlockdetect是檔名(可自行修改),sql會自動在後面加上.trc的副檔名 if (@rc!=0) goto error -- 設定跟蹤事件 declare@onbitset@on=1--下述語句中的148指的是locks:deadlock graph事件(參見sys.trace_events),12指的是spid列(參見sys.trace_columns) exec sp_trace_setevent @traceid, 148, 12, @onexec sp_trace_setevent @traceid, 148, 11, @onexec sp_trace_setevent @traceid, 148, 4, @onexec sp_trace_setevent @traceid, 148, 14, @onexec sp_trace_setevent @traceid, 148, 26, @onexec sp_trace_setevent @traceid, 148, 64, @onexec sp_trace_setevent @traceid, 148, 1, @on-- 啟動跟蹤 exec sp_trace_setstatus @traceid, 1-- 記錄下跟蹤id,以備後面使用 select traceid =@traceidgoto finish error: select errorcode=@rc finish: go

執行上述語句後,每當sql server中發生死鎖事件,都會自動往檔案e:\dblog\deadlockdetect.trc中插入一條記錄。

2.暫停和停止伺服器端跟蹤

如果要暫停上面的伺服器端跟蹤,可執行下面的語句:

sql code

exec sp_trace_setstatus 1, 0--第乙個引數表示traceid,即步驟1中的輸出引數。第二個引數表示將狀態改為0,即暫停

如果要停止上面的伺服器端跟蹤,可執行下面的語句:

sql code

exec sp_trace_setstatus 1, 2--第乙個引數表示traceid,即步驟1中的輸出引數。第二個引數表示將狀態改為2,即停止

3.檢視跟蹤檔案內容

對於上面生成的跟蹤檔案(e:\dblog\deadlockdetect.trc),可通過兩種方法檢視:

1).執行t-sql命令

sql code

select*from fn_trace_gettable('e:\dblog\deadlockdetect.trc',1)

結果中的textdata列即以xml的形式返回死鎖的詳細資訊。

2).在sql server profiler中開啟。

依次 進入profiler -> 開啟跟蹤檔案 ->選擇e:\dblog\deadlockdetect.trc,就可以看到以圖形形式展現的死鎖資訊了。

怎麼捕獲和記錄SQL Server中發生的死鎖

我們知道,可以使用sql server自帶的profiler工具來跟蹤死鎖資訊。但這種方式有乙個很大的敝端,就是消耗很大。據國外某大神測試,profiler甚至可以佔到伺服器總頻寬的35 所以,在乙個繁忙的系統中,使用profiler顯然不是乙個好主意,下面我介紹兩種消耗比較少的方法。其中第二種的消...

記錄 輸入捕獲

捕獲輸入訊號脈衝的寬度。捕獲的概念是,捕獲邊沿訊號,同時將定時器的計數值儲存下牢。通過檢測輸入通道 timx chx 上的邊沿訊號,在邊沿訊號發生跳變 上公升沿 下降沿 的時候,將當前定時器的值 timx cnt 存入對應的捕獲 比較暫存器 timx ccrx 中,完成一次捕獲。定時器的輸入通道,就...

js中的事件捕獲和事件捕獲

事件流的三個階段 事件捕獲階段 目標階段 事件冒泡事件 關於這三個階段的介紹網上已經有很多介紹了,在這裡不做介紹。本文主要說下需要注意的一點 當在事發元素上即繫結了捕獲事件又繫結了冒泡事件時,事發元素上的執行順序由事件註冊順序決定。如 var p document.getelementbyid pa...