Skip to content

Commit 9e33bd6

Browse files
sp_Blitz: fix 14 bugs found in code review
HIGH (4): - Line 7414: 'dbo.MSreplication_objects' never matches sys.tables.name — replication subscriber check (CheckID 19 Method B) was dead code. Fixed to 'MSreplication_objects' - Line 6805: Missing ISNULL in THEN branch for AG replica lag (CheckID 185) — Details became NULL when last_commit_time was NULL - Line 4900: Duplicate CheckID 145 used for both Hekaton memory and Accelerated Database Recovery. Changed ADR to new CheckID 275 - Lines 6576-6604: GROUP BY included transaction_type and transaction_state (CheckID 215) — produced duplicate rows with wrong partial counts MEDIUM (6): - Lines 8796-8800: Trace flag 7752 CASE branch ordering — specific messages for @CheckUserDatabaseObjects and @QueryStoreInUse unreachable on SQL 2019+ - Line 5508: ISNULL(@var, @var) no-op replaced with ISNULL(@var, '(unknown)') - Lines 5736-5743: @MaximumVersionDate only tracked for first outdated component, not the actual maximum - Lines 1479/1513-1516: CheckID 256 SkipChecks filter commented out with wrong CheckID reference (2 instead of 256). Uncommented and fixed - Lines 3989-3998: CheckID 270 "last 4 hours" claim had no time filter on snapshot_time from sys.dm_os_memory_health_history - Lines 10267/10269: Named instances never reported CheckID 266 memory counters — hardcoded 'SQLServer:Memory Manager%' changed to '%Memory Manager%' LOW (4): - Line 5655: sp_executesql parameter DATETIME vs DATETIME2 mismatch - Line 8114: Debug RAISERROR said CheckID 218, should be 225 - Line 8857: TF 7752 recommendation had spurious FROM #TraceStatus producing duplicate rows - Line 2049: Double ++ typo in string concatenation - Line 7695: Missing % wildcard on sp_PressureDetector exclusion - Line 1839: CheckID 2301 missing DatabaseName IS NULL in SkipChecks filter - Line 7674: Dead JOIN SM.object_id = DB_id() removed (object_id vs database_id) Documentation updated: CheckID 275 added, high CheckID bumped to 275. Tested default, @CheckServerInfo, @CheckUserDatabaseObjects=0, @OutputType='MARKDOWN', and @SkipChecksTable on sql2022 — all pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2422c4b commit 9e33bd6

2 files changed

Lines changed: 29 additions & 26 deletions

File tree

‎Documentation/sp_Blitz_Checks_by_Priority.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Before adding a new check, make sure to add a Github issue for it first, and hav
66

77
If you want to change anything about a check - the priority, finding, URL, or ID - open a Github issue first. The relevant scripts have to be updated too.
88

9-
CURRENT HIGH CHECKID: 274.
10-
If you want to add a new one, start at 275.
9+
CURRENT HIGH CHECKID: 275.
10+
If you want to add a new one, start at 276.
1111

1212
| Priority | FindingsGroup | Finding | URL | CheckID |
1313
|----------|-----------------------------|---------------------------------------------------------|------------------------------------------------------------------------|----------|
@@ -275,6 +275,7 @@ If you want to add a new one, start at 275.
275275
| 210 | Non-Default Database Config | Snapshot Isolation Enabled | https://www.BrentOzar.com/go/dbdefaults | 132 |
276276
| 210 | Non-Default Database Config | Supplemental Logging Enabled | https://www.BrentOzar.com/go/dbdefaults | 131 |
277277
| 210 | Non-Default Database Config | Target Recovery Time Changed | https://www.BrentOzar.com/go/dbdefaults | 142 |
278+
| 210 | Non-Default Database Config | Accelerated Database Recovery Enabled | https://www.BrentOzar.com/go/dbdefaults | 275 |
278279
| 210 | Non-Default Database Config | Trustworthy Enabled | https://www.BrentOzar.com/go/dbdefaults | 137 |
279280
| 210 | Non-Default Database Config | Broker Enabled | https://www.BrentOzar.com/go/dbdefaults | 230 |
280281
| 210 | Non-Default Database Config | Honor Broker Priority Enabled | https://www.BrentOzar.com/go/dbdefaults | 231 |

