web-dev-qa-db-ja.com

SQL Server 2008 R2トランザクションログを使用したCOPY_ONLY完全バックアップの復元

いくつかの調査を行った後、私はこの質問に対する答えを見つけることができないようです。

背景次の3つの要件に適合するバックアップ計画をセットアップしようとしています。

  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

おそらく、この全体のセットアップは合理的ではないかもしれません。SQLServerを初めて使用するので、勉強しながら学んでいきます。任意のアドバイス/助けいただければ幸いです。

11
dv10t

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. 完全なコピーのみ
  5. ログ

次に、データベースは次のように削除および復元されます。

  1. 最初のフル
  2. 最初のログ
  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. 最初のフル
  2. 一次微分
  3. 2番目のフル
  4. 二階微分
  5. Copy_Only Diff
  6. 3階微分

次に、この復元ルートを試みます。

  1. 最初のフル
  2. 一次微分
  3. 二階微分

ステップ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. 二階微分
  3. 3階微分

次の選択は、この復元が成功したことを証明しています。これは、COPY_ONLY完全バックアップは、差分チェーンを中断しません。

14
Sebastian Meine

微分が関係している場合は、次のようになります。

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.

差分バックアップは理解するのが難しく、経験豊富なDBAでさえ騙すことができます。

2
spaghettidba