2

我正在调查死锁并使用以下查询(我从 Jonathan Kehayias 的 Pluralsight 死锁课程中获得)从有关死锁的扩展事件中提取信息:

SELECT  
    XEvent.query('data[@name="xml_report"]/value/deadlock') AS deadlock_graph 
FROM    (SELECT CAST([target_data] AS XML) AS TargetData 
         FROM sys.dm_xe_session_targets AS st 
         INNER JOIN sys.dm_xe_sessions AS s  
            ON [s].[address] = [st].[event_session_address] 
         WHERE [s].[name] = N'system_health' 
           AND [st].[target_name] = N'ring_buffer') AS Data 
CROSS APPLY TargetData.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData (XEvent); 

奇怪的是,这给了我一个 1 行 1 列的结果集,其中包含一个空值。经过一番挖掘,我发现这是由于内部查询返回的 XML 文档的死锁图部分不是有效的 XML。它看起来像这样:

格式错误的 XML

如您所见,尖括号已全部替换为它们的 HTML 编码。我不明白这是怎么发生的,因为我所做的只是直接从 SSMS 查询数据库。

无论如何,一旦我意识到这个问题,我就能够用正确的尖括号替换所有错误的值并且我的 XML 是有效的,并且我能够检查死锁。不过我觉得这很奇怪,有谁知道为什么死锁图会像这样回来?

我应该注意到 XML 的其余部分(即除了死锁图之外的其余事件)完美地返回,如您在此处看到的: 在此处输入图像描述

这是我的版本信息:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) Jun 28 2012 08:36:30 版权所有 (c) Microsoft Corporation Enterprise Edition (64-bit) o​​n Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor) )

有人知道发生了什么吗?我觉得比较奇特。

提前致谢

杰米

4

3 回答 3

3

Jamie,我相信这是 XML 包装在 XML 中的标准。此查询有效(由 Kehayias 提供)

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
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_session_targets st
    JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
    WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';
于 2013-11-06T18:38:44.527 回答
1

A straight copy/paste of Michael's code above caused an error:

Msg 9436, Level 16, State 1, Line 1

XML parsing: line 5, character 15, end tag does not match start tag

So I fiddled about a bit to get this:

SELECT CAST (
            XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)')
    AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_session_targets st
    JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
    WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';

which seems to work fine.

HTH

JT

于 2013-11-07T08:47:29.937 回答
0

这是另一个版本(用于 SQL Server 2008R2 (SP2)):

SELECT CAST(CAST(st.target_data AS xml).query('RingBufferTarget/event[@name="xml_deadlock_report"]/data/value/text()').value('.', 'nvarchar(MAX)') AS xml)
FROM sys.dm_xe_session_targets st
    INNER JOIN sys.dm_xe_sessions s 
        ON st.event_session_address = s.address
WHERE s.name = 'system_health' AND st.target_name = 'ring_buffer'
FOR XML PATH('deadlock-list');
于 2015-03-12T22:07:23.720 回答