Skip to content

for #3959 - added check for backup to NUL device#3960

Merged
BrentOzar merged 3 commits intoBrentOzarULTD:devfrom
VladDBA:sp_BlitzBackups-bkp-to-NUL-check
Apr 26, 2026
Merged

for #3959 - added check for backup to NUL device#3960
BrentOzar merged 3 commits intoBrentOzarULTD:devfrom
VladDBA:sp_BlitzBackups-bkp-to-NUL-check

Conversation

@VladDBA
Copy link
Copy Markdown
Contributor

@VladDBA VladDBA commented Apr 25, 2026

Closes #3959

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new rule to sp_BlitzBackups (CheckId 14) to detect backups written to the Windows NUL device, highlighting both “phantom but non-chain-breaking” cases (COPY_ONLY or SIMPLE) and potentially chain-impacting cases (non-copy-only in non-SIMPLE).

Changes:

  • Add CheckId 14 query to flag databases with recent backups directed to NUL.
  • Split results into two findings based on is_copy_only / recovery_model to indicate risk level.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sp_BlitzBackups.sql Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@BrentOzar BrentOzar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VladDBA you don't have to worry about fixing my notes - I'm going to make AI do it. 🤖

Comment thread sp_BlitzBackups.sql Outdated
INNER JOIN ' + QUOTENAME(@MSDBName) + '.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id
WHERE UPPER(bmf.physical_device_name)= N''NUL''
AND (bs.is_copy_only = 1 OR bs.recovery_model = N''SIMPLE'')
AND bs.backup_finish_date >= DATEADD(DAY, -30, SYSDATETIME())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hard-coding 30 days back, let's use the @starttime variable, which is set via the @HoursBack input parameter on the stored proc.

Comment thread sp_BlitzBackups.sql Outdated
INNER JOIN ' + QUOTENAME(@MSDBName) + '.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id
WHERE UPPER(bmf.physical_device_name)= N''NUL''
AND bs.is_copy_only = 0 AND bs.recovery_model <> N''SIMPLE''
AND bs.backup_finish_date >= DATEADD(DAY, -30, SYSDATETIME())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hard-coding 30 days back, let's use the @starttime variable, which is set via the @HoursBack input parameter on the stored proc.

Comment thread sp_BlitzBackups.sql Outdated
100 AS [Priority],
bs.database_name AS [Database Name],
''Backup to NUL device'' AS [Finding],
''The database '' + QUOTENAME(bs.database_name) + '' has had '' + CONVERT(VARCHAR(10), COUNT(*)) + '' backups to the NUL device in the last 30 days, the latest one being on ''+
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the 30 day reference and just say "backups to the NUL device, the latest one being on" since we're using the @HoursBack parameter.

Comment thread sp_BlitzBackups.sql Outdated
100 AS [Priority],
bs.database_name AS [Database Name],
''Backup to NUL device without COPY_ONLY'' AS [Finding],
''The database '' + QUOTENAME(bs.database_name) + '' is not in SIMPLE recovery model and has had '' + CONVERT(VARCHAR(10), COUNT(*)) + '' backups to the NUL device in the last 30 days, the latest one being on ''+
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the 30 day reference and just say "backups to the NUL device, the latest one being on" since we're using the @HoursBack parameter.

@VladDBA
Copy link
Copy Markdown
Contributor Author

VladDBA commented Apr 25, 2026

Hey @BrentOzar,

Got it. Just note that I've used that date filter because I've seen it used in some of the previous checks (e.g. check IDs 7 and 12)

Honor the @HoursBack parameter instead of a hard-coded 30-day window,
matching the convention used elsewhere in this proc, and drop the
"in the last 30 days" wording from the warning text now that the window
is dynamic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@BrentOzar BrentOzar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done, Claude3PO.

@BrentOzar BrentOzar added this to the 2026-07 Release milestone Apr 26, 2026
@BrentOzar
Copy link
Copy Markdown
Member

Thanks @VladDBA for the pull request. Merging into the dev branch, will be in the next release with credit to you in the release notes.

@BrentOzar BrentOzar merged commit 69ffdd0 into BrentOzarULTD:dev Apr 26, 2026
pull Bot pushed a commit to SammyEnigma/SQL-Server-First-Responder-Kit that referenced this pull request Apr 26, 2026
The "No CHECKSUMS" (CheckId 7) and "Uncompressed backups" (CheckId 12)
checks were filtering on a hard-coded 30-day window via
DATEADD(DAY, -30, SYSDATETIME()) instead of the user-supplied
@HoursBack window already exposed via @starttime. That ignored
@HoursBack and made the warning text inconsistent with the actual
window being analyzed.

Replace both filters with @starttime, pass @starttime through
sp_executesql, and drop the "in the last 30 days" / "in the past 30
days" wording from the findings now that the window is dynamic. Same
treatment as PR BrentOzarULTD#3960 applied to CheckId 14.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sp_BlitzBackups: New check - Backup to NUL device

4 participants