This blog post is a continuation of my earlier post. Since BACKUP VERIFYONLY does not ensure (guarantee) that the backup will fully restore, and I also wanted to offload the DBCC CHECKDB activities into a secondary server, I wrote a Automated Restore Process that will:
1) RESTORE A DATABASE
2) Keep History
Since my test system is pretty much equivalent to my production boxes, it will also give me a better idea on how much time it takes for a particular database to restore. Script as follows:
Table Creation Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | USE [DBATasks] GO /****** Object: Table [dbo].[Admin_BackupRestores] Script Date: 7/19/2012 1:49:43 PM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Admin_BackupRestores]( [BackupRestoreID] [int] IDENTITY(1,1) NOT NULL, [ServerName] [varchar](50) NOT NULL, [DatabaseName] [varchar](50) NOT NULL, [LastCopied] [varchar](50) NOT NULL, [DateCreated] [datetime] NOT NULL, [LastRestored] [varchar](50) NOT NULL, [DateRestored] [datetime] NOT NULL ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_ServerName] DEFAULT ('') FOR [ServerName] GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_DatabaseName] DEFAULT ('') FOR [DatabaseName] GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_LastCopied] DEFAULT ('') FOR [LastCopied] GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_DateCreated] DEFAULT (getdate()) FOR [DateCreated] GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_Restored] DEFAULT ('') FOR [LastRestored] GO ALTER TABLE [dbo].[Admin_BackupRestores] ADD CONSTRAINT [DF_Admin_BackupRestore_DateRestored] DEFAULT ('1900-01-01') FOR [DateRestored] GO |
Stored Proc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | USE [DBATasks] GO /****** Object: StoredProcedure [dbo].[Admin_RestoreVerifyOnly] Script Date: 7/19/2012 11:55:45 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROC [dbo].[Admin_AutomaticRestores] ( @ServerName VARCHAR(50) , @Path VARCHAR(200) , @LogicalDataFileName VARCHAR(50) , @LogicalLogFileName VARCHAR(50) ) AS SET NOCOUNT ON; /*************************************************************************** Usage: EXEC [dbo].[Admin_AutomaticRestores] @ServerNAme = 'Test-DB1' , @Path = 'K:\Backup\DB1' , @LogicalDataFileName = 'DBATasks' , @LogicalLogFileName = 'DBATasks_log' ***************************************************************************/ /*************************************************************************** Author: Subhash Pant Date Created: 07/19/2012 Date Modified: Purpose: This process automatically restores the database so that DBCC can be run against it. ***************************************************************************/ DECLARE @DATE DATETIME , @fileName NVARCHAR(75) , @dir NVARCHAR(255) , @loadPath NVARCHAR(500) , @cmd1 NVARCHAR(330) , @maxDate DATETIME , @id INT , @dateRestored DATETIME , @restorePath NVARCHAR(500), @lastRestored VARCHAR(50) , @errMsg VARCHAR(500) , @errSeverity INT , @errState INT /********************************************************* Please configure these values **********************************************************/ SET @loadPath = @Path SET @restorePath = @Path --SET @loadPath = '"K:\Backup\DB1"' --SET @restorePath = 'K:\Backup\DB1' /********************************************************* No modification needed beyond this point **********************************************************/ SET @dir = 'dir ' + @loadPath SET @dateRestored = '1900-01-01' IF OBJECT_ID('tempdb.dbo.#tmpDir') IS NULL CREATE TABLE #tmpDir ( id INT IDENTITY , ret NVARCHAR(1000) ) ELSE TRUNCATE TABLE #tmpDir INSERT #tmpDir EXEC master.dbo.xp_cmdshell @dir /********************************************************* Remove unwanted values **********************************************************/ DELETE #tmpDir WHERE NOT ret LIKE '%.bak%' OR ret IS NULL IF EXISTS ( SELECT * FROM #tmpDir AS tmp LEFT OUTER JOIN [dbo].[Admin_BackupRestores] AS lr ON LTRIM(RTRIM(RIGHT(tmp.ret, CHARINDEX(' ', REVERSE(tmp.ret))))) = LastCopied WHERE tmp.ret LIKE '%.bak%' AND LastCopied IS NULL ) BEGIN INSERT into [dbo].[Admin_BackupRestores](ServerName, DatabaseName, LastCopied, DateCreated) SELECT @ServerName, LEFT(LTRIM(RTRIM(RIGHT(tmp.ret, CHARINDEX(' ', REVERSE(tmp.ret))))), PatIndex('%[0-9]%', LTRIM(RTRIM(RIGHT(tmp.ret, CHARINDEX(' ', REVERSE(tmp.ret))))) + '1') - 1), LTRIM(RTRIM(RIGHT(tmp.ret, CHARINDEX(' ', REVERSE(tmp.ret))))) AS LastCopied, CASE WHEN tmp.ret LIKE '% PM %' THEN LEFT(tmp.ret, CHARINDEX(' PM ', tmp.ret) + 3) WHEN tmp.ret LIKE '% AM %' THEN LEFT(tmp.ret, CHARINDEX(' AM ', tmp.ret) + 3) END AS date_created FROM #tmpDir AS tmp LEFT OUTER JOIN DBATasks.dbo.Admin_BackupRestores AS lr ON LTRIM(RTRIM(RIGHT(tmp.ret, CHARINDEX(' ', REVERSE(tmp.ret))))) = LastCopied WHERE tmp.ret LIKE '%.bak%' AND LastCopied IS NULL END WHILE EXISTS (SELECT * FROM [dbo].[Admin_BackupRestores] WHERE [DateRestored] = '1900-01-01') BEGIN SELECT TOP 1 @id = [BackupRestoreID] , @lastRestored = [LastCopied] , @cmd1 = 'RESTORE DATABASE ' + SUBSTRING(LastCopied, 1, CHARINDEX('_', [LastCopied])-1) + ' FROM DISK = ''' + @restorePath + '\' + LastCopied + ''' WITH MOVE ''' + @LogicalDataFileName + ''' TO ''' + 'K:\TestRestores\DB1\' + DatabaseName + CONVERT(VARCHAR(20), GETDATE(), 112) + '_Data.mdf ' + '''' + ', MOVE ''' + @LogicalLogFileName + '''' + ' TO ''' + 'K:\TestRestores\DB1\' + DatabaseName + CONVERT(VARCHAR(20), GETDATE(), 112) + '_log.ldf''' FROM [dbo].[Admin_BackupRestores] WHERE [DateRestored] = '1900-01-01' ORDER BY [DateCreated] BEGIN TRY --print @cmd1 EXEC sp_executesql @cmd1 END TRY BEGIN CATCH SELECT @errMsg = ERROR_MESSAGE() , @errSeverity = ERROR_SEVERITY() , @errState = ERROR_STATE() RAISERROR(@errMsg, @errSeverity, @errState) WITH NOWAIT GOTO cleanup END CATCH UPDATE [dbo].[Admin_BackupRestores] SET [LastRestored] = @lastRestored, [DateRestored] = GETDATE() WHERE [BackupRestoreID] = @id END cleanup: SET NOCOUNT OFF; |
What to run
1 2 3 4 5 | EXEC [dbo].[Admin_AutomaticRestores] @ServerNAme = 'Servername' , @Path = 'K:\Backup\DB1' , @LogicalDataFileName = 'DBATasks' , @LogicalLogFileName = 'DBATasks_log' |