Skip to content

Commit 5760c43

Browse files
Update sp_BlitzLock.sql
Doing some more work on this as I find data source issues. Apparently there's more than one way to report a deadlock!
1 parent 69fb073 commit 5760c43

File tree

1 file changed

+113
-22
lines changed

1 file changed

+113
-22
lines changed

sp_BlitzLock.sql

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ BEGIN
223223
@StartDateUTC datetime,
224224
@EndDateUTC datetime,
225225
@extract_sql nvarchar(MAX),
226-
@validation_sql nvarchar(MAX);
226+
@validation_sql nvarchar(MAX),
227+
@xe bit,
228+
@xd bit;
227229

228230
/*Temporary objects used in the procedure*/
229231
DECLARE
@@ -348,8 +350,8 @@ BEGIN
348350
@TargetSessionType = N'ring_buffer';
349351
END;
350352

351-
IF @TargetDatabaseName IS NOT NULL
352-
AND @TargetSchemaName IS NOT NULL
353+
IF ISNULL(@TargetDatabaseName, DB_NAME()) IS NOT NULL
354+
AND ISNULL(@TargetSchemaName, N'dbo') IS NOT NULL
353355
AND @TargetTableName IS NOT NULL
354356
AND @TargetColumnName IS NOT NULL
355357
BEGIN
@@ -359,15 +361,6 @@ BEGIN
359361
/* Add this after the existing parameter validations */
360362
IF @TargetSessionType = N'table'
361363
BEGIN
362-
IF @TargetDatabaseName IS NULL
363-
OR @TargetSchemaName IS NULL
364-
OR @TargetTableName IS NULL
365-
OR @TargetColumnName IS NULL
366-
BEGIN
367-
RAISERROR(N'When using a table as a source, you must specify @TargetDatabaseName, @TargetSchemaName, @TargetTableName, and @TargetColumnName.', 11, 1) WITH NOWAIT;
368-
RETURN;
369-
END;
370-
371364
IF @TargetDatabaseName IS NULL
372365
BEGIN
373366
SET @TargetDatabaseName = DB_NAME();
@@ -377,6 +370,16 @@ BEGIN
377370
BEGIN
378371
SET @TargetSchemaName = N'dbo';
379372
END;
373+
374+
IF @TargetTableName IS NULL
375+
OR @TargetColumnName IS NULL
376+
BEGIN
377+
RAISERROR(N'
378+
When using a table as a source, you must specify @TargetTableName, and @TargetColumnName.
379+
When @TargetDatabaseName or @TargetSchemaName is NULL, they default to DB_NAME() AND dbo',
380+
11, 1) WITH NOWAIT;
381+
RETURN;
382+
END;
380383

381384
/* Check if target database exists */
382385
IF NOT EXISTS
@@ -1257,8 +1260,42 @@ BEGIN
12571260
SET @d = CONVERT(varchar(40), GETDATE(), 109);
12581261
RAISERROR('Inserting to #deadlock_data from table source %s', 0, 1, @d) WITH NOWAIT;
12591262

1263+
/*
1264+
First, we need to heck the XML structure.
1265+
Depending on the data source, the XML could
1266+
contain either the /event or /deadlock nodes.
1267+
When the /event nodes are not present, there
1268+
is no @name attribute to evaluate.
1269+
*/
1270+
1271+
SELECT
1272+
@extract_sql = N'
1273+
SELECT TOP (1)
1274+
@xe = xe.e.exist(''.''),
1275+
@xd = xd.e.exist(''.'')
1276+
FROM [master].[dbo].[bpr] AS x
1277+
OUTER APPLY x.[bpr].nodes(''/event'') AS xe(e)
1278+
OUTER APPLY x.[bpr].nodes(''/deadlock'') AS xd(e)
1279+
OPTION(RECOMPILE);
1280+
';
1281+
1282+
IF @Debug = 1 BEGIN PRINT @extract_sql; END;
1283+
1284+
EXECUTE sys.sp_executesql
1285+
@extract_sql,
1286+
N'
1287+
@xe bit OUTPUT,
1288+
@xd bit OUTPUT
1289+
',
1290+
@xe OUTPUT,
1291+
@xd OUTPUT;
1292+
1293+
12601294
/* Build dynamic SQL to extract the XML */
1261-
SET @extract_sql = N'
1295+
IF @xe = 1
1296+
AND @xd IS NULL
1297+
BEGIN
1298+
SET @extract_sql = N'
12621299
SELECT
12631300
deadlock_xml = ' +
12641301
QUOTENAME(@TargetColumnName) +
@@ -1281,21 +1318,60 @@ BEGIN
12811318
OR e.x.exist(''@name[ .= "database_xml_deadlock_report"]'') = 1
12821319
OR e.x.exist(''@name[ .= "xml_deadlock_report_filtered"]'') = 1
12831320
)';
1321+
END;
1322+
1323+
IF @xe IS NULL
1324+
AND @xd = 1
1325+
BEGIN
1326+
SET @extract_sql = N'
1327+
SELECT
1328+
deadlock_xml = ' +
1329+
QUOTENAME(@TargetColumnName) +
1330+
N'
1331+
FROM ' +
1332+
QUOTENAME(@TargetDatabaseName) +
1333+
N'.' +
1334+
QUOTENAME(@TargetSchemaName) +
1335+
N'.' +
1336+
QUOTENAME(@TargetTableName) +
1337+
N' AS x
1338+
LEFT JOIN #t AS t
1339+
ON 1 = 1
1340+
CROSS APPLY x.' +
1341+
QUOTENAME(@TargetColumnName) +
1342+
N'.nodes(''/deadlock'') AS e(x)
1343+
WHERE 1 = 1';
1344+
END;
12841345

