Technical Article

Point in time restore to a new DB from files of a Full Recovery Model

,

This script is designed to restore to a new DB in a specific point in time from backup files (FULL/DIFF/LOG) created from Ola Hallengren's backup solution (http://ola.hallengren.com). Just fill the "Initialize variables" section and the generator will print all the necessary commands, you can review and execute them manually for extra security. Although it is based on a specific solution with little or no modifications it can be universal for all directory/file naming conventions.

USE Master; 
GO 
SET NOCOUNT ON 

-- 1 - Variable declaration 
DECLARE @RestoredbName sysname 
DECLARE @OriginaldbName sysname 
DECLARE @backupPath NVARCHAR(500) 
DECLARE @RestorePath NVARCHAR(500)
DECLARE @cmd NVARCHAR(3000) 
DECLARE @comments NVARCHAR(250) 
DECLARE @fileList TABLE (backupFile NVARCHAR(255)) 
DECLARE @lastFullBackup NVARCHAR(500) 
DECLARE @lastDiffBackup NVARCHAR(500) 
DECLARE @backupFile NVARCHAR(500) 
DECLARE @PointInTime NVARCHAR(50) 

-- 2 - Initialize variables 
SET @OriginaldbName = 'GLDatabase' 
SET @RestoredbName = 'GLDatabase_Restore' 
SET @backupPath = 'D:\SQL_DATA\DatabaseWeeklyBackup\' 
SET @RestorePath = 'D:\SQL_DATA\GL\'
SET @PointInTime = N'2011-05-19 17:05:15'

-- 3 - Create Database to restore to
SET @cmd = 
'CREATE DATABASE ['+@RestoredbName+'] ON PRIMARY 
( NAME = N'''+@RestoredbName+''', FILENAME = N'''+@RestorePath+@RestoredbName+'.mdf'', SIZE = 100000KB , FILEGROWTH = 10% )
LOG ON 
( NAME = N'''+@RestoredbName+'_log'', FILENAME = N'''+@RestorePath+@RestoredbName+'_log.ldf'', SIZE = 1024KB , FILEGROWTH = 5%)
GO
ALTER DATABASE ['+@RestoredbName+'] SET COMPATIBILITY_LEVEL = 100
GO
ALTER DATABASE ['+@RestoredbName+'] SET ANSI_NULL_DEFAULT OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET ANSI_NULLS OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET ANSI_PADDING OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET ANSI_WARNINGS OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET ARITHABORT OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET AUTO_CLOSE OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET AUTO_CREATE_STATISTICS ON 
GO
ALTER DATABASE ['+@RestoredbName+'] SET AUTO_SHRINK OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET AUTO_UPDATE_STATISTICS ON 
GO
ALTER DATABASE ['+@RestoredbName+'] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET CURSOR_DEFAULT GLOBAL 
GO
ALTER DATABASE ['+@RestoredbName+'] SET CONCAT_NULL_YIELDS_NULL OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET NUMERIC_ROUNDABORT OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET QUOTED_IDENTIFIER OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET RECURSIVE_TRIGGERS OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET DISABLE_BROKER 
GO
ALTER DATABASE ['+@RestoredbName+'] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO
ALTER DATABASE ['+@RestoredbName+'] SET PARAMETERIZATION SIMPLE 
GO
ALTER DATABASE ['+@RestoredbName+'] SET READ_WRITE 
GO
ALTER DATABASE ['+@RestoredbName+'] SET RECOVERY SIMPLE 
GO
ALTER DATABASE ['+@RestoredbName+'] SET MULTI_USER 
GO
ALTER DATABASE ['+@RestoredbName+'] SET PAGE_VERIFY CHECKSUM 
GO
USE ['+@RestoredbName+']
GO
IF NOT EXISTS (SELECT name FROM sys.filegroups WHERE is_default=1 AND name = N''PRIMARY'') ALTER DATABASE ['+@RestoredbName+'] MODIFY FILEGROUP [PRIMARY] DEFAULT
GO
'

PRINT @cmd

PRINT ''

SET @cmd = 'USE Master;' 
PRINT @cmd 

-- 4 - get list of files 
SET @cmd = 'DIR /b /s ' + @backupPath 

INSERT INTO @fileList(backupFile) 
EXEC master.sys.xp_cmdshell @cmd 

SET @comments = 'PRINT ''Starting Restoration at:'' + CONVERT(VARCHAR(20),GETDATE(),113)'
PRINT @comments

-- 5 - Find latest full backup 
SELECT @lastFullBackup = MAX(backupFile) 
FROM @fileList 
WHERE backupFile LIKE '%_FULL_%.bak' 
AND
RIGHT(backupFile,19) < REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(30),@PointInTime,120),'-',''),':',''),' ','_')+'.bak'

