SQL Server 2008 R2 Восстановление COPY_ONLY полной резервной копии с журналами транзакций

11

После некоторых исследований я не могу найти ответ на этот вопрос.

Предыстория Я пытаюсь настроить план резервного копирования, который соответствует следующим трем требованиям:

  1. Надежность резервных копий, имеющих ночные полные резервные копии
  2. Резервные копии журнала транзакций, которые можно восстановить из
  3. Низкое количество используемого дискового пространства
  4. Резервные копии должны быть доступны локально для инструмента аудита

Поэтому, чтобы удовлетворить эти потребности, я думаю, что полное резервное копирование выполняется еженедельно, разностно - ежедневно, а транзакции - ежечасно. Затем каждую ночь будет выполняться резервное копирование copy_only, которое может быть отправлено за пределы площадки, это резервное копирование выполняется таким образом, чтобы не нарушать цепочку журналов, и у нас есть надежные ночные полные резервные копии за пределами площадки, без необходимости израсходовать столько локального дискового пространства.

Вопрос Можно ли восстановить из резервной копии copy_only, а восстановить журналы транзакций после.

Позвольте мне привести пример, чтобы вы знали, о чем я говорю.

Используя приведенный ниже список, мне интересно, возможно ли восстановить FullbackupCOPY_ONLYC.bak, за которым следуют TransactionbackupG.trn, TransactionbackupH.trn, наконец TransactionbackupI.trn

> ---List of Backups---   
FullbackupA.bak 01/01/2013 00:00:00   
>  DifferntialbackupA.bak 02/01/2013 00:00:00 
FullbackupCOPY_ONLYA.bak 02/01/2013 00:00:00
>     TransactionbackupA.trn 02/01/2013 01:00:00
>     TransactionbackupB.trn 02/01/2013 02:00:00
>     TransactionbackupC.trn 02/01/2013 03:00:00
>  DifferntialbackupB.bak 03/01/2013 00:00:00 
FullbackupCOPY_ONLYB.bak 03/01/2013 00:00:00
>     TransactionbackupD.trn 03/01/2013 01:00:00
>     TransactionbackupE.trn 03/01/2013 02:00:00
>     TransactionbackupF.trn 03/01/2013 03:00:00
>  DifferntialbackupC.bak 04/01/2013 00:00:00 
FullbackupCOPY_ONLYC.bak 04/01/2013 00:00:00
>     TransactionbackupG.trn 04/01/2013 01:00:00
>     TransactionbackupH.trn 04/01/2013 02:00:00
>     TransactionbackupI.trn 04/01/2013 03:00:00

Может быть, вся эта установка не является разумной, я довольно новичок в SQL Server и пытаюсь учиться на ходу. Любой совет / помощь будет принята с благодарностью.

dv10t
источник

Ответы:

14

Полное резервное копирование в SQL Server 2008 не нарушает цепочку журналов. Сбрасывает только дифференциал base-lsn.

Вы также можете восстановить резервные копии журнала после восстановления только из копии. Следующий скрипт демонстрирует это:

CREATE DATABASE BakTst13;
GO
ALTER DATABASE BakTst13 SET RECOVERY FULL;
GO
USE BakTst13;
GO
CREATE TABLE dbo.tst(id INT IDENTITY(1,1));
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP LOG BakTst13 
TO DISK = 'BakTst13_Log_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_2' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_C' WITH COPY_ONLY,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP LOG BakTst13 
TO DISK = 'BakTst13_Log_2' WITH INIT,FORMAT;
GO
USE tempdb;
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_1' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_1' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;

Он создает базу данных и таблицу и вставляет 50 строк в эту таблицу. Между этими вставками делается несколько резервных копий в следующем порядке:

  1. Полный
  2. Журнал
  3. Полный
  4. Full Copy_Only
  5. Журнал

Затем база данных удаляется и восстанавливается следующим образом:

  1. 1-й полный
  2. 1-й журнал
  3. 2-й журнал

Ниже SELECTпоказано, что восстановление прошло успешно.

Это показывает, что COP_ONLYни обычное полное резервное копирование, ни обычное резервное копирование не нарушают цепочку журналов.

Затем база данных снова удаляется и восстанавливается следующим образом:

  1. Copy_Only Full
  2. 2-й журнал

После этого SELECTснова демонстрирует успех.

Это демонстрирует, что вы можете использовать COPY_ONLYполную резервную копию в качестве основы вашего восстановления журнала.

Дифференциальные тесты

Я DIFFERENTIALтоже создал версию:

