Skip to content

Commit abedea4

Browse files
committed
Query changes to determine avg sizes/throughput etc
This changes the queries we used to populate the #Recoverability table - Use compressed backup size instead - Standardize output to MB to match other tables - Change column names and types (adds MB, changes to decimal) to standardize output - Respect passed in @starttime parameter for calculations
1 parent 6128ae7 commit abedea4

File tree

1 file changed

+44
-35
lines changed

1 file changed

+44
-35
lines changed

sp_BlitzBackups.sql

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -188,21 +188,21 @@ CREATE TABLE #Recoverability
188188
DatabaseName NVARCHAR(128),
189189
DatabaseGUID UNIQUEIDENTIFIER,
190190
LastBackupRecoveryModel NVARCHAR(60),
191-
FirstFullBackupSize BIGINT,
191+
FirstFullBackupSizeMB DECIMAL (18,2),
192192
FirstFullBackupDate DATETIME,
193-
LastFullBackupSize BIGINT,
193+
LastFullBackupSizeMB DECIMAL (18,2),
194194
LastFullBackupDate DATETIME,
195-
AvgFullBackupThroughput DECIMAL (18,2),
195+
AvgFullBackupThroughputMB DECIMAL (18,2),
196196
AvgFullBackupDurationSeconds INT,
197-
AvgDiffBackupThroughput DECIMAL (18,2),
197+
AvgDiffBackupThroughputMB DECIMAL (18,2),
198198
AvgDiffBackupDurationSeconds INT,
199-
AvgLogBackupThroughput DECIMAL (18,2),
199+
AvgLogBackupThroughputMB DECIMAL (18,2),
200200
AvgLogBackupDurationSeconds INT,
201-
AvgFullSize BIGINT,
202-
AvgDiffSize BIGINT,
203-
AvgLogSize BIGINT,
204-
IsBigDiff AS CASE WHEN (AvgFullSize - AvgDiffSize) * .01 > .40 AND (AvgFullSize > 1073741824) THEN 1 ELSE 0 END,
205-
IsBigLog AS CASE WHEN (AvgFullSize - AvgLogSize) * .01 > .20 AND (AvgFullSize > 1073741824) THEN 1 ELSE 0 END
201+
AvgFullSizeMB DECIMAL (18,2),
202+
AvgDiffSizeMB DECIMAL (18,2),
203+
AvgLogSizeMB DECIMAL (18,2),
204+
IsBigDiff AS CASE WHEN (AvgFullSizeMB - AvgDiffSizeMB) * .01 > .40 AND (AvgFullSizeMB > 1024) THEN 1 ELSE 0 END,
205+
IsBigLog AS CASE WHEN (AvgFullSizeMB - AvgLogSizeMB) * .01 > .20 AND (AvgFullSizeMB > 1024) THEN 1 ELSE 0 END
206206
);
207207

208208
CREATE TABLE #Trending
@@ -618,136 +618,144 @@ RAISERROR('Gathering RTO worst cases', 0, 1) WITH NOWAIT;
618618
SET @StringToExecute += N'
619619
UPDATE r
620620
SET r.LastBackupRecoveryModel = ca.recovery_model,
621-
r.LastFullBackupSize = ca.backup_size,
621+
r.LastFullBackupSizeMB = ca.compressed_backup_size,
622622
r.LastFullBackupDate = ca.backup_finish_date
623623
FROM #Recoverability r
624624
CROSS APPLY (
625-
SELECT TOP 1 b.recovery_model, b.backup_size, b.backup_finish_date
625+
SELECT TOP 1 b.recovery_model, (b.compressed_backup_size / 1048576.0) AS compressed_backup_size, b.backup_finish_date
626626
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset AS b
627627
WHERE r.DatabaseName = b.database_name
628628
AND r.DatabaseGUID = b.database_guid
629629
AND b.type = ''D''
630+
AND b.backup_finish_date > @StartTime
630631
ORDER BY b.backup_finish_date DESC
631632
) ca;'
632633

633634
IF @Debug = 1
634635
PRINT @StringToExecute;
635636

636-
EXEC sys.sp_executesql @StringToExecute;
637+
EXEC sys.sp_executesql @StringToExecute, N'@StartTime DATETIME2', @StartTime;
637638

638639
/*Find first backup size and date*/
639640
SET @StringToExecute =N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' + @crlf;
640641

