Skip to content

Commit f31d67b

Browse files
committed
Issue 814
added ContinueDiff bit paremeter to signal that the procedure should check for diffs added LastDiffBackup variable and moved the BackupFile and BackupDateTime variables to be global so that they can be used across the full and diff functions cut n pasted the full restore feature, modified it to handle diffs and set conditional logic so that the most recent diff date is checked against the full backup date, this will hopefully prevent a situation where there are no diffs or diffs older than the full.
1 parent 62d3a9e commit f31d67b

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

sp_DatabaseRestore.sql

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ IF OBJECT_ID('dbo.sp_DatabaseRestore') IS NULL
3333
GO
3434

3535
ALTER PROCEDURE [dbo].[sp_DatabaseRestore]
36-
@Database NVARCHAR(128), @RestoreDatabaseName NVARCHAR(128) = NULL, @BackupPathFull NVARCHAR(MAX), @BackupPathLog NVARCHAR(MAX),
37-
@MoveFiles bit = 0, @MoveDataDrive NVARCHAR(260) = NULL, @MoveLogDrive NVARCHAR(260) = NULL, @TestRestore bit = 0, @RunCheckDB bit = 0,
36+
@Database NVARCHAR(128), @RestoreDatabaseName NVARCHAR(128) = NULL, @BackupPathFull NVARCHAR(MAX), @BackupPathDiff NVARCHAR(MAX), @BackupPathLog NVARCHAR(MAX),
37+
@MoveFiles bit = 0, @MoveDataDrive NVARCHAR(260) = NULL, @MoveLogDrive NVARCHAR(260) = NULL, @TestRestore bit = 0, @RunCheckDB bit = 0, @ContinueDiff bit = 0,
3838
@ContinueLogs bit = 0, @RunRecovery bit = 0
3939
AS
4040
SET NOCOUNT ON;
4141

42-
DECLARE @cmd NVARCHAR(4000), @sql NVARCHAR(MAX), @LastFullBackup NVARCHAR(500), @BackupFile NVARCHAR(500);
42+
DECLARE @cmd NVARCHAR(4000), @sql NVARCHAR(MAX), @LastFullBackup NVARCHAR(500), @LastDiffBackup NVARCHAR(500), @BackupFile NVARCHAR(500), @BackupDateTime AS CHAR(15), @FullLastLSN NUMERIC(25, 0);
4343
DECLARE @FileList TABLE (BackupFile NVARCHAR(255));
4444

