Quantcast
Channel: Thoughts, codes, occasional rants, many others. » SQL Server
Viewing all articles
Browse latest Browse all 11

Automation of Backup Restores

$
0
0

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'

Viewing all articles
Browse latest Browse all 11

Trending Articles