In summary, the main steps are as follows;
1- on primary database: create a job to backup transaction logs regularly
2- on primary database: share the transaction log backup directory.
3- backup and restore the database to be log shipped from prımary to secondary database
4- on secondary database: create the following structure (tables and procedures)
5- on secondary database: create the copy and load jobs via the created structure
6- on secondary database: monitor the process
There are 3 stored procedures and 3 tables to create;
USE msdb CREATE TABLE backup_movement_plans ( plan_id UNIQUEIDENTIFIER NOT NULL PRIMARY KEY CLUSTERED, plan_name sysname NULL, source_dir NVARCHAR(256) NOT NULL, destination_dir NVARCHAR(256) NOT NULL, database_subdir BIT NOT NULL DEFAULT (1) ) USE msdb CREATE TABLE backup_movement_plan_databases ( plan_id UNIQUEIDENTIFIER NOT NULL FOREIGN KEY REFERENCES backup_movement_plans(plan_id), source_database sysname NOT NULL, destination_database sysname NOT NULL, source_server sysname NOT NULL DEFAULT (@@servername), load_delay INT NOT NULL DEFAULT(0), -- In minutes load_all BIT NOT NULL DEFAULT(1), retention_period INT NOT NULL DEFAULT(48), -- In hours last_file_copied NVARCHAR(256) NULL, date_last_copied DATETIME NULL, last_file_loaded NVARCHAR(256) NULL, date_last_loaded DATETIME NULL ) USE msdb CREATE TABLE backup_movement_plan_history ( sequence_id INT NOT NULL IDENTITY UNIQUE CLUSTERED, plan_id UNIQUEIDENTIFIER NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), plan_name sysname NOT NULL DEFAULT ('All ad-hoc plans'), destination_server sysname NOT NULL DEFAULT (@@servername), source_server sysname NOT NULL DEFAULT (@@servername), source_database sysname NOT NULL, destination_database sysname NOT NULL, activity BIT NOT NULL DEFAULT (0), succeeded BIT NOT NULL DEFAULT (1), num_files INT NOT NULL DEFAULT (0), last_file NVARCHAR(256) NULL, end_time DATETIME NOT NULL DEFAULT (GETDATE()), duration INT NULL DEFAULT (0), error_number INT NOT NULL DEFAULT (0), message NVARCHAR(512) NULL ) USE msdb CREATE PROCEDURE sp_create_backup_movement_plan @name sysname, @source_dir VARCHAR(256), @dest_dir VARCHAR(256), @sub_dir BIT = 1, -- Each database has it's own sub-directory @load_job_freq INT = 5, -- In Minutes @copy_job_freq INT = 5 -- In Minutes AS BEGIN BEGIN TRANSACTION SET NOCOUNT ON SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS ON DECLARE @PlanID uniqueidentifier DECLARE @CopyJobName sysname DECLARE @LoadJobName sysname DECLARE @CopyCommand VARCHAR(500) DECLARE @LoadCommand VARCHAR(500) DECLARE @ReturnCode INT -- Create a GUID for the plan SELECT @PlanID = NEWID() -- Check if a plan with the same name exists IF (EXISTS (SELECT * FROM msdb.dbo.backup_movement_plans WHERE plan_name = @name )) BEGIN RAISERROR('A backup movement plan with the same name already exists. Specify a different name.'', 16, 1) GOTO QuitWithRollback END -- Insert plan in the table INSERT msdb.dbo.backup_movement_plans (plan_id, plan_name, source_dir, destination_dir, database_subdir) VALUES (@PlanID, @name, @source_dir, @dest_dir, @sub_dir) SELECT @CopyJobName = N'Copy Job For ' + @name SELECT @LoadJobName = N'Load Job For ' + @name SELECT @CopyCommand = N'EXECUTE master.dbo.xp_sqlmaint ''-CopyPlanName "' + @name + '" '' ' SELECT @LoadCommand = N'EXECUTE master.dbo.xp_sqlmaint ''-LoadPlanName "' + @name + '" '' ' -- Create the load job EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_name = @LoadJobName IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_name = @LoadJobName, @step_id=1, @step_name = N'step1', @command = @LoadCommand, @subsystem = N'TSQL', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2, @flags = 4 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_name = @LoadJobName, @freq_subday_interval = @load_job_freq, @name = N'sch1', @enabled = 1, @freq_type = 4, @active_start_date = 19980402, @active_start_time = 0, @freq_interval = 1, @freq_subday_type = 4, @freq_relative_interval = 0, @freq_recurrence_factor = 0, @active_end_date = 99991231, @active_end_time = 235959 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_name = @LoadJobName, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -- Create the Copy Job EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_name = @CopyJobName IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_name = @CopyJobName, @step_id = 1, @step_name = N'step1', @command = @CopyCommand, @subsystem = N'TSQL', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2, @flags = 4 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_name = @CopyJobName, @freq_subday_interval = @copy_job_freq, @name = N'sch1', @enabled = 1, @freq_type = 4, @active_start_date = 19980402, @active_start_time = 0, @freq_interval = 1, @freq_subday_type = 4, @freq_relative_interval = 0, @freq_recurrence_factor = 0, @active_end_date = 99991231, @active_end_time = 235959 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_name = @CopyJobName, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION EndSave: END USE msdb CREATE PROCEDURE sp_add_db_to_backup_movement_plan @plan_id uniqueidentifier = NULL, @plan_name sysname = NULL, @source_db sysname, @dest_db sysname, @load_delay INT = 0, -- In Minutes @load_all BIT = 1, @source_server sysname = @@servername, @retention_period INT = 48 -- In Hours. 0 implies do not delete files AS BEGIN SET NOCOUNT ON SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS ON DECLARE @PlanID uniqueidentifier if((@plan_id IS NULL) AND (@plan_name IS NULL)) BEGIN RAISERROR('You must supply the plan name or the plan id.', 16, 1) RETURN(1) END IF (@plan_id IS NULL) BEGIN IF (NOT EXISTS (SELECT * FROM msdb.dbo.backup_movement_plans WHERE plan_name = @plan_name ) ) BEGIN RAISERROR('Backup movement plan with this name was not found.', 16, 1) RETURN(1) END IF (SELECT COUNT(*) FROM msdb.dbo.backup_movement_plans WHERE plan_name = @plan_name) > 1 BEGIN RAISERROR('There are more than one backup movement plans with this name.', 16, 1) RETURN(1) END SELECT @PlanID = plan_id FROM msdb.dbo.backup_movement_plans WHERE plan_name = @plan_name END ELSE BEGIN SELECT @PlanID = @plan_id IF (NOT EXISTS (SELECT * FROM msdb.dbo.backup_movement_plans WHERE plan_id = @plan_id ) ) BEGIN RAISERROR('Backup movement plan with this id.', 16, 1) RETURN(1) END IF (SELECT COUNT(*) FROM msdb.dbo.backup_movement_plans WHERE plan_id = @plan_id) > 1 BEGIN RAISERROR('There are more than one backup movement plans with this id.', 16, 1) RETURN(1) END END IF (EXISTS ( SELECT * FROM msdb.dbo.backup_movement_plan_databases WHERE plan_id = @PlanID AND source_database = @source_db AND destination_database = @dest_db )) BEGIN RAISERROR('These databases are already included in this plan', 16, 1) RETURN(1) END INSERT msdb.dbo.backup_movement_plan_databases (plan_id, source_database, destination_database, load_delay, load_all, source_server, retention_period) VALUES (@PlanID, @source_db, @dest_db, @load_delay, @load_all, @source_server, @retention_period) END
After creating the infrastructure you can create the transaction log backup copy and load jobs by running the following script. After running the script logshipping started via the created jobs and the process can be monitored by creating and using the following stored procedure.
exec msdb..sp_create_backup_movement_plan @name = "DB01_logshipping", @source_dir = "\\PRMDB01\trnlogs", @dest_dir = "D:\logshipping\", @sub_dir = "DB01", @load_job_freq =30, @copy_job_freq = 30 exec msdb..sp_add_db_to_backup_movement_plan @plan_name = "DB01_logshipping", @source_db = "DB01", @dest_db = "DB01", @load_delay = 10, @load_all = 1, @source_server = 'PRMYDB01', @retention_period = 30 --in days
Here is the stored procedure to monitor the log shipping process.
USE msdb CREATE PROCEDURE dbo.sp_log_ship_status @p_svr varchar( 30 ) = NULL, @p_db varchar( 30 )= NULL AS Begin set nocount on DECLARE @dest_db char(30), @history_id int, @time_delta int CREATE TABLE #table ( destination_db CHAR(30), time_delta INT) DECLARE log_ship_cursor CURSOR FOR SELECT destination_database from backup_movement_plan_databases OPEN log_ship_cursor FETCH NEXT FROM log_ship_cursor into @dest_db WHILE @@FETCH_STATUS = 0 BEGIN set nocount on select @history_id = (select max(restore_history_id) from restorehistory where destination_database_name = @dest_db) select @time_delta = (select datediff(mi, (select backup_start_date from backupset where backup_set_id = (select backup_set_id from restorehistory where restore_history_id = @history_id)), getdate())) INSERT INTO #table VALUES( @dest_db, @time_delta) FETCH NEXT from log_ship_cursor into @dest_db end close log_ship_cursor DEALLOCATE log_ship_cursor SELECT "Primary Srv" = CONVERT(char(30),source_server), "Primary DB" = CONVERT(char(30),source_database), "Secondary DB" = CONVERT(char(30),destination_database), "Delta" = time_delta, "Load All" = CASE WHEN (load_all = 0) THEN "No" ELSE "Yes" end, "Load Delay" = load_delay, "Save Period" = retention_period, "Last File Copied" = CONVERT(char(75),last_file_copied), "Copy Logged Time" = date_last_copied, "Last File Loaded" = CONVERT(char(75),last_file_loaded), "Load Logged Time" = date_last_loaded FROM msdb..backup_movement_plan_databases, #table WHERE (@p_svr is NULL or source_server like @p_svr) AND (@p_db is NULL or source_database like @p_db) AND destination_database = destination_db drop table #table END ------------------------- -- it seems it is working ------------------------- dbo.log_ship_status /* Primary Srv Primary DB Secondary DB Delta Load All Load Delay Save Period Last File Copied Copy Logged Time Last File Loaded Load Logged Time ----------- --------------- ----------------- -------- -------- ----------- ----------- ------------------------------------------------ ----------------------- ------------------------------------------- ----------------------- crmsbdb01 siebeldb siebeldb 34 Yes 1 60 \\crmsbdb01\t-logs\siebeldb\siebeldb_tlog_201... 2011-07-13 15:10:01.610 E:\t-logs\siebeldb\siebeldb_tlog_2011071314... 2011-07-13 15:00:12.563 crmsbdb01 IVR_INTEGRATE IVR_INTEGRATE 34 Yes 1 60 \\crmsbdb01\t-logs\IVR_INTEGRATE\IVR_INTEGRAT... 2011-07-13 15:10:03.313 E:\t-logs\IVR_INTEGRATE\IVR_INTEGRATE_tlog_... 2011-07-13 14:50:07.627 */
No comments:
Post a Comment