stored proc for removing old backups inside
joshmurrah
Posts: 24
I wrote this stored proc to remove all old backups, keeping only what's needed for one full restore... we have pretty tight space limitations, due to the size of some of the databases we run, and SQL Backup's built-in ERASEFILES option isn't too smart (can remove all full's when ran with a diff for example)... Hopefully somebody can get some use out of this. This is installed as part of our standard backup/maint. package, in SQL Server Agent, in a job step after the full/diff backups.
CREATE PROCEDURE pr_maint_ArchiveBackups @Database SYSNAME, @BackupPath VARCHAR(255), @BackupType VARCHAR(255) AS /* Written by Josh Murrah, jmurrah@gtl.net This stored procedure will take care of doing the housekeeping on old/un-needed backups... it assumes the following: 1) You only want one good set of backups. There's no provision here for multiple sets. 2) You have the database name and type (FULL, LOG, DIFF) , both surrounded with underscores somewhere in the filename, usually with _<DATABASE>_<TYPE>_ in the file name format under Options in Red-Gate SQL Backup GUI and doing <AUTO> during backup for the filename specification... I use: <SERVER>_<DATABASE>_<TYPE>_<DATETIME yyyymmddhhmm> 3) You backup each server/instance to a seperate folder, or at least have unique DB names. 4) This does work with UNC paths, just make sure Red-Gate has permissions to do it first. In this case, you'd need to do a NET USE \\server\share passwd /user:xxx /persistent:yes at some point to get the Red-Gate software working, this uses the same stored credintials. */ SET NOCOUNT ON DECLARE @Sql VARCHAR(255) DECLARE @LatestBackupFileId INT DECLARE @counter INT DECLARE @output VARCHAR(255) DECLARE @ErrorMsg VARCHAR(255) CREATE TABLE #filetable ( Ident INT IDENTITY(1, 1), line VARCHAR(128)) CREATE TABLE #delcommand ( Ident INT IDENTITY(1, 1), command VARCHAR(255)) CREATE TABLE #errors ( result VARCHAR(255)) --check backup path SELECT @Sql='dir '+@BackupPath INSERT INTO #errors(result) EXEC master..xp_cmdshell @Sql IF (SELECT COUNT(*) FROM #errors WHERE result LIKE '%File Not Found%') > 0 BEGIN SET @ErrorMsg = 'Backup path '+@BackupPath+' does not exist' GOTO pr_maint_ArchiveBackups_ERROR END TRUNCATE TABLE #errors --get a file listing for the Database in question, from the backup path SELECT @Sql='dir /b /o:-d '+@BackupPath+'\*_'+@Database+'_*.sqb' INSERT INTO #filetable(line) EXEC master..xp_cmdshell @Sql --error checking for file list IF @output <> 0 BEGIN SET @ErrorMsg = 'error executing '+@Sql GOTO pr_maint_ArchiveBackups_ERROR END --last line in a dir/b command comes back NULL DELETE FROM #filetable where line IS NULL --get the latest full backup file for the database in question and build deletion commands IF @BackupType='FULL' BEGIN SELECT @LatestBackupFileId=(SELECT TOP 1 Ident FROM #filetable WHERE line LIKE ('%'+@Database+'%') AND line LIKE '%_FULL_%' ORDER BY Ident) INSERT INTO #delcommand(command) SELECT 'del '+@BackupPath+'\'+line FROM #filetable WHERE (Ident > @LatestBackupFileId AND line LIKE '%_LOG_%') OR (Ident > @LatestBackupFileId AND line LIKE '%_DIFF_%') OR (Ident > @LatestBackupFileId AND line LIKE '%_FULL_%') END ELSE BEGIN SELECT @LatestBackupFileId=(SELECT TOP 1 Ident FROM #filetable WHERE line LIKE ('%'+@Database+'%') AND line LIKE '%_DIFF_%' ORDER BY Ident) INSERT INTO #delcommand(command) SELECT 'del '+@BackupPath+'\'+line FROM #filetable WHERE (Ident > @LatestBackupFileId AND line LIKE '%_LOG_%') END --loop through each command and execute. SELECT @counter=1 WHILE @counter <= (SELECT MAX(Ident) FROM #delcommand) BEGIN SELECT @Sql=command FROM #delcommand WHERE Ident=@counter INSERT INTO #errors(result) EXEC @output=master..xp_cmdshell @Sql IF @output <> 0 BEGIN SET @ErrorMsg = 'error executing '+@Sql GOTO pr_maint_ArchiveBackups_ERROR END SELECT @counter=@counter+1 END IF (SELECT COUNT(*) FROM #errors WHERE result IS NOT NULL) > 0 BEGIN SET @ErrorMsg = 'Unable to delete all old backups for [' + @Database+'].' GOTO pr_maint_ArchiveBackups_ERROR END --no errors, so skip to cleanup GOTO pr_maint_ArchiveBackups_EXIT --if there was an error, jump to here pr_maint_ArchiveBackups_ERROR: RAISERROR(@ErrorMsg, 16, 1) pr_maint_ArchiveBackups_EXIT: --cleanup DROP TABLE #errors DROP TABLE #delcommand DROP TABLE #filetable
-Josh Murrah
Comments
SQL Backup Consultant Developer
Associate, Yohz Software
Beyond compression - SQL Backup goodies under the hood, updated for version 8