Skip to main content

There is more than one way to find database backup files

I was told during the initial implementation of Ola Hallengren's Maintenance Solution at my workplace that it was too hard to find database backup files in the default folder structure his solution creates.  The concern was that it took too long to find the oldest file or the biggest file when trying to resolve a space issue on a database server.

Ola's solution creates a folder tree with these elements. Drive:\root\ServerName\DatabaseName\TypeOfBackup

You specify the backup drive and root folder using the Directory parameter of the DatabaseBackup stored procedure.

When I originally solved this problem, Windows XP was in use.  I wish I had spent more time figuring this out because I had to modify Ola's database backup procedure to dump all the backups into one folder in order for the DBA teams to sign off on the initial deployment.

It only takes a couple of minutes to search using Windows Explorer in Windows XP but finding files in a folder tree has gotten much easier on Windows 7 and higher.  

Given Windows XP's imminent retirement, I will only cover Windows 7 or higher.

Start Windows Explorer and navigate to the backup root folder on the server.

Type *.bak in the Search field in the upper right hand corner of Windows Explorer on Windows 7 or 8 and press Enter.

By default, Windows Explorer in Windows 7 and higher searches sub-folders.

The Search result returns all the database backups in the entire folder tree.
The two requirements given were finding files by size or date.

Both are easily solved by clicking on the appropriate header. 
In the search result, headers are clickable and allow sorting by any column. 
So, click on Date Modified to find files by date or click on Size to find files by size.
Finding files to delete by size or date is done in less than a minute.
You can even save searches now.

Microsoft's GUI interfaces are sufficient if you only have a few servers to check. But GUIs don't scale when you need to do the same task on a few hundred servers. So, you'll need to do a bit of scripting.  
Google answered this question pretty quickly.
Find the ten largest files in a directory.

get-childitem -path  C:\Backup -recurse | ?{ -not $_.PSIsContainer } | sort-object Length -desc | select-object fullname -f 10
gci C:\Backup -r |  ?{ -not $_.PSIsContainer } | sort Length -desc | select fullname -f 10

Finding the oldest ten files in a folder tree by date
get-childitem C:\Backup  -recurse | ?{ -not $_.PSIsContainer } | sort-object LastWriteTime | select-object fullname -f 10
gci C:\Backup  -r | ?{ -not $_.PSIsContainer } | sort LastWriteTime | select fullname -f 10
gci \\ServerName\FolderName\dump_data  -r |  ?{ -not $_.PSIsContainer } | sort Length -desc | select fullname -f 10

Including ?{ -not $_.PSIsContainer } in the pipeline ensures only files not folders are included in the results. 

If you want to run these commands on multiple servers, wrap them in a foreach loop that reads a list of text files from a server. Check out my PowerShell posts for examples. 

Old School
If you are not comfortable with PowerShell, the venerable dir command from the Windows command line is still available.

Oldest files first in a folder tree
dir /S /OD | more

Files ordered by size largest first in folder tree
dir /S /O-S | more

So, it doesn't take very long to find the largest or oldest database backup using any of these methods.  Which means I didn't need to modify Ola's scripts for the next release. ;-)


Popular posts from this blog

Modifying Endpoint URLs on Availability Group Replicas

I recently had to modify the Endpoint URLs on our SQL Server Availability Group replicas.  The reason for this blog post is that I could not answer the following questions: Do I need to suspend data movement prior to making this change?  Would this change require a restart of the database instance? I spent enough time searching on my own to no avail that I tossed the question to the #sqlhelp hashtag on Twitter and Slack but didn't get an answer prior to executing the change request. After reading the relevant documentation, I think it's probably a good idea to suspend data movement for this change. The T-SQL is straightforward.  USE MASTER GO ALTER AVAILABILITY GROUP [AG1]  MODIFY REPLICA ON 'SQL2012-1' WITH (ENDPOINT_URL = 'TCP://'); ALTER AVAILABILITY GROUP [AG1]  MODIFY REPLICA ON 'SQL2012-2' WITH (ENDPOINT_URL = 'TCP://'); ALTER AVAILABILITY GROUP [AG2]  MODIFY REPLICA ON 'SQL2012-1

PASS Summit 2012 - Gone to the mountain and returned wiser I began my conference schedule by attending Allen White's pre-con "Automating SQL Server with PowerShell". Allen starts by telling everyone in attendance “We all can learn something from each other.  We all know something that someone else doesn't.” I thought this was a great intro and inspiration to the attendees to participate in the PASS Community. Later in the day while answering a question, Allen tells us he is not a PowerShell expert.  Which kind of surprises me.  He says he’s just figured out how to use PowerShell with SQL Server. I think he is being a bit too humble.   Afterwards, I talk to Allen about a script I’m working on and he points me in a direction that hopefully will help me finish it. All in all, it was e xcellent day of training on using PowerShell with SQL Server. As the main conference began, I tweeted about how tight the seating was in some of the rooms on the first day of the main conference.   After the Sum

PowerShell: Quick SQL Server Version Check

I have to keep track of our SQL Server version inventory.  The goal is to reduce the SQL Server 2000 population as fast as possible. The following PowerShell script will produce a csv file containing the database server name and the version of SQL Server it's running. 1: ## Get SQL Version installed on multiple servers ## 2: ## ./sqlver.ps1 3: $start = get-date 4: write-host "Start: " $start 5:   6: [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null 7:   8: $FilePath = "C:\Output" 9: $OutFile = Join-Path -path $FilePath -childPath ("SQLVersions_" + (get-date).toString('yyyyMMdd_hhmmtt') + ".log") 10:   11: # Version inventory 12: @(foreach ($svr in get-content "C:\Input\AllLOBServers.txt") 13: { 14: $s = New-Object "Microsoft.SqlServer.Management.Smo.Server" $svr 15: $s | select Name, Version 16:   17: }) | export-csv -noType $OutFile 18:   1