为什么差异备份无法指定其基础?


18

这是我的第一篇DBA.SE帖子,如有任何错误,请通知我,谢谢!

我是一名新的DBA(不是IT专业人员,只是公司中没有其他人可以这样做),所以解释越基本,越好。我一直在阅读有关数据库备份策略的信息(或者,据我所知,它们称为“恢复策略”)。我了解完整,差异和事务日志备份的功能,但是我想知道为什么差异备份只能基于最新的完整备份。

如果差异备份是自上次完整备份以来发生的所有变化,那么为什么差异不能基于我选择的任何备份呢?更清楚地说,我要问的是在进行备份时(而不是在还原时)指定基准。我假设还原时,您将选择正确的基准和相应的差异来执行还原(不使用由基准B制成的差异从基准A还原)。

是什么原因阻止了此功能的实现?我认为一定有原因,我只是不知道那是什么。

注意:我知道不能指定基数,但是我的问题是为什么不指定?(我也对“为什么要这么做?”的讨论不感兴趣)

比喻

这是我了解差异备份的类比:

我有一个Excel文件,在单元格中有一些数据。

在第一天,我将复制此文件并将其存储在其他位置(“完整备份”)。

在第2天,我查看该文件并将其与在第1天创建的备份副本进行比较,并注意到所有已更改的单元以及它们的新值(“差异备份”)。我没有注意到对单元格所做的每一次更改,只是它的最终值是多少。如果单元格A1开始为“ Alfred”,更改为“ Betty”,“ Charlie”,然后更改为“ Dave”,那么我只会注意到“ A1现在是Dave”。

在第3天,我再次将当前文件与备份文件进行比较,并记下更改(另一个“差异备份”与第2天具有相同的基准)。同样,仅注意观察到的每个单元格的最终值,而不是整个一天中单元格的所有值。

在第4天,我再次比较并注意到更改。继续到单元格A1,现在它说“ Sarah”,即使一天中有其他10个名字,我只注意到“现在A1是Sarah”。

第5天,我的文件被弄乱了。因此,我看了第1天制作的备份副本,然后看了第4天记录的最终状态,然后将记录的更改应用于备份副本,现在我将文件“还原”到了第4天的状态。因此,我看一下在第1天进行的备份,看到在第4天单元格A1结束为“ Sarah”,并将备份单元格A1更改为“ Sarah”。

如果在第二天我又制作了文件的另一个备份副本(“完整”),那怎么办?为什么仍无法将第3或4天的文件与第1天制作的副本进行比较(读取,“进行差异备份”)?据我了解,SQL Server将要求我将(在进行另一次差异备份时)与第二天(如果已进行)进行的完整备份进行比较-没有其他选择。

Answers:


14

差异备份使用所谓的差异更改映射来构建自上次完整备份以来已被修改的页面的列表。此列表是“差异”列表,因此是备份类型的名称,以及只能在关联的完整备份之上还原备份的原因。

执行完全备份将重置差异更改图。从那时起,所有修改过的页面都记录在地图中。如果您随后进行差异处理,则该备份仅包含自上次完整备份以来已被修改并记录在地图中的页面。

以此类推,作为整个还原过程基础的两个完整备份可能具有不同的内容,因此具有不同的差异映射。如果您基于第一个备份而非第二个备份还原差异,则数据库可能已损坏。实际上,SQL Server会阻止对差异备份进行任何还原,但该还原所基于的原始完整备份除外。

当您要求SQL Server进行差异备份时,差异的唯一“基础”是差异备份开始时数据库中存在的单个差异更改映射。这就是为什么您不能指定差异备份的基础的原因。


响应@MartinSmith的评论-您也许可以使用COPY_ONLY备份在多个完整备份上还原差异备份。请考虑以下情形:

  1. BACKUP DATABASE xyz TO DISK = 'path_to_backup.bak';
  2. BACKUP DATABASE xyz TO DISK = 'path_to_backup_2.bak' WITH COPY_ONLY;
  3. BACKUP DATABASE xyz TO DISK = 'path_to_backup_3.bak' WITH COPY_ONLY;
  4. BACKUP DATABASE xyz TO DISK = 'path_to_backup_4.bak' WITH COPY_ONLY;
  5. BACKUP DATABASE xyz TO DISK = 'path_to_backup_diff.bak' WITH DIFFERENTIAL;

步骤5中的差异备份应该能够在步骤1-4中进行的任何备份之上恢复,因为差异更改映射仅在步骤1中发生完全备份时才被清除。COPY_ONLY步骤2、3和4中的备份不会重置更改映射。由于差异更改映射会累积自完全备份以来所做的更改,因此每个后续COPY_ONLY备份都包含足够的信息,以使差异备份可与之前的4个备份中的任何一个配合使用。

尽管看起来应该可行,但实际上,在copy_only备份之上还原差异会导致以下错误:

消息3136,级别16,状态1,行1
无法还原此差异备份,因为数据库尚未还原到正确的较早状态。
消息3013,级别16,状态1,第1行
RESTORE DATABASE正在异常终止。

我已经创建了一个SQL Server 2012平台repro以测试差异还原和copy_only还原,并将文件保存在gist.github.com上 -警告该脚本将删除任何命名RestoreTest为第一步的数据库。


如果不执行完整备份,则仅重置差异更改图COPY_ONLY-如果OP在第1天进行常规完整备份,COPY_ONLY在第2天进行完整备份,那么从同一基准应用更高的差异将导致什么问题?到第二天备份?
马丁·史密斯