641642
SET @StringToExecute += N'
642643
UPDATE r
643-
SET r.FirstFullBackupSize = ca.backup_size,
644+
SET r.FirstFullBackupSizeMB = ca.compressed_backup_size,
644645
r.FirstFullBackupDate = ca.backup_finish_date
645646
FROM #Recoverability r
646647
CROSS APPLY (
647-
SELECT TOP 1 b.backup_size, b.backup_finish_date
648+
SELECT TOP 1 (b.compressed_backup_size / 1048576.0) AS compressed_backup_size, b.backup_finish_date
648649
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset AS b
649650
WHERE r.DatabaseName = b.database_name
650651
AND r.DatabaseGUID = b.database_guid
651652
AND b.type = ''D''
653+
AND b.backup_finish_date > @StartTime
652654
ORDER BY b.backup_finish_date ASC
653655
) ca;'
654656

655657
IF @Debug = 1
656658
PRINT @StringToExecute;
657659

658-
EXEC sys.sp_executesql @StringToExecute;
660+
EXEC sys.sp_executesql @StringToExecute, N'@StartTime DATETIME2', @StartTime;
659661

660662

661663
/*Find average backup throughputs for full, diff, and log*/
662664
SET @StringToExecute = N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' + @crlf;
663665

664666
SET @StringToExecute += N'
665667
UPDATE r
666-
SET r.AvgFullBackupThroughput = ca_full.AvgFullSpeed,
667-
r.AvgDiffBackupThroughput = ca_diff.AvgDiffSpeed,
668-
r.AvgLogBackupThroughput = ca_log.AvgLogSpeed,
668+
SET r.AvgFullBackupThroughputMB = ca_full.AvgFullSpeed,
669+
r.AvgDiffBackupThroughputMB = ca_diff.AvgDiffSpeed,
670+
r.AvgLogBackupThroughputMB = ca_log.AvgLogSpeed,
669671
r.AvgFullBackupDurationSeconds = AvgFullDuration,
670672
r.AvgDiffBackupDurationSeconds = AvgDiffDuration,
671673
r.AvgLogBackupDurationSeconds = AvgLogDuration
672674
FROM #Recoverability AS r
673675
OUTER APPLY (
674676
SELECT b.database_name,
675-
CAST(AVG(( backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576 )) AS INT) AS AvgFullSpeed,
676-
CAST(AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS INT) AS AvgFullDuration
677+
AVG( b.compressed_backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576.0 ) AS AvgFullSpeed,
678+
AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS AvgFullDuration
677679
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset b
678680
WHERE r.DatabaseName = b.database_name
679681
AND r.DatabaseGUID = b.database_guid
680682
AND b.type = ''D''
681683
AND DATEDIFF(SECOND, b.backup_start_date, b.backup_finish_date) > 0
684+
AND b.backup_finish_date > @StartTime
682685
GROUP BY b.database_name
683686
) ca_full
684687
OUTER APPLY (
685688
SELECT b.database_name,
686-
CAST(AVG(( backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576 )) AS INT) AS AvgDiffSpeed,
687-
CAST(AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS INT) AS AvgDiffDuration
689+
AVG( b.compressed_backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576.0 ) AS AvgDiffSpeed,
690+
AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS AvgDiffDuration
688691
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset b
689692
WHERE r.DatabaseName = b.database_name
690693
AND r.DatabaseGUID = b.database_guid
691694
AND b.type = ''I''
692695
AND DATEDIFF(SECOND, b.backup_start_date, b.backup_finish_date) > 0
696+
AND b.backup_finish_date > @StartTime
693697
GROUP BY b.database_name
694698
) ca_diff
695699
OUTER APPLY (
696700
SELECT b.database_name,
697-
CAST(AVG(( backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576 )) AS INT) AS AvgLogSpeed,
698-
CAST(AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS INT) AS AvgLogDuration
701+
AVG( b.compressed_backup_size / ( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) / 1048576.0 ) AS AvgLogSpeed,
702+
AVG( DATEDIFF(ss, b.backup_start_date, b.backup_finish_date) ) AS AvgLogDuration
699703
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset b
700704
WHERE r.DatabaseName = b.database_name
701705
AND r.DatabaseGUID = b.database_guid
702706
AND b.type = ''L''
703707
AND DATEDIFF(SECOND, b.backup_start_date, b.backup_finish_date) > 0
708+
AND b.backup_finish_date > @StartTime
704709
GROUP BY b.database_name
705710
) ca_log;'
706711

707712
IF @Debug = 1
708713
PRINT @StringToExecute;
709714

710-
EXEC sys.sp_executesql @StringToExecute;
715+
EXEC sys.sp_executesql @StringToExecute, N'@StartTime DATETIME2', @StartTime;
711716

712717

