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还是相当陌生,并且正在尝试学习。任何建议/帮助将不胜感激。

Answers:


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. 完全复制
  5. 记录

接下来,将数据库删除并还原,如下所示:

  1. 第一满
  2. 第一日志
  3. 第二日志

以下SELECT说明还原成功。

这表明a COP_ONLY和正常的完全备份都不会中断日志链。

然后,再次删除数据库并按以下方式还原:

  1. 仅复制完整
  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. 仅复制差异
  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. 仅复制完整
  2. 三阶微分

步骤2失败,并出现与上述步骤3相同的错误。这表明仅复制备份不能用作差异还原的基础。

然后再次删除数据库并执行以下还原:

  1. 第二满
  2. 二阶微分
  3. 三阶微分

以下选择证明此还原成功。这表明COPY_ONLY完全备份不会中断差分链。


我一直在寻找有关是否可以将事务日志应用于copy_only完整备份的信息。这真的是很好的信息!
Brain2000 '18

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.

差异备份可能很难理解,甚至可能使有经验的DBA蒙蔽。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.