Analyzing SQL Server backups

Analyzing SQL Server backups

Analyzing SQL Server backups

SQLShack

SQL Server training Español

Analyzing SQL Server backups

March 8, 2016 by Shawn Melton

Introduction

Database backups are important and always something you should have in any environment. Outside of needing them to restore a given database they have some information that can be useful in certain situations. One situation I found them convenient is with consolidation projects. If the databases are online you can obviously go to the source SQL Server instance to gather that information, but as a consultant I don’t necessarily have access to every environment. You may have the same issue if you are being brought into a project and your customer or department manager just wants you to advise on how you would setup the server. One easy request is to have them point you where the backups are stored and ensure you have access to the files. The backup of a database can tell you everything from the compatibility level of the database to the date the database was created. You can find out the physical file names, size, and even the disk block size where the database was stored on the source server. The size is the information I am most interested in with consolidation projects. I can utilize this to analyze how much storage space I will need for the new server, and work out how I am going to need that storage carved up. After I get all that information together I pull it into Excel and then utilize pivot tables to calculate out the storage totals for all the databases, and can also create tables on drive letter or file type. I found PowerShell to be the best method, for me, to pull all the information out of the backup files into a format I could bring into Excel. I did actually consider writing PowerShell that would put it directly into Excel for me but that is not a strong area I use often so decided against it for right now. In this article I want to share the tool I created for this in PowerShell. I will then go through how I build the Pivot tables in Excel.

The Script