713718
/*Find max and avg diff and log sizes*/
714719
SET @StringToExecute = N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' + @crlf;
715720

716721
SET @StringToExecute += N'
717722
UPDATE r
718-
SET r.AvgFullSize = fulls.avg_full_size,
719-
r.AvgDiffSize = diffs.avg_diff_size,
720-
r.AvgLogSize = logs.avg_log_size
723+
SET r.AvgFullSizeMB = fulls.avg_full_size,
724+
r.AvgDiffSizeMB = diffs.avg_diff_size,
725+
r.AvgLogSizeMB = logs.avg_log_size
721726
FROM #Recoverability AS r
722727
OUTER APPLY (
723-
SELECT b.database_name, AVG(b.backup_size) AS avg_full_size
728+
SELECT b.database_name, AVG(b.compressed_backup_size / 1048576.0) AS avg_full_size
724729
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset AS b
725730
WHERE r.DatabaseName = b.database_name
726731
AND r.DatabaseGUID = b.database_guid
727732
AND b.type = ''D''
733+
AND b.backup_finish_date > @StartTime
728734
GROUP BY b.database_name
729735
) AS fulls
730736
OUTER APPLY (
731-
SELECT b.database_name, AVG(b.backup_size) AS avg_diff_size
737+
SELECT b.database_name, AVG(b.compressed_backup_size / 1048576.0) AS avg_diff_size
732738
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset AS b
733739
WHERE r.DatabaseName = b.database_name
734740
AND r.DatabaseGUID = b.database_guid
735741
AND b.type = ''I''
742+
AND b.backup_finish_date > @StartTime
736743
GROUP BY b.database_name
737744
) AS diffs
738745
OUTER APPLY (
739-
SELECT b.database_name, AVG(b.backup_size) AS avg_log_size
746+
SELECT b.database_name, AVG(b.compressed_backup_size / 1048576.0) AS avg_log_size
740747
FROM ' + QUOTENAME(@MSDBName) + N'.dbo.backupset AS b
741748
WHERE r.DatabaseName = b.database_name
742749
AND r.DatabaseGUID = b.database_guid
743750
AND b.type = ''L''
751+
AND b.backup_finish_date > @StartTime
744752
GROUP BY b.database_name
745753
) AS logs;'
746754

747755
IF @Debug = 1
748756
PRINT @StringToExecute;
749757

750-
EXEC sys.sp_executesql @StringToExecute;
758+
EXEC sys.sp_executesql @StringToExecute, N'@StartTime DATETIME2', @StartTime;
751759

752760
/*Trending - only works if backupfile is populated, which means in msdb */
753761
IF @MSDBName = N'msdb'
@@ -812,12 +820,13 @@ RAISERROR('Returning data', 0, 1) WITH NOWAIT;
812820
LEFT JOIN #Trending t
813821
ON r.DatabaseName = t.DatabaseName
814822
AND r.DatabaseGUID = t.DatabaseGUID
823+
WHERE r.LastBackupRecoveryModel IS NOT NULL
815824
ORDER BY r.DatabaseName
816825

817826

818827
RAISERROR('Rules analysis starting', 0, 1) WITH NOWAIT;
819828

820-
/*Looking for non-Agent backups. Agent handles most backups, can expand or change depending on what we find out there*/
829+
/*Looking for out of band backups by finding most common backup operator user_name and noting backups taken by other user_names*/
821830

822831
SET @StringToExecute = N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' + @crlf;
823832

@@ -1073,7 +1082,7 @@ IF @ProductVersionMajor >= 12
10731082
100 AS [Priority],
10741083
b.database_name AS [Database Name],
10751084
''Uncompressed backups'' AS [Finding],
1076-
''The database '' + QUOTENAME(b.database_name) + '' has had '' + CONVERT(VARCHAR(10), COUNT(*)) + '' uncompressed backups in the last 30 days. This is a free way to save time and space. And SPACETIME if your version of SQL supports it.'' AS [Warning]
1085+
''The database '' + QUOTENAME(b.database_name) + '' has had '' + CONVERT(VARCHAR(10), COUNT(*)) + '' uncompressed backups in the last 30 days. This is a free way to save time and space. And SPACETIME. If your version of SQL supports it.'' AS [Warning]
10771086
FROM ' + QUOTENAME(@MSDBName) + '.dbo.backupset AS b
10781087
WHERE backup_size = compressed_backup_size AND type = ''D''
10791088
AND b.backup_finish_date >= DATEADD(DAY, -30, SYSDATETIME())

0 commit comments

Comments
 (0)