Technical Article

Backup Transaction Logs on all Databases

,

Here we go again. This is the last in my backup series that I use to do backups of the databases. As far as I know this should only kick out errors when there really is one.

This stored procedure is designed to take 4 parameters

@bksrv : This is the name or the IP address of the spooler or backup server to send to.

@user : Login name for the FTP server

@upass : Password for the FTP server

@path : Local path files will be written to first.

As always if you can do better or make this one better please do so and post it!

/*******************************************************************************************
usr_sp_backup_tran_db

by: Wesley D. Brown
Date 01/21/01
mod 08/30/01

This is the stored proc that I use to do full backups of my databases.
This script will backup locally then ship the file off via ftp and confirm that it is there.
It has some other basic error checking in it like drive space checking to make sure you 
don't blow up the server by filling up a drive.
Also, It will only delete files that are confirmed on the FTP site. If the file isn't there
it will not be deleted. You will recive an event. The script will run until the disk fills up
then you will get no more backups!

This stored procedure is designed to take 4 parameters
@bksrv	: This is the name or the IP address of the spooler or backup server to send to.
@user	: Login name for the FTP server
@upass	: Password for the FTP server
@path	: Local path files will be written to first.

This has only been tested under MS-SQL2k,MS-SQL 7,Win2k,WinNT4sp6a
********************************************************************************************/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[usr_sp_backup_tran_db]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[usr_sp_backup_tran_db]
GO
--drop it if it is already in the syscatalog

create procedure usr_sp_backup_tran_db @bksrv as varchar(255),
@user as varchar(100), @upass as varchar(100),@path as varchar(255) 
WITH RECOMPILE
-- we do with recompile because we are taking variables in and need to keep this
-- dynamic
as	

--declare variables
declare @errnum as int
declare @db_size as decimal
declare @db_holder as varchar(10)
declare @db as varchar(255)
declare @bkvar as varchar(255)
declare @cmdstr as varchar(255)
declare @time as varchar(255)
declare @date as varchar(255)
declare @tran as varchar(255)
declare @bpath as varchar(255)
declare @errmsg as varchar(255)
declare @cmdmsg as varchar(255)
declare @cmds as varchar(255)
declare @fname as varchar(255)
declare @bk_drive as varchar(1)
declare @db_bk_mode as varchar(255)
declare @diskfull as int

select @diskfull = 0
--set disk full flag to no 
declare Database_Cursor cursor for select name from sysdatabases where name <> 'tempdb' and name <> 'model' and name <> 'Northwind' and name <> 'Master'
--get all the db names and load up a cursor
open Database_Cursor
--open up the cursor
fetch next from Database_Cursor into @db
--load the first db name
while @@fetch_status = 0
--while we have db names run the loop!
	begin

		set @cmdstr = 'md '+@path+@db
		-- this is to make the local directories
		--create a seperate directory for every database
		exec @cmdmsg = master..xp_cmdshell @cmdstr, NO_OUTPUT
		--Directories are not removed with the files. This makes it easier to
		--recover a database with it's full/diff/trn logs all in one place
	
		--build the path and db backup file name
		--I use dbname_TLOG_yyyymmddhhmm.bak
		--the _TLOG_ tells me this is a transaction log backup
		select @bpath = rtrim(@path)+rtrim(@db)+'\'
		select @date = convert(varchar,getdate(),112)
		SELECT @time = REPLACE(convert(varchar,CURRENT_TIMESTAMP,114),':','')
		select @time = LEFT(@time,4)
		select @bkvar = rtrim(@bpath)+rtrim(@db)
		select @fname = @db+'_TLOG_'+@date+@time+'.trn'
		select @tran = @bkvar+'_TLOG_'+@date+@time
		select @tran = @tran+'.trn'
		select @bk_drive = LEFT(@path,1)

		--these are the two temp tables I use to find out how much free space we have
		--on the local server and if the database backup will fit on the local drive
		create table #result (output varchar(255) null)
		CREATE table #DriveTable (Drive varchar(10),[MB Free] int)
		INSERT into #Drivetable Exec master..xp_fixeddrives 
		CREATE table #helpdb (name varchar(100),db_size varchar(100),owner varchar(100),dbid varchar(100),created varchar(100),status varchar(255),compatibility_level varchar(100))
		INSERT into #helpdb Exec master..sp_helpdb 
		select @db_holder = (select db_size from #helpdb where name = @db)
		select @db_size = cast(rtrim(ltrim(@db_holder))as decimal)+1

		select @db_bk_mode =(select status from #helpdb where status like'%Recovery=SIMPLE%' and name = @db)
		--find out if the DB can have a tlog backup performed this is just to cut down on errors
		if @db_bk_mode <> ''
			begin
				drop table #result
				drop table #DriveTable
				drop table #helpdb
			end
			else
			begin
				if @db_size < (select [MB Free] from #DriveTable where drive = @bk_drive)
					begin
						--if it fits backup the db
						BACKUP LOG  @db
						TO DISK = @tran
					end
					else
					begin
						-- if it don't raise an error and move on to the next one
						select @errmsg = 'Backup drive does not have enough space to complete'
						raiserror (@errmsg,16,1)WITH LOG
						select @diskfull = 1
					end

				select @errnum = @@ERROR
				IF @errnum <> 0 or @diskfull = 1
					begin
						--if we get an error on the backup or if the disk is full err out
						select @errmsg = 'The backup for '+@db+' failed with error '+convert(varchar,@errnum)+' please see logs for details'
						raiserror (@errmsg,16,1)WITH LOG
						drop table #result
						drop table #DriveTable
						drop table #helpdb
					end
				else
					begin
						--else build the ftp command file needed to ship the backup to the backup server
						select @cmds = 'echo OPEN '+@bksrv+' > '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo USER '+@user+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds
		
						select @cmds = 'echo '+@upass+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo mkdir '+@@servername+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo cd '+@@servername+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo mkdir '+@db+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo cd '+@db+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds
	
						select @cmds = 'echo bin >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds

						select @cmds = 'echo send '+rtrim(@tran)+' '+rtrim(@fname)+' >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds
		
						select @cmds = 'echo ls >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds
				
						select @cmds = 'echo bye >> '+@bk_drive+':\ftpcmd.txt'
						exec @cmdstr = master..xp_cmdshell @cmds
	
						select @cmds = 'ftp -n -s:'+@bk_drive+':\ftpcmd.txt > '+@bk_drive+':\ftpout.txt'
						exec master..xp_cmdshell @cmds

						select @cmds = 'type '+@bk_drive+':\ftpout.txt'
						insert #result (output) exec master..xp_cmdshell @cmds

						select @cmds = 'del '+@bk_drive+':\ftpout.txt'
						exec master..xp_cmdshell @cmds

						if (select count(*) from #result where [output] like rtrim(@fname)+'%') > 0
							begin
								select @cmds = 'del '+rtrim(@tran)
								exec @cmdstr = master..xp_cmdshell @cmds

							end
						--clean up the temp tables
						drop table #result
						drop table #DriveTable
						drop table #helpdb

					end 
	
				--load the next db name
		end

		fetch next from Database_Cursor into @db
	end

--clean up the cursor
close Database_Cursor
deallocate Database_Cursor

Rate

5 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (1)

You rated this post out of 5. Change rating