Let me introduce you to, “GetBackupInformation.ps1”. This script will look like it does a good bit, but is pretty basic. I have included help information along with comments in the script itself to help with two things: (1) You learn how to use the script and (2) you possibly learn some new things with PowerShell. A few points about this script: Minimum required is PowerShell 3.0 or higher. You will need access to at least one SQL Server instance, but it can be Express Edition. The data is output to the console or a parameter is provided to spit it to a CSV file. ** The Connection String and Delimiter parameters I set to default vales, so you can change those to your environment or pass them each time. ** I added the ability for this script to output to the console in the event you may want to send this data to another source altogether (Power BI, database, etc.). It is up to you once you have the output to take it and do what you want. The background of this script came from having to use this process a few times, I decided to finally sit down and make it more robust. It could have been made complex by using SMO to read the backup files but I like shortcuts. I settled on just using T-SQL RESTORE command to read the backup file information, this is the reason a SQL Server instance is required. The script will simply execute “RESTORE FILELISTONLY” and “RESTORE HEADERONLY” against each backup file path that is passed to the script, which even on large backups these commands should only take a few seconds to execute, (should). The script will handle reading a single backup, multiple backup files, or a single backup file with multiple backups (backup set). 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 <# .SYNOPSIS Script to pull out information about backup files .DESCRIPTION Script to pull out information of a single or multiple backup files .PARAMETER connectionString String. Connection string to connect to SQL Server instance. .PARAMETER bacupfiles System.IO.FileInfo array. File information array. .PARAMETER csvFile String. Full path to CSV file for output of backup information, file is deleted if it exist. .PARAMETER delimiter String. Delimiter for CSV file. .EXAMPLE Output backup information to console of all backups in directory, using SQL Server instance on local host GetBackupInformation -cn "Server=localhost;Integrated Security=true;Initial Catalog=master;" -backupFiles (Get-ChildItem C:\temp\backups) .EXAMPLE Output backup information of single backup to console, using SQL Server instance on local host GetBackupInformation -cn "Server=localhost;Integrated Security=true;Initial Catalog=master;" -backupFiles (Get-ChildItem C:\temp\backups\MyBackup.bak) .EXAMPLE Output backup information to CSV of all backups in directory, using SQL Server instance on local host GetBackupInformation -cn "Server=localhost;Integrated Security=true;Initial Catalog=master;" -backupFiles (Get-ChildItem C:\temp\backups) -csvFile C:\temp\BackupInfo.csv -delimiter ""#>[cmdletbinding()]param( [Parameter(Mandatory = $false,Position = 0)] [Alias("cn")] [string]$connectionString = "Server=localhost\number12;Integrated Security=true;Initial Catalog=master;", [Parameter(Mandatory = $false,Position = 1)] [Alias("bkfiles")] [System.IO.FileInfo[]]$backupFiles, [Parameter(Mandatory = $false,Position = 2)] [Alias("csv")] [string]$csvFile, [Parameter(Mandatory = $false,Position = 3)] [string]$delimiter = "" ) $sqlcn = New-Object System.Data.SqlClient.SqlConnection $sqlcn.ConnectionString = $connectionString try { $sqlcn.Open(); } catch { $errText = $error[0].ToString() if ($rrText.Contains("Failed to connect")) { Write-Verbose "Connection failed." Return "Connection failed to $server" $error[0] select * } } if ($csvFile) { if (Test-Path $csvFile) { Remove-Item $csvFile -Force } } $result = [pscustomobject]@{BackupFile=$null; DatabaseName=$null; CompatibilityLevel=0; RecoveryModel=$null; LogicalName=$null; FileGroupName=$null; sizeMB=0; sizeGB=0; Type=$null; LocalDrive=$null} foreach ($b in $backupFiles) { $qryHeader = @"RESTORE HEADERONLY FROM DISK = N'$($b.FullName)';"@ $sqlcmd = $sqlcn.CreateCommand() $sqlcmd.CommandText= $qryHeader $adp = New-Object System.Data.SqlClient.SqlDataAdapter $sqlcmd $dataHeader = New-Object System.Data.DataSet $adp.Fill($dataHeader) Out-Null $headerRowCount = $dataHeader.Tables[0].Rows.Count if ($headerRowCount -eq 1) { $qryFilelist = @"RESTORE FILELISTONLY FROM DISK = N'$($b.FullName)';"@ $sqlcmd.CommandText= $qryFilelist $dataFilelist = New-Object System.Data.DataSet $adp.Fill($dataFilelist) Out-Null $fileListRowCount = $dataFilelist.Tables[0].Rows.Count for ($f=0; $fileListRowCount -gt $f; $f++) { $result.BackupFile = $b.Name $result.DatabaseName = $dataHeader.Tables[0].Rows.DatabaseName $result.CompatibilityLevel = $dataHeader.Tables[0].Rows.CompatibilityLevel $result.RecoveryModel = $dataHeader.Tables[0].Rows.RecoveryModel $result.LogicalName = $dataFilelist.Tables[0].Rows[$f].LogicalName $result.FileGroupName = $dataFilelist.Tables[0].Rows[$f].FileGroupName $result.sizeMB = $dataFilelist.Tables[0].Rows[$f].size/1mb $result.sizeGB = $dataFilelist.Tables[0].Rows[$f].size/1gb $result.Type = $dataFilelist.Tables[0].Rows[$f].Type $result.LocalDrive = $null if ($csvFile) { $result Export-Csv -Path $csvFile -Delimiter $delimiter -NoClobber -NoTypeInformation -Append } else { $result } } #end for fileListRowCount } # end single backup set else { #clearing the contents of the dataset $dataFileList.Reset() for ($h=0; $headerRowCount -gt $h; $h++) { #for getting backup info within backup set need to specify file number $fileNum = 1 $qryFilelist = @"RESTORE FILELISTONLY FROM DISK = N'$($b.FullName)' WITH FILE = $($fileNum);"@ $sqlcmd.CommandText= $qryFilelist $dataFilelist = New-Object System.Data.DataSet $adp.Fill($dataFilelist) Out-Null $fileListRowCount = $dataFilelist.Tables[0].Rows.Count for ($f=0; $fileListRowCount -gt $f; $f++) { $result.BackupFile = $b.Name $result.DatabaseName = $dataHeader.Tables[0].Rows[$h].DatabaseName $result.CompatibilityLevel = $dataHeader.Tables[0].Rows[$h].CompatibilityLevel $result.RecoveryModel = $dataHeader.Tables[0].Rows[$h].RecoveryModel $result.LogicalName = $dataFilelist.Tables[0].Rows[$f].LogicalName $result.FileGroupName = $dataFilelist.Tables[0].Rows[$f].FileGroupName $result.sizeMB = $dataFilelist.Tables[0].Rows[$f].size/1mb $result.sizeGB = $dataFilelist.Tables[0].Rows[$f].size/1gb $result.Type = $dataFilelist.Tables[0].Rows[$f].Type $result.LocalDrive = $null if ($csvFile) { $result Export-Csv -Path $csvFile -Delimiter $delimiter -NoClobber -NoTypeInformation -Append } else { $result } } #end for fileListRowCount #this is to clear the dataset as we are done with te current data $dataFileList.Reset() #incrementing file number to get the next backup set $fileNum++ } #end for headerRowCount } } #end foreach file#close the connection to SQL Server$sqlcn.Close(); #start up Excel automatically by uncommenting below line#Start-Process Excel.exe

Example Data

