Wszyscy są zgodni, że robienie backupu bazy i logów jest bardzo ważnym zadaniem administratora baz danych, jeżeli chodzi o backup logu powinien on być robiony jak najczęściej bo wtedy możemy zminimalizować straty w przypadku awarii.
Czasami słyszę opinie, że ktoś nie robi backupu logu częściej niż co godzinę bo by miał potem problem z odtworzeniem ciągłości backupu.
Przy odtwarzaniu bazy po awarii pomocna może się okazać procedura.
CREATE PROCEDURE rk_restore_plan
@db_name SYSNAME
,@restore_to_datetime DATETIME --= GETDATE()
AS
/*
rk_restore_plan 'test','2011-02-16 13:47'
*/
SET NOCOUNT ON
DECLARE @server_name NVARCHAR(512)
DECLARE @first_full_backupset_id INTEGER
DECLARE @first_full_backup_startdate DATETIME
DECLARE @print TABLE(id INT IDENTITY(1,1) PRIMARY KEY, tekst VARCHAR(255))
CREATE TABLE #plan(backup_set_id INTEGER NOT NULL,type CHAR(1),stopat_time DATETIME ,used BIT)
SET @server_name = @@SERVERNAME
SELECT @first_full_backupset_id = backupset_outer.backup_set_id
,@first_full_backup_startdate = backupset_outer.backup_start_date
FROM msdb.dbo.backupset backupset_outer
WHERE backupset_outer.database_name = @db_name
AND backupset_outer.server_name = @server_name
AND backupset_outer.type = 'D'
AND backupset_outer.backup_start_date =
( SELECT MAX(backupset_inner.backup_start_date)
FROM msdb.dbo.backupset backupset_inner
WHERE backupset_inner.database_name = backupset_outer.database_name
AND backupset_inner.server_name = @server_name
AND backupset_inner.type = backupset_outer.type
AND backupset_inner.backup_start_date <= @restore_to_datetime
AND backupset_inner.is_copy_only = 0 )
AND backupset_outer.is_copy_only = 0
INSERT #plan
SELECT backup_set_id,type,backup_finish_date,1
FROM msdb.dbo.backupset
WHERE msdb.dbo.backupset.backup_set_id = @first_full_backupset_id
AND msdb.dbo.backupset.server_name = @server_name
INSERT #plan
SELECT backup_set_id,type,backup_finish_date,1
FROM msdb.dbo.backupset
WHERE msdb.dbo.backupset.database_name = @db_name
AND msdb.dbo.backupset.server_name = @server_name
AND msdb.dbo.backupset.type IN ('I', 'L')
AND msdb.dbo.backupset.backup_start_date >= @first_full_backup_startdate
UPDATE #plan
SET used =0
WHERE stopat_time>@restore_to_datetime
UPDATE #plan
SET used =1
WHERE type ='L'
AND backup_set_id IN(SELECT TOP (1) backup_set_id FROM #plan
WHERE used =0
ORDER BY backup_set_id)
INSERT @print
SELECT
'RESTORE '+ CASE BS.type WHEN 'D' THEN 'DATABASE '
WHEN 'I' THEN 'DATABASE '
WHEN 'L' THEN 'LOG '
ELSE 'ERROR' END
+QUOTENAME(BS.database_name) + ' FROM DISK = N'''
+MF.physical_device_name +''' WITH FILE = '+CAST (BS.position AS VARCHAR(5))
+' , NORECOVERY, REPLACE, STATS = 10'
+ CASE WHEN BST.stopat_time >@restore_to_datetime THEN ', STOPAT = N'''+CONVERT(VARCHAR(20),@restore_to_datetime,126)+'''' ELSE '' END
FROM msdb..backupset BS
INNER JOIN #plan BST
ON BS.backup_set_id = BST.backup_set_id
INNER JOIN msdb..backupmediafamily MF
on BS.media_set_id=MF.media_set_id
WHERE used =1
ORDER BY BST.backup_set_id
INSERT @print
SELECT 'RESTORE DATABASE '+QUOTENAME(@db_name) + ' WITH RECOVERY'
SELECT tekst FROM @print
ORDER BY id
Zwraca ona wszystkie kopie które trzeba odtworzyć żeby przywrócić bazę do konkretnego punktu w czasie.
Dla bezpieczeństwa nie są uruchamiane skrypty a tylko zwracane polecenia do wykonania.
Skrypt zakłada, że baza jest odtwarzana w te samo miejsce na dyskach, obsługuje
- backup full
- backup differential
- backup log
- backup copy_only
- backupy do pliku i devices
- backupy dopisujące i nadpisujące media set