‎sp_Blitz.sql‎

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ AS
14761476
WHERE DatabaseName IS NULL AND CheckID = 256 )
14771477
BEGIN
14781478

1479-
IF @Debug IN (1, 2) RAISERROR('Running CheckId [%d].', 0, 1, 2) WITH NOWAIT;
1479+
IF @Debug IN (1, 2) RAISERROR('Running CheckId [%d].', 0, 1, 256) WITH NOWAIT;
14801480

14811481
INSERT INTO #BlitzResults
14821482
( CheckID ,
@@ -1510,10 +1510,10 @@ AS
15101510
AND d.state NOT IN(1, 6, 10) /* Not currently offline or restoring, like log shipping databases */
15111511
AND d.is_in_standby = 0 /* Not a log shipping target database */
15121512
AND d.source_database_id IS NULL /* Excludes database snapshots */
1513-
--AND d.name NOT IN ( SELECT DISTINCT
1514-
-- DatabaseName
1515-
-- FROM #SkipChecks
1516-
-- WHERE CheckID IS NULL OR CheckID = 2)
1513+
AND d.name NOT IN ( SELECT DISTINCT
1514+
DatabaseName
1515+
FROM #SkipChecks
1516+
WHERE CheckID IS NULL OR CheckID = 256)
15171517
AND EXISTS ( SELECT *
15181518
FROM msdb.dbo.backupset AS b INNER JOIN
15191519
msdb.dbo.backupmediafamily AS bmf
@@ -1836,7 +1836,7 @@ AS
18361836

18371837
IF NOT EXISTS ( SELECT 1
18381838
FROM #SkipChecks
1839-
WHERE CheckID = 2301 )
1839+
WHERE DatabaseName IS NULL AND CheckID = 2301 )
18401840
BEGIN
18411841

18421842
IF @Debug IN (1, 2) RAISERROR('Running CheckId [%d].', 0, 1, 2301) WITH NOWAIT;
@@ -2046,7 +2046,7 @@ AS
20462046
''Performance'' AS FindingsGroup,
20472047
''Server Triggers Enabled'' AS Finding,
20482048
''https://www.brentozar.com/go/logontriggers/'' AS URL,
2049-
(''Server Trigger ['' + [name] ++ ''] is enabled. Make sure you understand what that trigger is doing - the less work it does, the better.'') AS Details
2049+
(''Server Trigger ['' + [name] + ''] is enabled. Make sure you understand what that trigger is doing - the less work it does, the better.'') AS Details
20502050
FROM sys.server_triggers
20512051
WHERE is_disabled = 0 AND is_ms_shipped = 0 AND name NOT LIKE ''rds^_%'' ESCAPE ''^'' OPTION (RECOMPILE);';
20522052

@@ -3995,6 +3995,7 @@ AS
39953995
+ N' severity level memory issues reported in the last 4 hours in sys.dm_os_memory_health_history.'
39963996
FROM sys.dm_os_memory_health_history
39973997
WHERE severity_level > 1
3998+
AND snapshot_time >= DATEADD(HOUR, -4, GETDATE())
39983999
GROUP BY severity_level, severity_level_desc;
39994000
END;
40004001

@@ -4897,7 +4898,7 @@ AS
48974898
WHERE name = 'is_memory_optimized_elevate_to_snapshot_on' AND object_id = OBJECT_ID('sys.databases')
48984899
AND SERVERPROPERTY('EngineEdition') <> 8; /* Hekaton is always enabled in Managed Instances per https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/issues/1919 */
48994900
INSERT INTO #DatabaseDefaults
4900-
SELECT 'is_accelerated_database_recovery_on', 0, 145, 210, 'Accelerated Database Recovery Enabled', 'https://www.brentozar.com/go/dbdefaults', NULL
4901+
SELECT 'is_accelerated_database_recovery_on', 0, 275, 210, 'Accelerated Database Recovery Enabled', 'https://www.brentozar.com/go/dbdefaults', NULL
49014902
FROM sys.all_columns
49024903
WHERE name = 'is_accelerated_database_recovery_on' AND object_id = OBJECT_ID('sys.databases') AND SERVERPROPERTY('EngineEdition') NOT IN (5, 8) ;
49034904

@@ -5505,7 +5506,7 @@ BEGIN
55055506
'Version Check Failed (dynamic query failure)' AS Finding ,
55065507
'http://FirstResponderKit.org' AS URL ,
55075508
'Download an updated First Responder Kit. Your version check failed due to dynamic query failure.' + @crlf +
5508-
'Error: following query failed at execution (check if component [' + ISNULL(@CurrentComponentName,@CurrentComponentName) + '] is mandatory and missing)' + @crlf +
5509+
'Error: following query failed at execution (check if component [' + ISNULL(@CurrentComponentName, '(unknown)') + '] is mandatory and missing)' + @crlf +
55095510
@tsql AS Details
55105511
;
55115512

@@ -5651,7 +5652,7 @@ BEGIN
56515652
CONTINUE;
56525653
END;
56535654

5654-
EXEC @ExecRet = sp_executesql @tsql , N'@ExecRet INT OUTPUT, @ObjDate DATETIME OUTPUT', @ExecRet = @InnerExecRet OUTPUT, @ObjDate = @CurrentComponentVersionDate OUTPUT;
5655+
EXEC @ExecRet = sp_executesql @tsql , N'@ExecRet INT OUTPUT, @ObjDate DATETIME2 OUTPUT', @ExecRet = @InnerExecRet OUTPUT, @ObjDate = @CurrentComponentVersionDate OUTPUT;
56555656

56565657
IF(@ExecRet <> 0)
56575658
BEGIN
@@ -5733,10 +5734,13 @@ BEGIN
57335734
CONTINUE;
57345735
END;
57355736

5736-
ELSE IF(@CurrentComponentVersionDate > @VersionDate AND @BlitzIsOutdatedComparedToOthers = 0)
5737+
ELSE IF(@CurrentComponentVersionDate > @VersionDate)
57375738
BEGIN
5738-
SET @BlitzIsOutdatedComparedToOthers = 1;
5739-
RAISERROR('Procedure %s is outdated',10,1,@spBlitzFullName);
5739+
IF(@BlitzIsOutdatedComparedToOthers = 0)
5740+
BEGIN
5741+
SET @BlitzIsOutdatedComparedToOthers = 1;
5742+
RAISERROR('Procedure %s is outdated',10,1,@spBlitzFullName);
5743+
END;
57405744
IF(@MaximumVersionDate IS NULL OR @MaximumVersionDate < @CurrentComponentVersionDate)
57415745
BEGIN
57425746
SET @MaximumVersionDate = @CurrentComponentVersionDate;
@@ -6601,7 +6605,7 @@ IF @ProductVersionMajor >= 10
66016605
LEFT JOIN sys.dm_exec_sessions AS s
66026606
ON s.session_id = tst.session_id
66036607
WHERE tat.name = ''implicit_transaction''
6604-
GROUP BY DB_NAME(s.database_id), transaction_type, transaction_state;';
6608+
GROUP BY DB_NAME(s.database_id);';
66056609

66066610

66076611
IF @Debug = 2 AND @StringToExecute IS NOT NULL PRINT @StringToExecute;
@@ -6802,7 +6806,7 @@ IF @ProductVersionMajor >= 10
68026806
'https://www.BrentOzar.com/go/ag' AS URL,
68036807
ag.name + N' AG replica server ' +
68046808
ar.replica_server_name + N' is ' +
6805-
CASE WHEN DATEDIFF(SECOND, ISNULL (drs.last_commit_time, drs.Last_hardened_time), ps.last_commit_time) < 200 THEN (CAST(DATEDIFF(SECOND, drs.last_commit_time, ps.last_commit_time) AS NVARCHAR(10)) + N' seconds ')
6809+
CASE WHEN DATEDIFF(SECOND, ISNULL (drs.last_commit_time, drs.Last_hardened_time), ps.last_commit_time) < 200 THEN (CAST(DATEDIFF(SECOND, ISNULL(drs.last_commit_time, drs.Last_hardened_time), ps.last_commit_time) AS NVARCHAR(10)) + N' seconds ')
68066810
ELSE (CAST(DATEDIFF(MINUTE, ISNULL (drs.last_commit_time, drs.Last_hardened_time), ps.last_commit_time) AS NVARCHAR(10)) + N' minutes ') END
68076811
+ N' behind the primary.'
68086812
AS details
@@ -7411,7 +7415,7 @@ IF @ProductVersionMajor >= 10
74117415
''https://www.brentozar.com/go/repl'',
74127416
(''['' + DB_NAME() + ''] has MSreplication_objects tables in it, indicating it is a replication subscriber.'')
74137417
FROM [?].sys.tables
7414-
WHERE name = ''dbo.MSreplication_objects''
7418+
WHERE name = ''MSreplication_objects''
74157419
AND ''?'' NOT IN (''master'', ''rdsadmin'')
74167420
OPTION (RECOMPILE)';
74177421
END;
@@ -7667,7 +7671,6 @@ IF @ProductVersionMajor >= 10
76677671
INSERT INTO #Recompile
76687672
SELECT DISTINCT DBName = DB_Name(), SPName = SO.name, SM.is_recompiled, ISR.SPECIFIC_SCHEMA
76697673
FROM sys.sql_modules AS SM
7670-
LEFT OUTER JOIN master.sys.databases AS sDB ON SM.object_id = DB_id()
76717674
LEFT OUTER JOIN dbo.sysobjects AS SO ON SM.object_id = SO.id and type = ''P''
76727675
LEFT OUTER JOIN INFORMATION_SCHEMA.ROUTINES AS ISR on ISR.Routine_Name = SO.name AND ISR.SPECIFIC_CATALOG = DB_Name()
76737676
WHERE SM.is_recompiled=1 OPTION (RECOMPILE); /* oh the rich irony of recompile here */
@@ -7688,7 +7691,7 @@ IF @ProductVersionMajor >= 10
76887691
Details = '[' + DBName + '].[' + SPSchema + '].[' + ProcName + '] has WITH RECOMPILE in the stored procedure code, which may cause increased CPU usage due to constant recompiles of the code.',
76897692
CheckID = '78'
76907693
FROM #Recompile AS TR
7691-
WHERE ProcName NOT LIKE 'sp_AllNightLog%' AND ProcName NOT LIKE 'sp_AskBrent%' AND ProcName NOT LIKE 'sp_Blitz%' AND ProcName NOT LIKE 'sp_PressureDetector'
7694+
WHERE ProcName NOT LIKE 'sp_AllNightLog%' AND ProcName NOT LIKE 'sp_AskBrent%' AND ProcName NOT LIKE 'sp_Blitz%' AND ProcName NOT LIKE 'sp_PressureDetector%'
76927695
AND DBName NOT IN ('master', 'model', 'msdb', 'tempdb');
76937696
DROP TABLE #Recompile;
76947697
END;
@@ -8107,7 +8110,7 @@ EXEC dbo.sp_MSforeachdb 'USE [?]; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITT
81078110
BEGIN
81088111
IF @Debug IN (1,2)
81098112
BEGIN
8110-
RAISERROR ('Running CheckId [%d].',0,1,218) WITH NOWAIT;
8113+
RAISERROR ('Running CheckId [%d].',0,1,225) WITH NOWAIT;
81118114
END
81128115

81138116
EXECUTE sp_MSforeachdb 'USE [?];
@@ -8793,9 +8796,9 @@ EXEC dbo.sp_MSforeachdb 'USE [?]; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITT
87938796
WHEN [T].[TraceFlag] = '7745' AND @QueryStoreInUse = 1 THEN '7745 enabled globally, which makes shutdowns/failovers quicker by not waiting for Query Store to flush to disk. This good idea loses you the non-flushed Query Store data.'
87948797
WHEN [T].[TraceFlag] = '7745' AND @ProductVersionMajor > 12 THEN '7745 enabled globally, which is for Query Store. None of your databases have Query Store enabled, so why do you have this turned on?'
87958798
WHEN [T].[TraceFlag] = '7745' AND @ProductVersionMajor <= 12 THEN '7745 enabled globally, which is for Query Store. Query Store does not exist on your SQL Server version, so why do you have this turned on?'
8796-
WHEN [T].[TraceFlag] = '7752' AND @ProductVersionMajor > 14 THEN '7752 enabled globally, which is for Query Store. However, it has no effect in your SQL Server version. Consider turning it off.'
87978799
WHEN [T].[TraceFlag] = '7752' AND @CheckUserDatabaseObjects = 0 THEN '7752 enabled globally, which stops queries needing to wait on Query Store loading up after database recovery. @CheckUserDatabaseObjects was set to 0, so we skipped checking if any databases have Query Store enabled.'
87988800
WHEN [T].[TraceFlag] = '7752' AND @QueryStoreInUse = 1 THEN '7752 enabled globally, which stops queries needing to wait on Query Store loading up after database recovery.'
8801+
WHEN [T].[TraceFlag] = '7752' AND @ProductVersionMajor > 14 THEN '7752 enabled globally, which is for Query Store. However, it has no effect in your SQL Server version. Consider turning it off.'
87998802
WHEN [T].[TraceFlag] = '7752' AND @ProductVersionMajor > 12 THEN '7752 enabled globally, which is for Query Store. None of your databases have Query Store enabled, so why do you have this turned on?'
88008803
WHEN [T].[TraceFlag] = '7752' AND @ProductVersionMajor <= 12 THEN '7752 enabled globally, which is for Query Store. Query Store does not exist on your SQL Server version, so why do you have this turned on?'
88018804
WHEN [T].[TraceFlag] = '8048' THEN '8048 enabled globally, which tries to reduce CMEMTHREAD waits on servers with a lot of logical processors.'
@@ -8849,8 +8852,7 @@ EXEC dbo.sp_MSforeachdb 'USE [?]; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITT
88498852
'Informational' AS FindingsGroup ,
88508853
'Recommended Trace Flag Off' AS Finding ,
88518854
'https://www.sqlskills.com/blogs/erin/query-store-trace-flags/' AS URL ,
8852-
'Trace Flag 7752 not enabled globally. It stops queries needing to wait on Query Store loading up after database recovery. It is so recommended that it is enabled by default as of SQL Server 2019.' AS Details
8853-
FROM #TraceStatus T
8855+
'Trace Flag 7752 not enabled globally. It stops queries needing to wait on Query Store loading up after database recovery. It is so recommended that it is enabled by default as of SQL Server 2019.' AS Details;
88548856
END;
88558857
END;
88568858

@@ -10260,9 +10262,9 @@ IF @ProductVersionMajor >= 10 AND NOT EXISTS ( SELECT 1
1026010262
+ N' Total Server Memory (GB): ' + CAST((CAST((pTotal.cntr_value / 1024.0 / 1024.0) AS DECIMAL(10,1))) AS NVARCHAR(100))
1026110263
FROM sys.dm_os_performance_counters pTarget
1026210264
INNER JOIN sys.dm_os_performance_counters pTotal
10263-
ON pTotal.object_name LIKE 'SQLServer:Memory Manager%'
10265+
ON pTotal.object_name LIKE N'%Memory Manager%'
1026410266
AND pTotal.counter_name LIKE 'Total Server Memory (KB)%'
10265-
WHERE pTarget.object_name LIKE 'SQLServer:Memory Manager%'
10267+
WHERE pTarget.object_name LIKE N'%Memory Manager%'
1026610268
AND pTarget.counter_name LIKE 'Target Server Memory (KB)%'
1026710269
END
1026810270

0 commit comments

Comments
 (0)