How to Find Last Full Backup Time and Size for Database? – Interview Question of the Week #173

Question: How do you find the last full backup time and size for each database? Read the retained history in msdb.

The newest sealed backup jar stands before older archives with a measuring ribbon

During a Comprehensive Database Performance Health Check, an absent backup plan worries me more than a slow query. I’ve seen teams jump into action when we discover that gap. I’ve also seen it remain unresolved after we discuss the risk.

This query gives us a starting point: the latest recorded full backup for each current database. It keeps databases without matching history in the results, with null backup fields. It excludes tempdb, which isn’t backed up.

WITH RankedBackups AS
(
    SELECT database_name, backup_finish_date, backup_size,
           compressed_backup_size, is_copy_only,
           ROW_NUMBER() OVER
           (
               PARTITION BY database_name
               ORDER BY backup_finish_date DESC, backup_set_id DESC
           ) AS rn
    FROM msdb.dbo.backupset
    WHERE type = 'D' AND backup_finish_date IS NOT NULL
)
SELECT CONVERT(nvarchar(128), SERVERPROPERTY(N'ServerName')) AS server_name,
       d.name AS database_name,
       b.backup_finish_date,
       CAST(b.backup_size / 1048576.0 AS decimal(20,2)) AS backup_MiB,
       CAST(b.compressed_backup_size / 1048576.0 AS decimal(20,2)) AS stored_MiB,
       b.is_copy_only
FROM sys.databases AS d
LEFT JOIN RankedBackups AS b ON b.database_name = d.name AND b.rn = 1
WHERE d.database_id <> 2
ORDER BY d.name;

The ranking selects one completed full backup per database name. Sorting by database name alone would list history without identifying the latest backup. Joining backupmediafamily also adds rows for each media family, which isn’t needed for this question.

backup_MiB reports the backup’s uncompressed size. stored_MiB reports the stored backup size, including compression when used. These are backup metadata values, not a measurement of every byte in a multi-backup media file.

What this check proves

A null date means this instance’s retained history has no matching completed full backup. It doesn’t prove the database has never been backed up. History can be purged, and an availability group backup can run on another replica.

The name match also needs care after renames, restores or name reuse. Review the backup identity and location when investigating a particular database. The is_copy_only flag helps distinguish an ad hoc copy-only full backup from a conventional full backup.

I’d be happy to find a recent date, but I wouldn’t stop there. Confirm the files are available and test restoration. A successful backup record cannot tell us whether today’s recovery procedure will work.

What do you use to monitor backup freshness? Share the script, and how you check restores, in the comments.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Backup and Restore, SQL Scripts, SQL Server
Previous Post
How to Search Special Characters in Table Column? – Interview Question of the Week #172
Next Post
How to Generate Fibonacci Series for the First 1000 Values? – Interview Question of the Week #174

Related Posts

5 Comments. Leave new

  • If looking for the last backup would it be better to only get the last backup date using a CTE like this:

    With MostRecent
    As (Select
    msdb.dbo.backupset.database_name,
    Max(msdb.dbo.backupset.backup_finish_date) As max_backup_finish_date
    From
    msdb.dbo.backupset
    Group By
    msdb.dbo.backupset.database_name)
    Select
    Convert(char(100),Serverproperty(‘Servername’)) As Server,
    msdb.dbo.backupset.database_name,
    msdb.dbo.backupset.backup_finish_date,
    Cast(msdb.dbo.backupset.backup_size As numeric(35,2)) / 1048576.0 As backup_size_MB
    From
    msdb.dbo.backupmediafamily
    Inner Join msdb.dbo.backupset
    On msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id
    Join MostRecent As mr
    On
    mr.database_name = backupset.database_name And
    mr.max_backup_finish_date = backupset.backup_finish_date
    Where msdb.dbo.backupset.type = ‘D’
    Order By
    msdb.dbo.backupset.database_name;

    Reply
  • Where we need to run this query?

    Reply
  • This query returns one row for each file in the backup set, for multiple backups of the same database. If what is wanted is one row for the most recent full backup of each database, that can be obtained using the following query adapted from https://dba.stackexchange.com/questions/150241/t-sql-query-for-date-of-last-full-backup-size-and-location :

    WITH LastBackUp AS
    (
    SELECT bs.database_name,
    bs.compressed_backup_size,
    bs.backup_size,
    bs.backup_start_date,
    bmf.physical_device_name,
    Position = ROW_NUMBER() OVER( PARTITION BY bs.database_name ORDER BY bs.backup_start_date DESC )
    FROM msdb.dbo.backupmediafamily bmf
    JOIN msdb.dbo.backupmediaset bms ON bmf.media_set_id = bms.media_set_id
    JOIN msdb.dbo.backupset bs ON bms.media_set_id = bs.media_set_id
    WHERE bs.[type] = ‘D’
    AND bs.is_copy_only = 0
    )
    SELECT
    database_name AS [Database],
    CAST(compressed_backup_size / 1073741824 AS DECIMAL(10, 4)) AS [CompressedBackupSizeGB],
    CAST(backup_size / 1073741824 AS DECIMAL(10, 4)) AS [BackupSizeGB],
    backup_start_date AS [Last Full DB Backup Date],
    physical_device_name AS [Backup File Location]
    FROM LastBackUp
    WHERE Position = 1
    ORDER BY [Database];

    Reply
  • how about if we want to know the last full back up only?

    Reply
  • Hi, I get actual or physical backup file size .bak is different from this value size from query result,
    I used compressed backup.

    how to get size physical backup size actual from query.

    thanks

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.