CREATE DATABASE BakTst13;
GO
ALTER DATABASE BakTst13 SET RECOVERY FULL;
GO
USE BakTst13;
GO
CREATE TABLE dbo.tst(id INT IDENTITY(1,1));
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Diff_1' WITH DIFFERENTIAL,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_2' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Diff_2' WITH DIFFERENTIAL,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_C' WITH COPY_ONLY,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Diff_3' WITH DIFFERENTIAL,INIT,FORMAT;
GO
USE tempdb;
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore F1, D1, D2',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_1' WITH NORECOVERY; 
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_1' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;--<--Fails!
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore FC, D3',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_3' WITH NORECOVERY;--<--Fails!
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore F2, D2, D3',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_2' WITH NORECOVERY; 
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_3' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;

Это берет резервные копии в следующем порядке:

  1. 1-й полный
  2. 1-й дифференциал
  3. 2-й полный
  4. 2-й дифференциал
  5. Copy_Only Diff
  6. 3-й дифференциал

Затем он пытается этот маршрут восстановления:

  1. 1-й полный
  2. 1-й дифференциал
  3. 2-й дифференциал

Шаг 3 завершается ошибкой:

Msg 3136, Level 16, State 1, Line 4
This differential backup cannot be restored because the database has not been restored to the correct earlier state.

Это показывает, что нормальное полное резервное копирование разрывает дифференциальную цепь.

Затем база данных удаляется и выполняется попытка восстановления:

  1. Copy_Only Full
  2. 3-й дифференциал

Шаг 2 завершается с той же ошибкой, что и шаг 3 выше. Это показывает, что резервная копия только для копирования не может использоваться в качестве базы для дифференциального восстановления.

Затем база данных снова удаляется и выполняется следующее восстановление:

  1. 2-й полный
  2. 2-й дифференциал
  3. 3-й дифференциал

Следующий выбор подтверждает, что это восстановление прошло успешно. Это показывает, что COPY_ONLYполное резервное копирование не прерывает дифференциальную цепочку.

Себастьян Майн
источник
Я искал информацию о том, можно ли применить журнал транзакций к полной резервной копии copy_only. Это действительно хорошая информация!
Brain2000
2

Вот что происходит, когда задействованы дифференциалы:

CREATE DATABASE BakTst13;
GO
ALTER DATABASE BakTst13 SET RECOVERY FULL;
GO
USE BakTst13;
GO
CREATE TABLE dbo.tst(id INT IDENTITY(1,1));
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 10 rows so far
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 20 rows so far
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Diff_1' WITH INIT,FORMAT,DIFFERENTIAL
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 30 rows so far
BACKUP LOG BakTst13 
TO DISK = 'BakTst13_Log_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 40 rows so far
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_2' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 50 rows so far
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Full_C' WITH COPY_ONLY,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 60 rows so far
GO
BACKUP DATABASE BakTst13 
TO DISK = 'BakTst13_Diff_2' WITH INIT,FORMAT,DIFFERENTIAL
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10 -- 70 rows so far
GO
BACKUP LOG BakTst13 
TO DISK = 'BakTst13_Log_2' WITH INIT,FORMAT;
GO


USE tempdb;
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_2' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT COUNT(*) FROM BakTst13.dbo.tst; -- Must be 70: log chain not broken
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT COUNT(*) FROM BakTst13.dbo.tst; -- Must be 70
GO
DROP DATABASE BakTst13;

Одним словом: да, вы можете использовать COPY_ONLYрезервную копию для восстановления дальнейших резервных копий журнала. Что вы не можете сделать, это использовать COPY_ONLYрезервную копию в качестве дифференциальной базы. Это означает, что вы не сможете восстановить какие-либо дифференциальные резервные копии из восстановленной COPY_ONLYрезервной копии:

DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;

Если вы попробуете это, вы получите ошибку:

Processed 160 pages for database 'BakTst13', file 'BakTst13' on file 1.
Processed 2 pages for database 'BakTst13', file 'BakTst13_log' on file 1.
RESTORE DATABASE successfully processed 162 pages in 0.009 seconds (139.811 MB/sec).
Msg 3136, Level 16, State 1, Line 2
This differential backup cannot be restored because the database has not been restored to the correct earlier state.
Msg 3013, Level 16, State 1, Line 2
RESTORE DATABASE is terminating abnormally.

Дифференциальные резервные копии могут быть трудны для понимания и могут обмануть даже опытных администраторов баз данных.

spaghettidba
источник