12851346
/* Add timestamp filtering if specified */
1286-
IF @TargetTimestampColumnName IS NOT NULL
1347+
IF @TargetTimestampColumnName IS NOT NULL
12871348
BEGIN
12881349
SET @extract_sql = @extract_sql + N'
12891350
AND x.' + QUOTENAME(@TargetTimestampColumnName) + N' >= @StartDate
12901351
AND x.' + QUOTENAME(@TargetTimestampColumnName) + N' < @EndDate';
12911352
END;
12921353

1293-
/* If no timestamp column but date filtering is needed, handle XML-based filtering */
1294-
IF @TargetTimestampColumnName IS NULL
1354+
/* If no timestamp column but date filtering is needed, handle XML-based filtering when possible */
1355+
IF @TargetTimestampColumnName IS NULL
1356+
AND @xe = 1
1357+
AND @xd IS NULL
12951358
BEGIN
12961359
SET @extract_sql = @extract_sql + N'
12971360
AND e.x.exist(''@timestamp[. >= sql:variable("@StartDate") and . < sql:variable("@EndDate")]'') = 1';
12981361
END;
1362+
1363+
/*Woof*/
1364+
IF @TargetTimestampColumnName IS NULL
1365+
AND @xe IS NULL
1366+
AND @xd = 1
1367+
BEGIN
1368+
SET @extract_sql = @extract_sql + N'
1369+
AND e.x.exist(''(/deadlock/process-list/process/@lasttranstarted)[. >= sql:variable("@StartDate") and . < sql:variable("@EndDate")]'') = 1';
1370+
END;
1371+
1372+
SET @extract_sql += N'
1373+
OPTION(RECOMPILE);
1374+
';
12991375

13001376
IF @Debug = 1 BEGIN PRINT @extract_sql; END;
13011377

@@ -1335,6 +1411,21 @@ BEGIN
13351411
FROM #deadlock_data AS d1
13361412
LEFT JOIN #t AS t
13371413
ON 1 = 1
1414+
WHERE @xe = 1
1415+
1416+
UNION ALL
1417+
1418+
SELECT
1419+
d1.deadlock_xml,
1420+
event_date = d1.deadlock_xml.value('(/deadlock/process-list/process/@lasttranstarted)[1]', 'datetime2'),
1421+
victim_id = d1.deadlock_xml.value('(/deadlock/victim-list/victimProcess/@id)[1]', 'nvarchar(256)'),
1422+
is_parallel = d1.deadlock_xml.exist('/deadlock/resource-list/exchangeEvent'),
1423+
is_parallel_batch = d1.deadlock_xml.exist('/deadlock/resource-list/SyncPoint'),
1424+
deadlock_graph = d1.deadlock_xml.query('.')
1425+
FROM #deadlock_data AS d1
1426+
LEFT JOIN #t AS t
1427+
ON 1 = 1
1428+
WHERE @xd = 1
13381429
OPTION(RECOMPILE);
13391430

13401431
SET @d = CONVERT(varchar(40), GETDATE(), 109);
@@ -4370,16 +4461,16 @@ BEGIN
43704461
@VictimsOnly,
43714462
DeadlockType =
43724463
@DeadlockType,
4373-
TargetDatabaseName =
4374-
@TargetDatabaseName,
4464+
TargetDatabaseName =
4465+
@TargetDatabaseName,
43754466
TargetSchemaName =
4376-
@TargetSchemaName,
4467+
@TargetSchemaName,
43774468
TargetTableName =
4378-
@TargetTableName,
4469+
@TargetTableName,
43794470
TargetColumnName =
4380-
@TargetColumnName,
4471+
@TargetColumnName,
43814472
TargetTimestampColumnName =
4382-
@TargetTimestampColumnName,
4473+
@TargetTimestampColumnName,
43834474
Debug =
43844475
@Debug,
43854476
Help =

0 commit comments

Comments
 (0)