info@techdevops.com
|
437-991-3573
|
Data Engineering Services
|
TechDevOps.com
|
| | | |
Experts in Microsoft SQL Server on Windows, Linux, Containers | Clusters, Always On, FCI | Migrations, Cloud, Performance
|
| | | |
|
Log Shipping Real-Time Processing Engine
by BF (Principal Consultant; Architecture; Engineering)
2018-11-02
Update:
Version 2:
Log Shipping Real-Time Processing Engine v2
--Execute on Log Shipping Secondary Server
- Replace DB1, DB2, DB3, DB4, DB5, DB6, DB7 with your Database Names (But do not replace these: @IsDB1, etc)
USE Master; GO
SET NOCOUNT ON
DECLARE @backupPath NVARCHAR(500) DECLARE @cmd NVARCHAR(500) DECLARE @fileList1 TABLE (backupFile NVARCHAR(255)) DECLARE @fileList2 TABLE (backupFile NVARCHAR(255)) DECLARE @backupFile NVARCHAR(500) DECLARE @IsDB1 bit DECLARE @IsDB2 bit DECLARE @IsDB3 bit DECLARE @IsDB4 bit DECLARE @IsDB5 bit DECLARE @IsDB6 bit DECLARE @IsDB7 bit DECLARE @jobname varchar(150) SET @backupPath = 'F:\LogShipping\Backups'
SELECT reh.Destination_Database_Name, reh.Restore_Type, reh.User_Name, reh.Restore_Date, bas.First_LSN, bas.Last_LSN, bas.Backup_Start_Date, bas.Backup_Finish_Date, bmf.Physical_Device_Name, LEFT(bmf.Physical_Device_Name,LEN(bmf.Physical_Device_Name) - charindex('\',reverse(bmf.Physical_Device_Name),1) + 1) as 'path', RIGHT(bmf.Physical_Device_Name, CHARINDEX('\', REVERSE(bmf.Physical_Device_Name)) -1) as 'file_name', bas.Server_Name, bas.Recovery_Model, bas.Compressed_Backup_Size, bms.Is_Compressed, bas.Compatibility_Level INTO #TMP1 FROM msdb.dbo.RESTOREHISTORY reh WITH (nolock) Inner Join msdb.dbo.backupset bas on reh.backup_set_id = bas.backup_set_id Inner Join msdb.dbo.backupmediaset bms on bas.backup_set_id = bms.media_set_id Inner Join msdb.dbo.backupmediafamily bmf on bas.media_set_id = bmf.media_set_id
SET @cmd = 'DIR /b "' + @backupPath + '"'
INSERT INTO @fileList1(backupFile) EXEC master.sys.xp_cmdshell @cmd
Delete from @filelist1 where backupfile IS NULL
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Starting - Log Shipping Processing check: Backup File --> Copy File --> Restore File' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> List File System Backup Files Outstanding:' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT CHAR(10)
If NOT EXISTS (Select BackupFile from @fileList1 where backupFile not in (Select [file_name] from #TMP1)) BEGIN PRINT ' - No Backup Files to process' PRINT CHAR(10)
PRINT '>>> Finished' DROP table #TMP1
RETURN
END
--Select BackupFile from @fileList1 where backupFile not in (Select [file_name] from #TMP1) order by backupFile asc
DECLARE @name1 nvarchar(128)
DECLARE cur1 CURSOR FOR Select BackupFile from @fileList1 where backupFile not in (Select [file_name] from #TMP1) order by backupFile asc
OPEN cur1
FETCH NEXT FROM cur1 INTO @name1;
WHILE @@FETCH_STATUS = 0 BEGIN IF CHARINDEX('DB1',@name1) > 0 Begin Set @IsDB1 = 1 PRINT 'DB1:' + CHAR(10) + @name1 End; IF CHARINDEX('DB2',@name1) > 0 Begin Set @IsDB2 = 1 PRINT 'DB2:' + CHAR(10) + @name1 End; IF CHARINDEX('DB3',@name1) > 0 Begin Set @IsDB3 = 1 PRINT 'DB3:' + CHAR(10) + @name1 End; IF CHARINDEX('DB4',@name1) > 0 Begin Set @IsDB4 = 1 PRINT 'DB4:' + CHAR(10) + @name1 End; IF CHARINDEX('DB5',@name1) > 0 Begin Set @IsDB5 = 1 PRINT 'DB5:' + CHAR(10) + @name1 End; IF CHARINDEX('DB6',@name1) > 0 Begin Set @IsDB6 = 1 PRINT 'DB6:' + CHAR(10) + @name1 End; IF CHARINDEX('DB7',@name1) > 0 Begin Set @IsDB7 = 1 PRINT 'DB7:' + CHAR(10) + @name1 End;
FETCH NEXT FROM cur1 INTO @name1; END
CLOSE cur1; DEALLOCATE cur1;
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Starting Log Shipping Copy Job(s)...' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT CHAR(10)
If @IsDB1 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB1%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB1%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB2 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB2%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB2%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB3 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB3%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB3%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB4 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB4%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB4%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB5 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB5%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB5%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB6 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB6%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB6%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB7 = 1 Begin IF NOT EXISTS ( SELECT sj.name--,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Copy%' AND sj.name like '%DB7%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Copy%' AND name like '%DB7%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Delay for 5s for Copy File processing...' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
WAITFOR DELAY '00:00:05';
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Starting Log Shipping Restore Job(s)...' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT CHAR(10)
If @IsDB1 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB1%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB1%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB2 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB2%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB2%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB3 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB3%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB3%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB4 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB4%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB4%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB5 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB5%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB5%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB6 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB6%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB6%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
If @IsDB7 = 1 Begin IF NOT EXISTS ( SELECT sj.name,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND aj.run_Requested_date IS NOT NULL AND sj.name like '%Restore%' AND sj.name like '%DB7%' and not exists( SELECT 1 from msdb..sysjobactivity new WHERE new.job_id = aj.job_id AND new.start_execution_date > aj.start_execution_date ) ) Begin Set @jobname = (Select name from msdb.dbo.sysjobs where category_id = 6 and name like '%Restore%' AND name like '%DB7%') EXEC msdb.dbo.sp_start_job @jobname; End Else Begin Print '>>> Job is already running - ' + @jobname End End
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Delay for 5s for Restore File processing...' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
WAITFOR DELAY '00:00:05';
PRINT CHAR(10)
SELECT reh.Destination_Database_Name, reh.Restore_Type, reh.User_Name, reh.Restore_Date, bas.First_LSN, bas.Last_LSN, bas.Backup_Start_Date, bas.Backup_Finish_Date, bmf.Physical_Device_Name, LEFT(bmf.Physical_Device_Name,LEN(bmf.Physical_Device_Name) - charindex('\',reverse(bmf.Physical_Device_Name),1) + 1) as 'path', RIGHT(bmf.Physical_Device_Name, CHARINDEX('\', REVERSE(bmf.Physical_Device_Name)) -1) as 'file_name', bas.Server_Name, bas.Recovery_Model, bas.Compressed_Backup_Size, bms.Is_Compressed, bas.Compatibility_Level INTO #TMP2 FROM msdb.dbo.RESTOREHISTORY reh WITH (nolock) Inner Join msdb.dbo.backupset bas on reh.backup_set_id = bas.backup_set_id Inner Join msdb.dbo.backupmediaset bms on bas.backup_set_id = bms.media_set_id Inner Join msdb.dbo.backupmediafamily bmf on bas.media_set_id = bmf.media_set_id
SET @cmd = 'DIR /b "' + @backupPath + '"'
INSERT INTO @fileList2(backupFile) EXEC master.sys.xp_cmdshell @cmd
Delete from @filelist2 where backupfile IS NULL
PRINT CHAR(10)
PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT '>>> Start - List File System Backup Files Outstanding:' PRINT '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' PRINT CHAR(10)
If NOT EXISTS (Select BackupFile from @fileList2 where backupFile not in (Select [file_name] from #TMP2)) BEGIN PRINT ' - No Backup Files to process' PRINT CHAR(10)
PRINT '>>> Finished' DROP Table #TMP1 DROP Table #TMP2
RETURN
END
DECLARE @name2 nvarchar(128)
DECLARE cur2 CURSOR FOR Select BackupFile from @fileList2 where backupFile not in (Select [file_name] from #TMP2) order by backupFile asc
OPEN cur2
FETCH NEXT FROM cur2 INTO @name2; WHILE @@FETCH_STATUS = 0 BEGIN PRINT @name2 FETCH NEXT FROM cur2 INTO @name2; END
CLOSE cur2; DEALLOCATE cur2;
Drop Table #TMP1 Drop Table #TMP2
PRINT CHAR(10)
PRINT '>>> Finished'
|
|
|
|
|
|
|
|