SET @cmd = 'RESTORE DATABASE [' + @RestoredbName + '] FROM DISK = N''' 
+ @lastFullBackup + '''
WITH FILE = 1, 
MOVE N'''+@OriginaldbName+''' TO N'''+@RestorePath+@RestoredbName+'.mdf'', 
MOVE N'''+@OriginaldbName+'_log'' TO N'''+@RestorePath+@RestoredbName+'_log.ldf'', 
NORECOVERY, NOUNLOAD, REPLACE, STATS = 10' 
SET @comments = 'PRINT ''Restoring Database Full Backup:'''
PRINT @comments
PRINT @cmd 

-- 6 - Find latest diff backup 
SELECT @lastDiffBackup = MAX(backupFile) 
FROM @fileList 
WHERE backupFile LIKE '%_DIFF_%.bak' 
AND RIGHT(backupFile,19) > RIGHT(@lastFullBackup,19)
AND 
RIGHT(backupFile,19) < REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(30),@PointInTime,120),'-',''),':',''),' ','_')+'.bak'

-- check to make sure there is a diff backup 
IF @lastDiffBackup IS NOT NULL 
BEGIN 
SET @cmd = 'RESTORE DATABASE [' + @RestoredbName + '] FROM DISK = N''' 
+ @lastDiffBackup + '''
WITH FILE = 1, 
MOVE N'''+@OriginaldbName+''' TO N'''+@RestorePath+@RestoredbName+'.mdf'', 
MOVE N'''+@OriginaldbName+'_log'' TO N'''+@RestorePath+@RestoredbName+'_log.ldf'', 
NORECOVERY, NOUNLOAD, REPLACE, STATS = 10' 
SET @comments = 'PRINT ''Restoring Database Nearest Differential Backup:'''
PRINT @comments
PRINT @cmd 
SET @lastFullBackup = @lastDiffBackup 
END 

-- 7 - check for log backups 
DECLARE backupFiles CURSOR FOR 
SELECT backupFile 
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY backupFile) AS RowNumber, backupFile 
FROM @fileList 
WHERE backupFile LIKE '%_LOG_%.trn' 
AND RIGHT(backupFile,19) > RIGHT(@lastFullBackup,19)
) LogFiles
WHERE RowNumber <= 
(
SELECT ISNULL(MAX(derivdtbl.RowNumber),0) + 1
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY backupFile) AS RowNumber, backupFile 
FROM @fileList 
WHERE backupFile LIKE '%_LOG_%.trn' 
AND RIGHT(backupFile,19) > RIGHT(@lastFullBackup,19))
AS derivdtbl
WHERE 
RIGHT(derivdtbl.backupFile,19) < REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(30),@PointInTime,120),'-',''),':',''),' ','_')+'.trn'
AND RIGHT(backupFile,19) > RIGHT(@lastFullBackup,19)
)

SET @comments = 'PRINT ''Restoring Sequentially Log Backups:'''
PRINT @comments
OPEN backupFiles 

-- Loop through all the files for the database 
FETCH NEXT FROM backupFiles INTO @backupFile 

WHILE @@FETCH_STATUS = 0 
BEGIN 
SET @cmd = 'RESTORE LOG [' + @RestoredbName + '] FROM DISK = N''' 
+ @backupFile + ''' WITH NORECOVERY, NOUNLOAD, STATS = 10, STOPAT = N'''+ @PointInTime +''''
PRINT @cmd 
FETCH NEXT FROM backupFiles INTO @backupFile 
END 

CLOSE backupFiles 
DEALLOCATE backupFiles 

-- 8 - put database in a useable state 
SET @comments = 'PRINT ''Bringing Database to Online Status...'''
PRINT @comments
SET @cmd = 'RESTORE DATABASE [' + @RestoredbName + '] WITH RECOVERY' 
PRINT @cmd 
SET @comments = 'PRINT ''Succesfully restored database ' +@OriginaldbName+ ' to ' +@RestoredbName+ ' as it was on ' +@PointInTime+ '. Finished at '' +CONVERT(VARCHAR(20),GETDATE(),113)'
PRINT @comments

Rate

3.67 (3)

You rated this post out of 5. Change rating

Share

Share

Rate

3.67 (3)

You rated this post out of 5. Change rating