いくつかの調査を行った後、私はこの質問に対する答えを見つけることができないようです。
背景次の3つの要件に適合するバックアップ計画をセットアップしようとしています。
したがって、これらのニーズに合わせるために、完全バックアップを毎週、差分を毎日、トランザクションを毎時間と考えています。その後、毎晩、オフサイトに出荷できる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を初めて使用するので、勉強しながら学んでいきます。任意のアドバイス/助けいただければ幸いです。
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行を挿入します。これらの挿入の間に、いくつかのバックアップがこの順序で行われます。
次に、データベースは次のように削除および復元されます。
次のSELECT
は、復元が成功したことを示しています。
これは、COP_ONLY
通常のフルバックアップでもログチェーンが切断されません。
次に、データベースは再び削除され、次のように復元されます。
その後、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;
これは次の順序でバックアップを取ります:
次に、この復元ルートを試みます。
ステップ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.
これは、通常の完全バックアップが差分チェーンを切断することを示しています。
次に、データベースが削除され、この復元フローが試行されます。
手順2は、上記の手順3と同じエラーで失敗します。これは、コピーのみのバックアップを差分復元のベースとして使用できないことを示しています。
次に、データベースが再び削除され、次の復元が実行されます。
次の選択は、この復元が成功したことを証明しています。これは、COPY_ONLY
完全バックアップは、差分チェーンを中断しません。
微分が関係している場合は、次のようになります。
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でさえ騙すことができます。