Sql-Server-2008

SQL Server 2008 R2 使用事務日誌還原 COPY_ONLY 完整備份

  • April 25, 2018

在做了一些研究之後,我似乎無法找到這個問題的答案。

背景 我正在嘗試設置一個符合以下三個要求的備份計劃:

  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 還很陌生,並且正在努力學習。任何建議/幫助將不勝感激。

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. 第二個日誌

以下SELECT說明還原成功。

這表明無論是COP_ONLY完整備份還是正常的完整備份都不會破壞日誌鏈。

然後再次刪除數據庫並像這樣恢復:

  1. Copy_Only Full
  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. 第二全
  4. 第二差速器
  5. Copy_Only Diff
  6. 第三差速器

然後它會嘗試這條恢復路線:

  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. 第三差速器

第 2 步失敗,出現與上述第 3 步相同的錯誤。這表明僅副本備份不能用作差異還原的基礎。

然後再次刪除數據庫並執行以下還原:

  1. 第二全
  2. 第二差速器
  3. 第三差速器

下面的select證明這次還原成功了。這表明COPY_ONLY完整備份不會中斷差異鏈。

引用自:https://dba.stackexchange.com/questions/37065