The below screen shot illustrates how the script can be used and provides a sample of what backup information I am pulling: The last command I am utilizing the CSV parameter, and will use that file to import into Excel. One note, if you notice the “LocalDrive” column is empty. I went ahead and just added this column, but do not currently populate it until I bring the data into Excel. If you have a standard drive letter mapping for data and log drives, you could add some logic to the script to have it populate this column if you wish.

Building the Pivot

I start out just bringing the CSV file into Excel and doing a bit of formatting. I also filled in the “LocalDrive” columns with some drive letters for reference on drive size. Now you go into the Insert ribbon and click on “PivotTable”: Click OK A new worksheet is going to be created and you will be presented with something similar to the below screenshot. You can now just click on the check box for the data you want to include, and Excel will take a guess where you want it to go (Rows, Columns, etc.). I however tend to just drag and drop where I want it to go. So just drag the following rows to the noted areas: Rows: DatabaseName Columns: LocalDrive Values: sizeMB (or sizeGB if you wish) In the end it should look something like this: Now I want to add another PivotTable to this same spreadsheet, this new table will show me the size of each database based on “Type” column. You can repeat the above steps and the only change is when you get to the step 2, before you click on OK perform the following step: Select “Existing Worksheet” Now click on the location selector This is just going to point Excel where you want the new table created. Click on “Sheet3” Click on cell “A20” Click on location selector to back to the previous screen Click OK. To create the next table, you follow same as we did above with the exception that “Columns” you would want to use “Type” instead of “LocalDrive” as we did previously. This should leave you with a table similar to below:

Summary

I hope this script will provide you with some insightful information with any consolidation project you may be working on, or even just in your day-to-day work as a DBA. I have found PivotTables in Excel can help make some tasks as a DBA very quick and easy. If you have not noticed this can also be a good tool for visually showing the numbers in a manner upper management can understand why that purchase request is being submitted for more storage.

References

Creating Pivot Tables in Excel T-SQL command RESTORE FILELISTONLY T-SQL command RESTORE HEADERONLY
Author Recent Posts Shawn MeltonShawn Melton is a SQL Server consultant at Pythian, a global IT services company based out of Ottawa - Canada.

After spending 6 years in the system and network administration world he found he enjoyed working and learning SQL Server. Since 2010 he has been involved in SQL Server.

He is passionate about PowerShell and automation around SQL Server and Windows. His experience is focused in SQL Server administration and some BI development (SSIS, SSRS).

View all posts by Shawn Melton Latest posts by Shawn Melton (see all) Learning PowerShell and SQL Server – Introduction - April 23, 2018 Connecting PowerShell to SQL Server – Using a Different Account - January 24, 2017 How to secure your passwords with PowerShell - January 18, 2017

Related posts

Understanding Log Sequence Numbers for SQL Server Transaction Log Backups and Full Backups How-to: SQL Server file-snapshot backups in Azure How to configure Azure SQL Database long-term retention (LTR) backups AWS RDS SQL Server recovery models, backups and restores AWS RDS SQL Server migration using native backups 1,738 Views

Follow us

Popular

SQL Convert Date functions and formats SQL Variables: Basics and usage SQL PARTITION BY Clause overview Different ways to SQL delete duplicate rows from a SQL Table How to UPDATE from a SELECT statement in SQL Server SQL Server functions for converting a String to a Date SELECT INTO TEMP TABLE statement in SQL Server SQL WHILE loop with simple examples How to backup and restore MySQL databases using the mysqldump command CASE statement in SQL Overview of SQL RANK functions Understanding the SQL MERGE statement INSERT INTO SELECT statement overview and examples SQL multiple joins for beginners with examples Understanding the SQL Decimal data type DELETE CASCADE and UPDATE CASCADE in SQL Server foreign key SQL Not Equal Operator introduction and examples SQL CROSS JOIN with examples The Table Variable in SQL Server SQL Server table hints – WITH (NOLOCK) best practices

Trending

SQL Server Transaction Log Backup, Truncate and Shrink Operations Six different methods to copy tables between databases in SQL Server How to implement error handling in SQL Server Working with the SQL Server command line (sqlcmd) Methods to avoid the SQL divide by zero error Query optimization techniques in SQL Server: tips and tricks How to create and configure a linked server in SQL Server Management Studio SQL replace: How to replace ASCII special characters in SQL Server How to identify slow running queries in SQL Server SQL varchar data type deep dive How to implement array-like functionality in SQL Server All about locking in SQL Server SQL Server stored procedures for beginners Database table partitioning in SQL Server How to drop temp tables in SQL Server How to determine free space and file size for SQL Server databases Using PowerShell to split a string into an array KILL SPID command in SQL Server How to install SQL Server Express edition SQL Union overview, usage and examples