4545
IF @RestoreDatabaseName IS NULL
@@ -174,55 +174,76 @@ BEGIN
174174
SELECT @MoveOption = @MoveOption + logicalcmds
175175
FROM Files;
176176
END;
177-
178177
IF @ContinueLogs = 0
179178
BEGIN
180179
SET @sql = 'RESTORE DATABASE '+@RestoreDatabaseName+' FROM DISK = '''+@BackupPathFull + @LastFullBackup+ ''' WITH NORECOVERY, REPLACE' + @MoveOption+CHAR(13);
181180
PRINT @sql;
182181
EXECUTE @sql = [dbo].[CommandExecute] @Command = @sql, @CommandType = 'RESTORE DATABASE', @Mode = 1, @DatabaseName = @Database, @LogToTable = 'Y', @Execute = 'Y';
183-
184182
--get the backup completed data so we can apply tlogs from that point forwards
185183

186184
SET @sql = REPLACE(@HeadersSQL, '{Path}', @BackupPathFull + @LastFullBackup);
187185
PRINT @sql;
188186
EXECUTE (@sql);
189-
190-
DECLARE @BackupDateTime AS CHAR(15), @FullLastLSN NUMERIC(25, 0);
191-
187+
--DECLARE @BackupDateTime AS CHAR(15), @FullLastLSN NUMERIC(25, 0);
192188
SELECT @BackupDateTime = RIGHT(@LastFullBackup, 19)
193-
194-
SELECT @FullLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 1;
195-
189+
SELECT @FullLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 1;
190+
PRINT @BackupDateTime
196191
END;
197192
ELSE
198193
BEGIN
199194
DECLARE @DatabaseLastLSN NUMERIC(25, 0);
200-
201195
SELECT @DatabaseLastLSN = CAST(f.redo_start_lsn AS NUMERIC(25, 0))
202196
FROM master.sys.databases d
203197
JOIN master.sys.master_files f ON d.database_id = f.database_id
204198
WHERE d.name = @RestoreDatabaseName AND f.file_id = 1
205199
END;
206200

201+
--Clear out table variables for differential
202+
DELETE FROM @FileList;
203+
204+
-- get list of files
205+
SET @cmd = 'DIR /b "'+ @BackupPathDiff + '"';
206+
INSERT INTO @FileList (BackupFile)
207+
EXEC master.sys.xp_cmdshell @cmd;
208+
209+
-- select * from @fileList
210+
-- Find latest diff backup
211+
SELECT @LastDiffBackup = MAX(BackupFile)
212+
FROM @FileList
213+
WHERE BackupFile LIKE '%.bak'
214+
AND
215+
BackupFile LIKE '%'+@Database+'%';
216+
217+
IF @ContinueDiff = 1 AND @BackupDateTime < RIGHT(@LastDiffBackup, 19)
218+
BEGIN
219+
SET @sql = 'RESTORE DATABASE '+@RestoreDatabaseName+' FROM DISK = '''+@BackupPathDiff + @LastDiffBackup+ ''' WITH NORECOVERY';
220+
PRINT @sql;
221+
EXECUTE @sql = [dbo].[CommandExecute] @Command = @sql, @CommandType = 'RESTORE DATABASE', @Mode = 1, @DatabaseName = @Database, @LogToTable = 'Y', @Execute = 'Y';
222+
--get the backup completed data so we can apply tlogs from that point forwards
223+
224+
SET @sql = REPLACE(@HeadersSQL, '{Path}', @BackupPathFull + @LastFullBackup);
225+
PRINT @sql;
226+
EXECUTE (@sql);
227+
--DECLARE @BackupDateTime AS CHAR(15), @FullLastLSN NUMERIC(25, 0);
228+
SELECT @BackupDateTime = RIGHT(@LastDiffBackup, 19)
229+
SELECT @FullLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 1;
230+
END;
231+
207232
--Clear out table variables for translogs
208233
DELETE FROM @FileList;
209234

210235
SET @cmd = 'DIR /b "'+ @BackupPathLog + '"';
211236
INSERT INTO @FileList (BackupFile)
212237
EXEC master.sys.xp_cmdshell @cmd;
213-
214238
--check for log backups
215239
DECLARE BackupFiles CURSOR FOR
216240
SELECT BackupFile
217241
FROM @FileList
218242
WHERE BackupFile LIKE '%.trn'
219243
AND BackupFile LIKE '%'+@Database+'%'
220244
AND (@ContinueLogs = 1 OR (@ContinueLogs = 0 AND LEFT(RIGHT(BackupFile, 19), 15) >= @BackupDateTime));
221-
222245
OPEN BackupFiles;
223-
224246
DECLARE @i tinyint = 1, @LogFirstLSN NUMERIC(25, 0), @LogLastLSN NUMERIC(25, 0);
225-
226247
-- Loop through all the files for the database
227248
FETCH NEXT FROM BackupFiles INTO @BackupFile;
228249
WHILE @@FETCH_STATUS = 0
@@ -234,26 +255,20 @@ BEGIN
234255
EXECUTE (@sql);
235256

236257
SELECT @LogFirstLSN = CAST(FirstLSN AS NUMERIC(25, 0)), @LogLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 2;
237-
238258
IF (@ContinueLogs = 0 AND @LogFirstLSN <= @FullLastLSN AND @FullLastLSN <= @LogLastLSN) OR (@ContinueLogs = 1 AND @LogFirstLSN <= @DatabaseLastLSN AND @DatabaseLastLSN < @LogLastLSN)
239259
SET @i = 2;
240-
241260
DELETE FROM #Headers WHERE BackupType = 2;
242261
END;
243-
244262
IF @i = 2
245263
BEGIN
246264
SET @sql = 'RESTORE LOG '+@RestoreDatabaseName+' FROM DISK = '''+@BackupPathLog + @BackupFile+''' WITH NORECOVERY'+CHAR(13);
247265
PRINT @sql
248266
EXECUTE @sql = [dbo].[CommandExecute] @Command = @sql, @CommandType = 'RESTORE LOG', @Mode = 1, @DatabaseName = @Database, @LogToTable = 'Y', @Execute = 'Y';
249267
END;
250-
251268
FETCH NEXT FROM BackupFiles INTO @BackupFile;
252269
END;
253-
254270
CLOSE BackupFiles;
255271
DEALLOCATE BackupFiles;
256-
257272
-- put database in a useable state
258273
IF @RunRecovery = 1
259274
BEGIN
@@ -264,11 +279,9 @@ END;
264279
--Run checkdb against this database
265280
IF @RunCheckDB = 1
266281
EXECUTE [dbo].[DatabaseIntegrityCheck] @Databases = @RestoreDatabaseName, @LogToTable = 'Y';
267-
268282
--If test restore then blow the database away (be careful)
269283
IF @TestRestore = 1
270284
BEGIN
271285
SET @sql = 'DROP DATABASE '+@RestoreDatabaseName;
272286
EXECUTE sp_executesql @sql;
273-
END;
274-
287+
END;

0 commit comments

Comments
 (0)