|
80 | 80 | END;
|
81 | 81 |
|
82 | 82 | IF @Top IS NULL
|
83 | | - SET @Top = 2147483647 |
| 83 | + SET @Top = 2147483647; |
84 | 84 |
|
85 | 85 | IF @StartDate IS NULL
|
86 | | - SET @StartDate = '19000101' |
| 86 | + SET @StartDate = '19000101'; |
87 | 87 |
|
88 | 88 | IF @EndDate IS NULL
|
89 | | - SET @EndDate = '99991231' |
| 89 | + SET @EndDate = '99991231'; |
90 | 90 |
|
91 | 91 |
|
92 | 92 | IF OBJECT_ID('tempdb..#deadlock_data') IS NOT NULL
|
|
113 | 113 | check_id INT NOT NULL,
|
114 | 114 | database_name NVARCHAR(256),
|
115 | 115 | object_name NVARCHAR(1000),
|
| 116 | + finding_group NVARCHAR(100), |
116 | 117 | finding NVARCHAR(4000),
|
117 | 118 | query_text XML
|
118 | 119 | );
|
@@ -235,61 +236,175 @@ AS
|
235 | 236 | /*Begin checks based on parsed values*/
|
236 | 237 |
|
237 | 238 | /*Check 1 is deadlocks by database*/
|
238 | | - INSERT #deadlock_findings ( check_id, database_name, object_name, finding, query_text ) |
| 239 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
239 | 240 | SELECT 1 AS check_id,
|
240 | 241 | DB_NAME(dow.database_id) AS database_name,
|
241 | 242 | NULL AS object_name,
|
| 243 | + 'Total database locks' AS finding_group, |
242 | 244 | 'This database had '
|
243 | 245 | + CONVERT(NVARCHAR(20), COUNT_BIG(DISTINCT dow.owner_id))
|
244 | 246 | + ' deadlocks.',
|
245 | 247 | NULL AS query_text
|
246 | 248 | FROM #deadlock_owner_waiter AS dow
|
247 | | - GROUP BY DB_NAME(dow.database_id) |
| 249 | + GROUP BY DB_NAME(dow.database_id); |
248 | 250 |
|
249 | 251 | /*Check 2 is deadlocks by object*/
|
250 | 252 |
|
251 | | - INSERT #deadlock_findings ( check_id, database_name, object_name, finding, query_text ) |
| 253 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
252 | 254 | SELECT 2 AS check_id,
|
253 | 255 | DB_NAME(dow.database_id) AS database_name,
|
254 | 256 | dow.object_name AS object_name,
|
| 257 | + 'Total object locks' AS finding_group, |
255 | 258 | 'This object had '
|
256 | 259 | + CONVERT(NVARCHAR(20), COUNT_BIG(DISTINCT dow.owner_id))
|
257 | 260 | + ' deadlocks.',
|
258 | 261 | NULL AS query_text
|
259 | 262 | FROM #deadlock_owner_waiter AS dow
|
260 | | - GROUP BY DB_NAME(dow.database_id), dow.object_name |
261 | | - |
262 | | - |
| 263 | + GROUP BY DB_NAME(dow.database_id), dow.object_name; |
| 264 | + |
263 | 265 |
|
264 | | - SELECT df.id, df.check_id, df.database_name, df.object_name, df.finding, df.query_text |
| 266 | + /*Check 3 looks for Serializable locking*/ |
| 267 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 268 | + SELECT 3 AS check_id, |
| 269 | + DB_NAME(dp.database_id) AS database_name, |
| 270 | + NULL AS object_name, |
| 271 | + 'Serializable locking' AS finding_group, |
| 272 | + 'This database has had ' + |
| 273 | + CONVERT(NVARCHAR(20), COUNT_BIG(*)) + |
| 274 | + ' instances of serializable deadlocks.' |
| 275 | + AS finding, |
| 276 | + NULL AS query_text |
| 277 | + FROM #deadlock_process AS dp |
| 278 | + WHERE dp.isolation_level LIKE 'serializable%' |
| 279 | + GROUP BY DB_NAME(dp.database_id); |
| 280 | + |
| 281 | + /*Check 4 looks for Repeatable Read locking*/ |
| 282 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 283 | + SELECT 4 AS check_id, |
| 284 | + DB_NAME(dp.database_id) AS database_name, |
| 285 | + NULL AS object_name, |
| 286 | + 'Repeatable Read locking' AS finding_group, |
| 287 | + 'This database has had ' + |
| 288 | + CONVERT(NVARCHAR(20), COUNT_BIG(*)) + |
| 289 | + ' instances of repeatable read deadlocks.' |
| 290 | + AS finding, |
| 291 | + NULL AS query_text |
| 292 | + FROM #deadlock_process AS dp |
| 293 | + WHERE dp.isolation_level LIKE 'repeatable read%' |
| 294 | + GROUP BY DB_NAME(dp.database_id); |
| 295 | + |
| 296 | + /*Check 5 breaks down app, host, and login information*/ |
| 297 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 298 | + SELECT 5 AS check_id, |
| 299 | + DB_NAME(dp.database_id) AS database_name, |
| 300 | + NULL AS object_name, |
| 301 | + 'Login, App, and Host locking' AS finding_group, |
| 302 | + 'This database has had ' + |
| 303 | + CONVERT(NVARCHAR(20), COUNT_BIG(DISTINCT dp.id)) + |
| 304 | + ' instances of deadlocks involving the login ' + |
| 305 | + dp.login_name + |
| 306 | + ' from the application ' + |
| 307 | + dp.client_app + |
| 308 | + ' on host ' + |
| 309 | + dp.host_name |
| 310 | + AS finding, |
| 311 | + NULL AS query_text |
| 312 | + FROM #deadlock_process AS dp |
| 313 | + GROUP BY DB_NAME(dp.database_id), dp.login_name, dp.client_app, dp.host_name; |
| 314 | + |
| 315 | + /*Check 6 breaks down the types of locks (object, page, key, etc.)*/ |
| 316 | + WITH lock_types AS ( |
| 317 | + SELECT DB_NAME(dp.database_id) AS database_name, |
| 318 | + dow.object_name, |
| 319 | + SUBSTRING(dp.wait_resource, 1, CHARINDEX(':', dp.wait_resource) -1) AS lock, |
| 320 | + CONVERT(NVARCHAR(20), COUNT_BIG(DISTINCT dp.id)) AS lock_count |
| 321 | + FROM #deadlock_process AS dp |
| 322 | + JOIN #deadlock_owner_waiter AS dow |
| 323 | + ON dp.id = dow.owner_id |
| 324 | + GROUP BY DB_NAME(dp.database_id), SUBSTRING(dp.wait_resource, 1, CHARINDEX(':', dp.wait_resource) - 1), dow.object_name |
| 325 | + ) |
| 326 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 327 | + SELECT 6 AS check_id, |
| 328 | + lock_types.database_name, |
| 329 | + lock_types.object_name, |
| 330 | + 'Types of locks by object' AS finding_group, |
| 331 | + 'This object has had ' + |
| 332 | + lock_types.lock_count + |
| 333 | + ' ' + |
| 334 | + lock_types.lock |
| 335 | + + ' locks', |
| 336 | + NULL AS query_text |
| 337 | + FROM lock_types; |
| 338 | + |
| 339 | + /*Check 7 gives you more info queries for sp_BlitzCache */ |
| 340 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 341 | + SELECT DISTINCT 7 AS check_id, |
| 342 | + DB_NAME(dow.database_id) AS database_name, |
| 343 | + ds.proc_name AS object_name, |
| 344 | + 'More Info - Query' AS finding_group, |
| 345 | + 'EXEC sp_BlitzCache ' + |
| 346 | + CASE WHEN ds.proc_name = 'adhoc' |
| 347 | + THEN ' @OnlySqlhandles = ' + |
| 348 | + QUOTENAME(ds.sql_handle, '''') |
| 349 | + ELSE '@StoredProcName = ' + |
| 350 | + QUOTENAME(ds.proc_name, '''') |
| 351 | + END + |
| 352 | + ';' AS finding, |
| 353 | + NULL AS query_text |
| 354 | + FROM #deadlock_stack AS ds |
| 355 | + JOIN #deadlock_owner_waiter AS dow |
| 356 | + ON dow.owner_id = ds.id; |
| 357 | + |
| 358 | + /*Check 8 gives you more info queries for sp_BlitzCache */ |
| 359 | + WITH bi AS ( |
| 360 | + SELECT DISTINCT |
| 361 | + dow.object_name, |
| 362 | + PARSENAME(dow.object_name, 3) AS database_name, |
| 363 | + PARSENAME(dow.object_name, 2) AS schema_name, |
| 364 | + PARSENAME(dow.object_name, 1) AS table_name |
| 365 | + FROM #deadlock_owner_waiter AS dow |
| 366 | + ) |
| 367 | + INSERT #deadlock_findings ( check_id, database_name, object_name, finding_group, finding, query_text ) |
| 368 | + SELECT 8 AS check_id, |
| 369 | + bi.database_name, |
| 370 | + bi.schema_name + '.' + bi.table_name, |
| 371 | + 'More Info - Table' AS finding_group, |
| 372 | + 'EXEC sp_BlitzIndex ' + |
| 373 | + '@DatabaseName = ' + QUOTENAME(bi.database_name, '''') + |
| 374 | + ', @SchemaName = ' + QUOTENAME(bi.schema_name, '''') + |
| 375 | + ', @TableName = ' + QUOTENAME(bi.table_name, '''') + |
| 376 | + ';' AS finding, |
| 377 | + NULL AS query_text |
| 378 | + FROM bi; |
| 379 | + |
| 380 | + SELECT df.check_id, df.database_name, df.object_name, df.finding_group, df.finding, df.query_text |
265 | 381 | FROM #deadlock_findings AS df
|
266 | | - ORDER BY df.check_id |
| 382 | + ORDER BY df.check_id; |
| 383 | + |
267 | 384 |
|
268 | 385 | IF @Debug = 1
|
269 | 386 | BEGIN
|
270 | 387 |
|
271 | 388 | SELECT '#deadlock_data' AS table_name, *
|
272 | 389 | FROM #deadlock_data AS dd;
|
273 | 390 |
|
| 391 | + SELECT '#deadlock_resource' AS table_name, * |
| 392 | + FROM #deadlock_resource AS dr; |
| 393 | + |
274 | 394 | SELECT '#deadlock_owner_waiter' AS table_name, *
|
275 | 395 | FROM #deadlock_owner_waiter AS dow;
|
276 | 396 |
|
277 | 397 | SELECT '#deadlock_process' AS table_name, *
|
278 | 398 | FROM #deadlock_process AS dp;
|
279 | 399 |
|
280 | | - SELECT '#deadlock_resource' AS table_name, * |
281 | | - FROM #deadlock_resource AS dr; |
282 | | - |
283 | 400 | SELECT '#deadlock_stack' AS table_name, *
|
284 | 401 | FROM #deadlock_stack AS ds;
|
| 402 | + |
285 | 403 | END; -- End debug
|
286 | 404 |
|
287 | 405 | END; --Final End
|
288 | 406 | GO
|
289 | 407 |
|
290 | | -EXEC dbo.sp_BlitzLock @Debug = 1; |
291 | | - |
292 | | - |
293 | 408 |
|
294 | 409 |
|
295 | 410 |
|
|
0 commit comments