web-dev-qa-db-ja.com

デッドロックエラーがデッドロックSQLを返さない

Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Webサイトの1つがビジー状態になると、このエラーがランダムに発生します。私は大まかにそれが起こっているテーブルのセットを知っていますが、他のプログラムでの経験では、通常、デッドロックが起こっている場所でSQLを返します。これを可能にするためにオンにする必要があるフラグはありますか?

これが今の私の主な質問なので、別の問題としてデッドロック自体を試してデバッグします。

SQL Server 2008 Standard Editionを使用しています。

13
webnoob

必要なデータは、デフォルトの拡張イベントトレースに記録されます。

_DECLARE @xml XML

SELECT @xml = target_data
FROM   sys.dm_xe_session_targets
       JOIN sys.dm_xe_sessions
         ON event_session_address = address
WHERE  name = 'system_health'
       AND target_name = 'ring_buffer'

SELECT   
             XEventData.XEvent.query('(data/value/deadlock)[1]')  AS DeadlockGraph,
             CAST(XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') AS XML) AS DeadlockGraph,
              XEventData.XEvent.value('(./@timestamp)[1]', 'DATETIME2') AS [DateTime]
FROM   (SELECT @xml AS TargetData) AS Data
       CROSS APPLY 
       TargetData.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData (XEvent) 
ORDER BY [DateTime] DESC
_

ただし、サービスを再起動している場合、それはもうありません。トレースフラグを適用するか、バッファがその間に循環したかどうか。

デッドロックグラフを永続的な非揮発性ストレージのファイルターゲットに保存する独自の拡張イベントトレースを設定できます。 ここにサンプルコード 。個人的には、デッドロックグラフXMLはトレースフラグの出力よりもわかりやすいと思います。

編集

  1. @ MartinC は、すべての更新が含まれていないSQL Serverのインスタンスでは、無効なXMLの生成に問題がある可能性があることをコメントで指摘しています。そのための修正は、いくつかの検索を実行して、SELECTリストのCAST(REPLACE(REPLACE(XEventData.XEvent.value('(data/value)[1]', 'varchar(max)'), '<victim-list>', '<deadlock><victim-list>'), '<process-list>', '</victim-list><process-list>') AS XML) AS DeadlockGraphを使用することです ここで説明
  2. Wayne Sheffieldが、デッドロックグラフXMLを表形式に細かく分割するための便利なスクリプト here を投稿しました。
25
Martin Smith

受け入れられた答え は、私にとって一貫して機能しませんでした。リングバッファは明らかに、特定の状況でイベントをドロップすることがわかっています。

ConnectItem

リングバッファの問題

System_healthログイベントファイルは解析できます( this answer から):

with XmlDeadlockReports as
(
  select convert(xml, event_data) as EventData
  from sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL)
  where substring(event_data, 1, 50) like '%"xml_deadlock_report"%'  
) 
select EventData.value('(event/@timestamp)[1]', 'datetime2(7)') as TimeStamp,
       EventData.query('event/data/value/deadlock') as XdlFile
  from XmlDeadlockReports
 order by TimeStamp desc

XdlFileフィールドは.xdlファイルに保存して、SSMSに読み込むことができます。 SQL Server 2012でテスト済み。

3
crokusek