我刚刚对其进行了测试,但实际上它不允许将较晚的差异还原到copy_only上,尽管“由于数据库尚未还原到正确的较早状态而无法还原此差异备份。” -我不确定是否有某些原因导致此操作不起作用或只是未实现。
马丁·史密斯

1
@MartinSmith-发声。我现在也对此进行了验证。
Max Vernon

5

所需的功能原则上可以存在。使用当前的数据库结构,效率不高(请参阅Max Vernon的答案)。SQL Server必须维护一组差异映射,或者将当前数据库的内容与您指定为基础的完整备份进行比较。

有些应用程序会对大型文件进行重复数据删除。您可以进行两次完整备份,而实际上仅存储已更改的数据。这就像自定义基础的差异。exdupe例如可以做到这一点。

这样做的好处是它可以与所有备份文件一起使用。实际上,从第3个完整备份文件开始,您只需支付增量(而非差异)的空间使用量。空间使用量是与上一个备份文件(而不是第一个)的差异。重复数据删除存储具有类似的行为。

您描述的功能为什么不存在?每个功能都消耗预算,导致其他功能不存在。显然,这一点在优先级列表上还不够。我不确定这会带来什么好处。似乎非常需要使用自定义基础。


3

不要将事务日志备份与差异备份混淆,它们具有不同的用途!实际上,您所谓的“差异备份”是“ 事务日志 ”,即“记录单元的所有更改” 。

差异备份的目的是通过仅记录自上次完整备份以来已更改的信息来保持生成的备份文件的大小较小,并使还原时间保持在恢复时间目标(RTO)之内。

事务日志备份的目的是让您将事务重播到任意时间点-经常但绝对不一定要重播“最近发生的任何事情”。

实际上,您正在谈论的内容是可能的-但您需要还原完整备份,然后还原事务日志。

如果您具有第1天的完整备份,并且在第1天到第5天之间有所有事务日志备份,那么没有什么阻止您还原第1天的备份并重播事务日志,直到获得第4天的数据为止。也可以从第2天备份开始,这会恢复得更快一些,因为您可以重放更少的事务。您还可以将第1天的完整备份,第3天的差异备份还原,然后将事务日志还原到第4天。

编辑:好的,您编辑的类比更有意义。答案是“因为您已经可以通过事务日志备份实现所需的功能”。差异备份只是记录大量事务日志活动的一种便宜又方便的方法。它不提供事务日志备份不提供的任何数据恢复粒度。只有这么多的功能可以提供“纯粹的便利性”,使其成为产品。


我想我的措辞可能很差,请
耐心

为您的新类比进行了编辑。
dpw

1

用Excel打个比方就是比较苹果和橘子。为什么呢 Excel不是数据库,因为它缺乏数据完整性。Excel是一个非常不错的电子表格应用程序,可能是数据库的补充。

SQL Server是一个关系数据库系统,它允许您存储所有数据并提供查询数据的机制。重要的部分是“关系”,因为数据关系与数据完整性(ACID属性)一起很重要。

基本 :

数据库中的数据被组织为用户可见的逻辑组件(表,视图,proc,触发器等)。至少,数据库在物理上还实现为磁盘上的两个(数据和日志文件)或更多(辅助数据文件)文件。

  • 数据库包含页面页面是用于存储记录的数据存储的基本单位。
  • 数据库页面是数据库数据文件的8192字节(8KB)块。
  • 数据库文件中的8个物理上连续的页面(8 * 8KB = 64KB)形成一个范围
  • IAM(索引分配图)页面在单个文件中跟踪约4GB的空间,并在4GB边界上对齐。这些4GB的块称为GAM间隔

为什么差异备份只能基于最新的完整备份。-或-如果差异备份是自上次完整备份以来发生的所有变化,那么为什么差异不能基于我选择的任何备份呢?

根据您对excel的类比,您正在做的就是应用已更改的内容。这将从事务日志中应用所有已提交的事务with STOP AT(注意:在第5天,文件被弄乱了,而在第4天停止)

在每个数据文件的每个4GB部分(称为GAM间隔)中,都有一个特殊的数据库页面,称为差异位图,该页面跟踪自上次完整备份以来该4GB部分的哪些部分(称为扩展区)已更改,指示数据已更改或已添加到数据库。

差异备份将扫描这些位图,并且仅备份标记为已更改的数据文件范围。位图由下一个完整备份重置 (因此差异备份只能基于最新的完整备份),因此您可以看到,随着数据库的变化越来越多,在差异位图中将标记出更多的数据库连续的差异备份将越来越大。

您甚至可以使用此脚本来查找自上次完整备份以来已更改了多少数据库?

差分基本信息存储在master数据库中- sys.database_file或(sys.master_files--当数据库为只读或脱机时很有用)。

有3个重要的列,用于存储与差分基准有关的信息。

  • differential_base_lsn是差异备份的基础。之后更改的数据范围differential_base_lsn将包括在差异备份中。
  • differential_base_guid是的唯一标识符基本备份在其上差异备份为基础的。
  • differential_base_time是时间对应于differential_base_lsn

差异备份对于加快RTO(恢复时间目标=恢复数据库所需的时间)很有用,而不是更频繁的完全备份,这对于大型数据库或恢复事务日志备份量可能会是一个问题,因为它们可能会变得很大随着时间的推移。

注意: COPY_ONLY完全备份不会重置差异基准,因此COPY_ONLY备份不能用作差异基准。

参考文献:



2
@PaulSRandal写道Pages存在用于存储记录。在他的博客上,所以我按原样引用了它。接受逻辑参考(基于参考)您所说的也是正确的!
Kin Shah
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.