Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
Community
Jacksonville SQL Server Users Group
Community
Annual Free Data Conference
Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
Super Hero Suit
Poll
Who is in the room?
Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
Questions
What is a database backup?
A copy of your data captured at a point in time, so you can put the database back the way it was.
…and it only counts if you can restore it.
Questions
Questions
Why should you back up your databases?
Because that's what you were hired to do.
Questions
Why should you restore your backups?
So you don't get fired!
A backup you've never tested is a hope, not a recovery plan.
Backup Types
What Backup Types Are There?
Recovery Models
What Backup Types are supported based on your Recovery Model
Recovery Model - Simple
Simple - Maximum Risk, No Point In Time Recovery
Recovery Model - Full/Bulk Logged
Full, Bulk Logged - Minimum Risk, Point in Time Recovery (RTO), Recovery Point (RPO)
Backup Type - Copy Only
Backup Type - Full
Backup Type - Transaction Logs
VLFs
Manage your VLFs (log fragmentation)
sys.dm_db_log_info (2016 SP2+/2017+) or DBCC LOGINFODBCC SHRINKFILE → regrow once via ALTER DATABASE … MODIFY FILE (SIZE = …); set autogrowth to a fixed chunk (e.g. 512 MB to 1 GB)VLFs
Pedro Lopes's VLF script (TigerToolbox)
SELECT DB_NAME(d.database_id) AS [Database],
COUNT(li.vlf_sequence_number) AS VLFs
FROM sys.databases d
CROSS APPLY sys.dm_db_log_info(d.database_id) li
GROUP BY d.database_id
HAVING COUNT(li.vlf_sequence_number) >= 50
ORDER BY VLFs DESC;Full script outputs Actual vs Potential VLFs and the exact SHRINKFILE + MODIFY FILE commands
https://github.com/microsoft/tigertoolbox/blob/master/Fixing-VLFs/Fix_VLFs.sql
Backup Retention
@CleanupTime, e.g. 7 to 14 daysRetention & long-term backups
RPO vs RTO - don't mix them up
RPO vs RTO
Software
Backup-DbaDatabase: full/diff/log, compression, encryption, striping, Azure blob, built-in verifyBackup software options
Cons
Full Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'FULL',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@CopyOnly = 'N',
@ChangeBackupType = 'Y',
@BackupSoftware = NULL,
@NumberOfFiles = 4,
@Description = 'Full Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 336,
@LogToTable = 'Y';
Differential Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'DIFF',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@CopyOnly = 'N',
@ChangeBackupType = 'N',
@BackupSoftware = NULL,
@NumberOfFiles = 4,
@Description = 'Diff Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 168,
@LogToTable = 'Y';
Transaction Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'LOG',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@BackupSoftware = NULL,
@NumberOfFiles = 1,
@Description = 'Tran Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 7,
@LogToTable = 'Y';
@BufferCount)@MaxTransferSize)@BlockSize)Performance
Compression
BACKUP DATABASE [StackOverflow]
TO
DISK = N'C:\DatabaseBackups\2025\StackOverflow2025.Compression.Medium.bak'
WITH
NOFORMAT,
NOINIT,
NAME = N'StackOverflow-Full Database Backup',
SKIP,
NOREWIND,
NOUNLOAD,
COMPRESSION (ALGORITHM = MS_XPRESS, LEVEL = MEDIUM),
STATS = 10,
CHECKSUM;
GO
Compression
| Backup | Time | Size | Savings | Restore |
|---|---|---|---|---|
| No compression | 38:45 | 258 GB | n/a | 8:22 |
| MS_XPRESS · Low | 27:28 | 128 GB | 50.4% | 9:21 |
| MS_XPRESS · Medium | 25:13 | 121 GB | 53.1% | 7:00 |
| MS_XPRESS · High | 30:18 | 121 GB | 53.1% | 7:01 |
| ZSTD · Low | 16:15 | 129 GB | 50.0% | 5:22 |
| ZSTD · Medium | 28:28 | 106 GB | 58.9% | 6:26 |
| ZSTD · High | 1:06:00 | 100 GB | 61.2% | 6:30 |
444 GB Stack Overflow · 16-core i9, 64 GB RAM, NVMe · each run verified. Winner: ZSTD Low.
ZSTD Benchmark
| Files | Time | Backup Type | Compression | Level |
|---|---|---|---|---|
| 2 | 9:34 | Full | ZSTD | Low |
| 4 | 9:20 | Full | ZSTD | Low |
| 8 | 9:36 | Full | ZSTD | Low |
| 12 | 8:42 | Full | ZSTD | Low |
| 16 | 8:38 | Full | ZSTD | Low |
444 GB Stack Overflow · ZSTD Low on every run · 16-core i9, 64 GB RAM, NVMe. Winner: 16 files at 8:38.
File Count
ZSTD takeaways
WITH NORECOVERY; only the final step is WITH RECOVERYSTOPAT = '2025-11-16 14:32:00' to recover to an exact secondSTANDBY leaves the DB readable between log restoresA backup is only as good as your last successful restore.
Restore
RESTORE VERIFYONLY only checks the media is readable - it does not prove the DB restoresRestore-DbaDatabase / Ola Hallengren DatabaseRestore)Test Restores
Always
Always
Let's talk backups - and restores.
Thank you for attending my session today.
If you have any additional questions, please don't hesitate to reach out.