Zip Backups and Copy to Secondary (free)

,

This is pretty simple. If you have set your default backup location within the registry, and you are using log-shipping as your method of disaster recovery, then all the variables are in your msdb database. This works for SQL 2005.

Compression requires twice the space of the actual backups, but if your in the middle of a disaster recovery, it is nice to have the backup on the server you actually need it to be on.

There are several awesome utilities from various vendors that do this much better, but my number one requirement was that it had to be free! In subsequent iterations, I also transfer the results of sp_help_revlogin, and the results of a "roles and permissions" script.

Enjoy and thanks to all the scripting gurus out there for many of the bits and pieces we hobble together for something like this.

 

Jeff

/*
--********************************************************
-- 
-- 
-- Designed to ship backup files from primary log-shipping server to secondary log
-- shipping server for DR reasons.
--
-- Date Who What
-- ----------    ----------- -----------------------------------------------
-- 12/30/2008 Jeff Bennett Initial 
-- 1/09/2009 Jeff Bennett Genericized

stored procedure is named DBA.dbo.usp_compress_and_send
input parameter can be either 'A' for 'ALL', 'U' for 'USER', or 'D' for 'DR'
input parameter defaults to 'A'
procedure compresses ALL backups and only ships those that meet criteria of input parameter.
Testing History.....


*/
CREATE PROCEDURE dbo.usp_compress_and_send
@dbtype char(1) = 'A'
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON

-- ******************************
-- initial variable declaration
-- ******************************
 --input variable can be 'A' for'ALL', 'U' for 'USER', or 'D' for 'DR'
 SET @dbtype = UPPER(@dbtype)
 IF (@dbtype not in ('A','U','D')) OR (@dbtype IS NULL) 
    BEGIN
    SET @dbtype = 'A' -- Default value
    END

-- *************************************************
-- find default backup directory location on primary
-- *************************************************
DECLARE @rc int, @dir nvarchar(4000)
SET @dir = ''
EXEC @rc = master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',N'Software\Microsoft\MSSQLServer\MSSQLServer',N'BackupDirectory', @dir output, 'no_output'

-- *********************************************************************************************
-- This command will zip up ALL *.BAK files in directory specified and directories below this
-- *********************************************************************************************
DECLARE @forfilezipcommand    varchar(255)
DECLARE @lastbackupdate varchar(10)
SET @lastbackupdate = convert(varchar(10),getdate()- 1,101)

--****************************************************
-- this command will compress all files and give them .zip extension, while retaining original file names
--****************************************************
SET @forfilezipcommand = 'FORFILES /p ' + @dir + ' /m *.bak /d ' + @lastbackupdate + ' /c "D:\gzip.exe -N -S.zip *.BAK"'
EXEC xp_cmdshell @forfilezipcommand 

-- ***********************************************
-- Determine where to copy files to on remote server (used log-shipping tables)
-- our backup directories do not retain instance name format, so I strip these out below
-- ***********************************************
DECLARE @secondserver varchar(30)
SELECT * INTO #lsps FROM msdb..log_shipping_primary_secondaries
IF @@ROWCOUNT <> 0
 BEGIN
     SELECT @secondserver = '\\' + secondary_server FROM #lsps
    -- PRINT @secondserver
     SET @secondserver = REPLACE(@secondserver, '\instancename1','')
     SET @secondserver = REPLACE(@secondserver,'\anyinstancename2','')
     SET @secondserver = REPLACE(@secondserver,'\someotherinstancename','')
 END
ELSE
 BEGIN     
    RAISERROR('ZIP and SHIP process requires a secondary server to send backup files',16,1)
 END
DROP TABLE #lsps

CREATE TABLE #DBS (DBName varchar(35),UserDB bit , Logshipped bit)
INSERT INTO #DBS SELECT name, 0, 0 FROM master..sysdatabases
UPDATE #DBS SET UserDB = 1 where DBName not in ('master', 'msdb','tempdb','model','DBA')
UPDATE #DBS SET Logshipped = 1 where DBName in (select secondary_database from msdb..log_shipping_primary_secondaries)

DECLARE @copycommand varchar(255)
DECLARE @dbfilename varchar(30)
DECLARE @userdb bit
DECLARE @logshipped bit

DECLARE filecursor CURSOR FOR
    SELECT DBName, UserDB, Logshipped FROM #DBS

OPEN filecursor

-- ***********************************************
-- Determine which files to copy based on input var
-- ***********************************************

FETCH NEXT FROM filecursor INTO @dbfilename, @userdb, @logshipped
WHILE (@@FETCH_STATUS <> -1)
 BEGIN
 IF ((@dbtype is NULL) or (@dbtype = 'A'))
        BEGIN
            -- set logic to create copy statement and execute entire set of files
            SET @copycommand = 'COPY /Y /B ' + @dir + '\' + @dbfilename + '*.zip ' + @secondserver + '\' + REPLACE(@dir,':','$')
--            PRINT @copycommand
            EXEC xp_cmdshell @copycommand
     END 
    IF @dbtype = 'U' AND @userdb = 1
        BEGIN
            -- set logic to create copy statements only for user defined databases
            SET @copycommand = 'COPY /Y /B ' + @dir + '\' + @dbfilename + '*.zip ' + @secondserver + '\' + REPLACE(@dir,':','$') 
--            PRINT @copycommand
            EXEC xp_cmdshell @copycommand
        END
    IF @dbtype = 'D' AND @logshipped = 1
        BEGIN
            -- set logic to create copy statements only for logshipped databases
            SET @copycommand = 'COPY /Y /B ' + @dir + '\' + @dbfilename + '*.zip ' + @secondserver + '\' + REPLACE(@dir,':','$') 
--            PRINT @copycommand
            EXEC xp_cmdshell @copycommand
        END
    FETCH NEXT FROM filecursor INTO @dbfilename, @userdb, @logshipped
 END

-- *******************************************
-- Deallocate and drop tables no longer needed
-- *******************************************
CLOSE filecursor
DEALLOCATE filecursor
DROP TABLE #DBS

END

Rate

Share

Share

Rate