Solutions

Read a SQL Server transaction logSQL Server database auditing techniquesHow to recover SQL Server data from accidental UPDATE and DELETE operationsHow to quickly search for SQL database data and objectsSynchronize SQL Server databases in different remote sourcesRecover SQL data from a dropped table without backupsHow to restore specific table(s) from a SQL Server database backupRecover deleted SQL data from transaction logsHow to recover SQL Server data from accidental updates without backupsAutomatically compare and synchronize SQL Server dataOpen LDF file and view LDF file contentQuickly convert SQL code to language-specific client codeHow to recover a single table from a SQL Server database backupRecover data lost due to a TRUNCATE operation without backupsHow to recover SQL Server data from accidental DELETE, TRUNCATE and DROP operationsReverting your SQL Server database back to a specific point in timeHow to create SSIS package documentationMigrate a SQL Server database to a newer version of SQL ServerHow to restore a SQL Server database backup to an older version of SQL Server

Categories and tips

►Auditing and compliance (50) Auditing (40) Data classification (1) Data masking (9) Azure (295) Azure Data Studio (46) Backup and restore (108) ►Business Intelligence (482) Analysis Services (SSAS) (47) Biml (10) Data Mining (14) Data Quality Services (4) Data Tools (SSDT) (13) Data Warehouse (16) Excel (20) General (39) Integration Services (SSIS) (125) Master Data Services (6) OLAP cube (15) PowerBI (95) Reporting Services (SSRS) (67) Data science (21) ►Database design (233) Clustering (16) Common Table Expressions (CTE) (11) Concurrency (1) Constraints (8) Data types (11) FILESTREAM (22) General database design (104) Partitioning (13) Relationships and dependencies (12) Temporal tables (12) Views (16) ►Database development (418) Comparison (4) Continuous delivery (CD) (5) Continuous integration (CI) (11) Development (146) Functions (106) Hyper-V (1) Search (10) Source Control (15) SQL unit testing (23) Stored procedures (34) String Concatenation (2) Synonyms (1) Team Explorer (2) Testing (35) Visual Studio (14) DBAtools (35) DevOps (23) DevSecOps (2) Documentation (22) ETL (76) ►Features (213) Adaptive query processing (11) Bulk insert (16) Database mail (10) DBCC (7) Experimentation Assistant (DEA) (3) High Availability (36) Query store (10) Replication (40) Transaction log (59) Transparent Data Encryption (TDE) (21) Importing, exporting (51) Installation, setup and configuration (121) Jobs (42) ►Languages and coding (686) Cursors (9) DDL (9) DML (6) JSON (17) PowerShell (77) Python (37) R (16) SQL commands (196) SQLCMD (7) String functions (21) T-SQL (275) XML (15) Lists (12) Machine learning (37) Maintenance (99) Migration (50) Miscellaneous (1) ►Performance tuning (869) Alerting (8) Always On Availability Groups (82) Buffer Pool Extension (BPE) (9) Columnstore index (9) Deadlocks (16) Execution plans (125) In-Memory OLTP (22) Indexes (79) Latches (5) Locking (10) Monitoring (100) Performance (196) Performance counters (28) Performance Testing (9) Query analysis (121) Reports (20) SSAS monitoring (3) SSIS monitoring (10) SSRS monitoring (4) Wait types (11) ►Professional development (68) Professional development (27) Project management (9) SQL interview questions (32) Recovery (33) Security (84) Server management (24) SQL Azure (271) SQL Server Management Studio (SSMS) (90) SQL Server on Linux (21) ►SQL Server versions (177) SQL Server 2012 (6) SQL Server 2016 (63) SQL Server 2017 (49) SQL Server 2019 (57) SQL Server 2022 (2) ►Technologies (334) AWS (45) AWS RDS (56) Azure Cosmos DB (28) Containers (12) Docker (9) Graph database (13) Kerberos (2) Kubernetes (1) Linux (44) LocalDB (2) MySQL (49) Oracle (10) PolyBase (10) PostgreSQL (36) SharePoint (4) Ubuntu (13) Uncategorized (4) Utilities (21) Helpers and best practices BI performance counters SQL code smells rules SQL Server wait types © 2022 Quest Software Inc. ALL RIGHTS RESERVED. GDPR Terms of Use Privacy
Share:
0 comments

Comments (0)

Leave a Comment

Minimum 10 characters required

* All fields are required. Comments are moderated before appearing.

No comments yet. Be the first to comment!

Analyzing SQL Server backups | Trend Now | Trend Now