График взаимоблокировок из XEvents не дает хорошего XML

Я исследую взаимоблокировку и использовал следующий запрос (который я получил из курса 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) 28 июня 2012 г. 08:36:30 Авторское право (c) Microsoft Corporation Enterprise Edition (64-разрядная версия) в Windows NT 6.1 (сборка 7601: пакет обновления 1) (гипервизор )

У кого-нибудь есть идея, что происходит? Я нахожу это довольно своеобразным.

заранее спасибо

Джейми


person jamiet    schedule 06.11.2013    source источник


Ответы (3)


Джейми, я считаю, что это стандарт для 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';
person mbourgon    schedule 06.11.2013
comment
Удивительно, чем ты, Майкл. Завтра утром первым делом займусь этим. - person jamiet; 06.11.2013
comment
Это прекрасно работает, за исключением того, что план по умолчанию был ужасен (~ 1 минута). Добавлена ​​опция (maxdop 1) или разбить на два запроса, так как нет подсказки о материализации. Склсервер 2012. - person crokusek; 29.10.2014

Прямая копия/вставка кода Майкла выше вызвала ошибку:

Сообщение 9436, уровень 16, состояние 1, строка 1

Разбор XML: строка 5, символ 15, конечный тег не соответствует начальному тегу

Поэтому я немного повозился, чтобы получить это:

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';

который, кажется, работает нормально.

ХТН

JT

person jamiet    schedule 07.11.2013
comment
Спасибо! Получил ту же ошибку, что и вы. Это помогает. Я удивлен, что я первый плюс... - person Sting; 01.02.2018

Вот еще одна версия (для 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');
person Alex    schedule 12.03.2015