SQL Server 备份应用程序 - 卷影复制服务 (VSS) 和 SQL 编写器

适用于:SQL Server - 仅限 Windows

SQL Server 通过提供一个编写器(SQL 编写器)来支持卷影复制服务 (VSS),使第三方备份应用程序可以使用 VSS 框架来备份数据库文件。 本文介绍了 SQL 编写器组件及其在 SQL Server 数据库的 VSS 快照创建和还原过程中的角色。 还介绍了如何配置和使用 SQL 编写器来处理 VSS 框架中的备份应用程序的详细信息。

VSS 的基础结构

VSS 提供了在 Windows 系统上运行 VSS 应用程序的系统基础结构。 尽管在很大程度上对用户和开发人员都是透明的,但 VSS:

  • 在卷影复制的创建和使用中协调提供程序、编写器和请求程序的活动。
  • 提供默认的系统提供程序。
  • 实现所需的低级别驱动程序功能,使任何提供程序能够正常工作。

VSS 服务按需启动,因此必须启用此服务才能成功执行 VSS 操作。

VSS 组件

VSS 协调以下协作组件的活动:

  • 提供程序拥有卷影副本数据并实例化卷影副本。

  • 编写器是更改数据并参与卷影复制同步过程的应用程序。

  • 请求程序启动卷影副本的创建和销毁。 此设计侧重于请求者是备份应用程序的情境。

VSS 在这些参与方之间提供协调:

显示 VSS 在参与方之间如何提供协调的示意图。

此图显示了参与典型的 VSS 快照活动的所有组件。 在这种情况下,SQL Server(包括 SQL 编写器)在某个“Writer”组件中作为一个编写器运行。 其他此类编写器可能是 Exchange Server 等。

  • 虚拟设备接口:SQL Server 提供名为虚拟设备接口(VDI)的应用程序编程接口,它通过为备份和还原作提供支持,帮助独立软件供应商将 SQL Server 集成到其产品中。 这些 API 能够提供非常高的可靠性和极佳的性能,并支持 SQL Server 的所有备份与还原功能,包括所有的热备份和快照备份功能。 有关详细信息,请参阅 SQL Server 2005 虚拟备份设备接口规范

  • 请求程序:从一个或多个原始卷中获取一个或多个快照集的过程(自动或 GUI)。 在本文中,请求程序还用于表示创建 SQL Server 数据库快照的备份应用程序。

有详细信息,请参阅卷影复制服务

SQL 编写器

SQL 编写器是由 SQL Server 实例提供的 VSS 编写器。 它处理与 SQL Server 的 VSS 交互。 SQL 编写器作为独立服务随 SQL Server 一起提供,并作为 SQL Server 安装的一部分进行安装。

SQL 编写器在 VSS 快照备份操作中的角色:

VSS 快照的屏幕截图。

配置 SQL 编写器

SQL 编写器服务作为 SQL Server 安装的一部分安装在系统中,配置为在 Windows 启动时自动启动。

SQL 编写器服务帐户

安装期间,将安装 SQL 编写器帐户以使用本地系统帐户。 由于 SQL 编写器需要使用专用的 VDI API 与 SQL Server 进行通信,因此 SQL 编写器帐户必须对 SQL Server 和 VSS 具有足够的访问权限。 将服务配置为本地系统帐户可为服务的正确运行提供足够的权限。

重要

确保 SQL 编写器服务在本地系统帐户下运行,并且 SQL Server NT SERVICE\SQLWriter 帐户是 sysadmin 角色的成员。

重新启用和启动 SQL 编写器

默认情况下,SQL 编写器服务已启用并自动启动。 如果修改了此配置,则必须执行以下步骤才能还原为默认设置:

可以通过将此服务标记为 “自动”来启用 SQL 编写器服务。 若要通过控制面板打开服务,请选择“ 开始”,选择 “控制面板”,双击 “管理工具”,然后双击“ 服务”。 在 “服务 ”窗格中,双击 SQL 编写器 服务,并将 启动类型 属性修改为 “自动”。

然后,应通过选择前面提到的服务属性屏幕中的“服务状态”属性下的“启动”按钮来启动服务。

注意

在某些情况下,安装了 SQL Server Express 实例,并且应用程序正在使用用户实例功能,SQL 编写器可能会由 SQL Server 自动启动。 这样做是为了方便在 VSS 备份操作期间枚举这些用户实例。

SQL 编写器支持的功能

  • 全文:SQL 编写器在编写器元数据文档的数据库组件下报告包含递归文件规范的全文目录容器。 选择数据库组件时,它们会自动包含在备份中。

  • 差异备份和还原:SQL 编写器通过两种 VSS 差异机制支持差异备份和还原:

    • 分部文件:SQL 编写器使用 VSS 部分文件机制报告其数据库文件中更改的字节范围。

    • 按上次修改时间的差异文件:SQL 编写器使用 VSS 按上次修改时间的差异文件机制来报告全文目录中的已更改文件

  • 使用移动进行还原:SQL 编写器在还原期间支持 VSS 的新目标规范。 新的目标规范说明允许将数据库、日志文件或全文目录容器在还原操作中重新定位。

  • 数据库重命名:请求者可能需要还原具有新名称的 SQL Server 数据库,尤其是在数据库与原始数据库并排还原时。 只要数据库保留在原始 SQL 实例中,SQL 编写器就会支持在还原操作期间重命名数据库。

  • 仅复制备份:有时需要执行用于特殊用途的备份,例如,需要为测试目的创建数据库副本。 此备份不应影响数据库的整体备份和还原过程。 COPY_ONLY使用此选项指定备份是在带外完成的,不应影响备份的正常顺序。 SQL 编写器支持 SQL Server 实例的仅复制备份类型。

  • 自动恢复数据库快照:通常,使用 VSS 框架获取的 SQL Server 数据库的快照处于非恢复状态。 在数据进入恢复阶段以回滚运行中的事务并将数据库置于一致状态之前,无法安全地访问快照中的数据。 在快照创建过程中,VSS 备份应用程序可以请求自动恢复快照。

本文中的 备份和还原选项详细信息 中更详细地介绍了这些新功能及其用法。

不支持的内容

  • SQL 编写器不支持日志备份。
  • 不支持文件和文件组备份。
  • 不支持页面还原。
  • 不支持数据库快照,在创建组件和非组件 VSS 快照时将被忽略。
  • 自动关闭数据库,或启用了关机的数据库。
  • Linux 不提供 VSS 框架,因此 SQL 编写器在 Linux 上不可用。

下表列出了 Windows 上所有版本的 SQL Server 在与 VSS 框架协作时,由 SQL Writer/SQL Server 支持的快照备份类型。

备份和还原操作 基于组件 不基于组件
完整数据备份
(包括全文目录)
完整还原
完全还原(无恢复)
差异备份
差异还原
还原并移动
数据库重命名
仅限复制的备份
自动恢复的快照
日志备份
数据库快照
自动关闭数据库
启用了关机的数据库
可用性组数据库 对于辅助数据库为否

备份操作

SQL Server (使用 SQL 编写器)支持以下基于 VSS 的备份作模式:

  • 不基于组件
  • 基于组件

版本支持

SQL 编写器是作为 SQL Server 的一部分提供的,并且只支持 SQL Server 实例。 SQL 编写器还会枚举 SQL Server Express 实例,包括 SQL Server Express 版本启动的用户实例。

不基于组件的备份操作

不基于组件的备份通过使用快照集中的卷列表隐式地选择数据库。 SQL 编写器检查是否有损坏的数据库,如果发现则引发错误。 损坏的数据库是指其中的文件子集由卷列表选择的数据库。

在非基于组件的模型中,仅支持具有简单恢复模式的数据库。 不支持还原后前滚。

基于组件的备份操作

首选基于组件的备份,建议使用 SQL 编写器,因为应用程序(VSS 备份应用程序)从 SQL 编写器返回的元数据中显式选择数据库。 快照集应包括备份这些数据库所需的所有卷。 VSS 基础结构不会自动添加所选数据库集所需的卷。 所有备份卷都应包含在卷快照集中。 备份应用程序有责任确保快照集中包括所有备份卷。 SQL 编写器将检测损坏的数据库(备份卷在快照集外部)并使备份失败。

本部分的其余部分假定基于组件的备份用作 SQL Server 的 VSS 快照创建过程的一部分。

快照创建过程

VSS 框架在创建 SQL Server 快照期间协调 请求方 (备份应用程序)和 SQL 编写器的活动。 为了启用此协调,VSS 框架定义请求者和编写器 接口。 这些接口应由参与的请求程序应用程序和编写器实现。 SQL 编写器实现了必要的编写器接口。 在快照创建过程中,VSS 框架将调用 SQL 编写器的接口。 SQL 编写器与系统上的 SQL Server 实例交互,以便于创建快照。

VSS 框架定义了一组 API 供请求程序/备份应用程序使用。 备份应用程序开发人员需要遵循这些 API 调用模式才能使用 VSS 框架快照创建过程。 下面几节将从 SQL 编写器的角度描述快照创建过程。 并且还将详细描述请求程序、VSS 框架、SQL 编写器和 SQL Server 实例之间的一些内部交互。

有关这些步骤的详细信息以及 VSS 框架接口的详细信息,请参阅卷影复制服务(VSS)。

注意

假设你熟悉 VSS 框架和备份创建过程。 这些部分是关于 SQL 编写器如何参与 VSS 备份创建过程的补充信息。

快照创建工作流

下图显示了基于组件的快照创建/备份作期间的数据流关系图。

数据流的屏幕截图。

若要更全面地了解执行备份所涉及的基本任务,将此概述分解为以下阶段非常有用:

备份初始化

在此备份阶段,请求程序(备份应用程序)绑定到快照接口 IvssBackupComponents,并初始化它以准备备份。 还会调用 VSS API IVssGatherWriterMetadata 以指示 VSS 框架从所有编写器收集元数据。

VSS 框架将使用 OnIdentify 事件调用每个注册的编写器,包括编写器元数据的 SQL 编写器。 SQL 编写器查询 SQL Server 实例以获取每个数据库的备份元数据信息,并创建编写器元数据文档。 此阶段也称为 元数据枚举

编写器元数据文档是一个文档,其中包含从编写器传递到请求程序(备份应用程序)的信息。 编写器元数据文档包含以下信息:

  • 应用程序 ID 和友好名称
  • 文件和组件存在的位置
  • 需要在备份中包含和排除哪些文件
  • 还原时应使用哪些选项

这会通过 VSS 框架传回请求者。

备份发现

在此阶段中,请求程序检查编写器元数据文档,并用需要备份的每个组件创建和填充“备份组件文档”。 它还指定了所需的备份选项和参数,作为本文档的一部分。 对于 SQL 编写器,需要备份的每个数据库实例都是一个单独的组件。

备份组件文档

这是请求程序(使用 IVssBackupComponents 接口)在设置还原或备份操作过程中创建的 XML 文档。 备份组件文档包含显式包含组件的列表,这些组件来自参与备份或还原操作的一个或多个编写器。 它不包含隐式包含的组件信息。 相比之下,编写器元数据文档仅包含可能参与备份的编写器组件。 VSS API 文档中描述了备份组件文档的结构细节。

预备份任务

VSS下的预备份任务主要是创建包含备份数据的卷的卷影副本。 备份应用程序将从卷影副本而不是实际卷中保存数据。

请求程序通常在准备备份和创建卷影副本期间等待编写器。 如果 SQL 编写器正在参与备份操作,那么它需要配置其文件及其本身,以准备备份和卷影复制。

准备备份

请求程序需要设置需要执行的备份作类型(IVssBackupComponents::SetBackupState),然后通过 VSS 通知编写器,以便准备使用 IVssBackupComponents::PrepareForBackup备份作。

SQL 编写器有权访问备份组件文档,其中详细介绍了需要备份的数据库。 所有备份卷都应包含在卷快照集中。 SQL 编写器将检测损坏的数据库(备份卷在快照集外部),并在 PostSnapshot 事件期间使备份失败。

文件的实际备份

在此阶段,如果需要,请求程序可以将数据移动到备份介质。 这个阶段的交互是请求程序和 VSS 框架之间的交互。 SQL 编写器不涉及。

  1. 获得作者身份。 返回编写器状态。 请求者可能需要在此处处理任何故障。
  2. 执行备份。

如果此时需要,请求程序可以将数据移动到备份介质。

备份完成

此事件指示备份已成功完成。

如果当前备份是数据库的完整备份(而不是仅副本备份),则这也是 SQL 编写器可以将备份提交为差异基准的时间。

注意事项

请求程序应显式发送此事件(备份完成事件),以允许 SQL 编写器提交差异基准备份。 如果未收到此事件,则创建的备份不是符合条件的差异基础备份。

保存编写器元数据

请求者应保存备份组件文档和每个组件备份元数据以及从快照备份的数据。 SQL 编写器/SQL Server 需要这些编写器元数据才能执行还原操作。

备份终止

请求程序通过释放 IVssBackupComponents 接口或通过调用 IVssBackupComponents::DeleteSnapshots 来终止影子副本。

SQL 编写器元数据文档

这是由编写器(在本例中是 SQL 编写器)使用 IVssCreateWriterMetadata 接口创建的 XML 文档,包含有关编写器状态和组件的信息。 VSS API 文档中介绍了编写器元数据文档的结构详细信息。 下面是 SQL 编写器元数据文档的一些详细信息。

  • 编写器标识信息

    • 编写器名称 - L"SqlServerWriter"
    • 编写器类 ID - 0xa65faa63、0x5ea8、0x4ebc、0x9d、0xbd、0xa0、0xc4、0xdb、0x26、0x91、0x2a
    • 编写器实例 ID - L"SQL Server:SQLWriter"
    • VSSUsageType - VSS_UT_USERDATA
    • VSSSourceType - VSS_ST_TRANSACTEDDB
  • 编写器级别信息 - VSS_APP_BACK_END

  • 还原方法规范 - VSS_RME_RESTORE_IF_CAN_REPLACE。

  • 支持的备份架构(IVssCreateWriterMetadata::SetBackupSchema API)

    • VSS_BS_DIFFERENTIAL:差异备份
    • VSS_BS_TIMESTAMPED - 基于时间戳(用于全文目录文件)。
    • VSS_BS_LAST_MODIFY - 基于上次修改时间的差异备份,
    • VSS_BS_WRITER_SUPPORTS_NEW_TARGET - 支持“新目标位置”选项。
    • VSS_BS_WRITER_SUPPORTS_RESTORE_WITH_MOVE - 支持还原“并移动”
    • VSS_BS_COPY - 支持“仅复制”备份选项。
  • 组件级别信息(包含 SQL 编写器提供的特定于组件级别的信息)

    • 类型 - VSS_CT_FILEGROUP
    • 名称 - 组件的名称(数据库名称)
    • 逻辑路径 – 服务器实例(对于命名实例,格式为“server\instance-name”;对于默认实例,格式为“server”)。
    • 组件标志
    • VSS_CF_APP_ROLLBACK_RECOVERY - 表示 SQL Server 快照始终需要“恢复”阶段,以使文件在非备份(即应用程序回滚)方案中保持一致和可用。
    • 可选 - True
    • 对于还原为可选择 - True
    • 支持的还原方法 - VSS_RME_RESTORE_IF_CAN_REPLACE

SQL Server 中组件集结构的唯一扩展是引入全文目录。 全文目录是容器目录,不能表示为 VSS 数据库或日志文件,因为 VSS 数据库和日志文件没有递归规范。 因此,SQL 编写器使用 VSS 文件组组件 (VSS_CT_FILEGROUP) 来表示数据库级组件和文件组文件,以表示数据库、日志和全文目录文件。

本文档末尾提供了一个示例编写器元数据文档。

启动快照

请求程序通过调用 VSS 框架接口 DoSnapshotSet启动快照进程。

创建快照

此阶段涉及 VSS 框架和 SQL 编写器之间的一系列交互。

  1. 准备快照。 SQL 编写器调用 SQL Server 来准备快照创建。

  2. 冻结。 SQL 编写器调用 SQL Server 来冻结快照中要备份的每个数据库的所有数据库 I/O。 冻结事件返回到 VSS 框架后,VSS 将创建快照。

  3. 解冻。 在此事件中,SQL 编写器调用 SQL Server 实例以 解冻 或恢复正常的 I/O作。

快照创建阶段所需时间不到 60 秒,以避免阻塞所有对数据库的写入操作。

创建快照后

如果快照需要自动恢复,SQL 编写器会针对已选择在快照中的每个数据库执行自动恢复。 有关详细说明,请参阅自动恢复的快照

还原过程

本节介绍还原操作工作流和涉及的各种步骤。

还原操作工作流

下图显示了在执行 VSS 还原操作期间的数据流关系图。

恢复流程的屏幕截图。

若要更全面地了解执行还原所涉及的基本任务,最好将此概述分解为以下部分:

在所有基于 VSS 组件的还原方案中,数据库还原由 SQL 编写器分两个不同的阶段处理。

  • 预还原:SQL 编写器处理验证、文件句柄关闭等。
  • 还原后:SQL 编写器附加数据库,并在需要时执行崩溃恢复。

在这两个阶段之间,备份应用程序负责移动 SQL 下方的相关数据。

还原初始化

在还原的初始化阶段,请求者需要有权访问存储的备份组件文档。

备份作期间生成的备份组件文档作为备份数据的一部分存储。 备份应用程序需要将这些数据传递回 VSS 框架。 SQL 编写器在恢复过程开始时获得对该数据的访问权限。

准备还原

当请求者准备还原时,它使用存储的备份组件文档来确定要还原的内容以及如何还原。 请求者选择要还原的组件,并根据需要设置适当的还原选项。

如果备份应用程序打算将差异备份或日志备份应用于当前还原操作(即需要使用不恢复选项进行还原),则应在每个要还原的数据库的组件创建过程中设置以下选项。

IVssBackupComponents::SetAdditionalRestores(true)

在备份组件文档中设置所有所需详细信息后,请求者会 IVssBackupComponents::PreRestore 调用通过编写器处理的 VSS 生成预还原事件。

SQL 编写器检查提供的备份组件文档,以确定相应的数据库,删除自备份时间以来创建的任何其他文件。 它还会检查磁盘空间并关闭所有打开的数据库文件句柄,以便请求程序可以在还原阶段复制所需的数据。 此阶段允许在请求程序执行实际文件复制之前检测任何早期错误条件。 SQL Server 还会使数据库处于还原状态。 从此开始,在成功还原之前,无法启动数据库。

还原文件

此操作完全特定于请求程序。 请求者(备份应用程序)负责将所需的数据库文件(或为差异恢复复制相关的数据范围)复制到适当的位置。 此操作中未涉及 SQL 编写器。

清理和终止

将所有数据还原到正确的位置后,请求者的调用会通知还原作已完成 IvssBackupComponents::PostRestore,让 SQL 编写器知道可以启动还原后作。 此时,SQL 编写器将执行崩溃恢复的重做阶段。 如果请求者未请求恢复(即未指定 SetAdditionalRestores(true)),那么恢复步骤中的撤销阶段也会在此阶段执行。

备份和还原选项详细信息

本部分详细介绍了 SQL 编写器支持的所有备份和还原选项。

请求程序创建卷影副本

SQL 编写器可能参与了卷影副本创建过程(超出备份和还原的上下文),因为数据库文件的备份卷已被添加到卷快照集中。 在这种情况下,SQL 编写器仅参与元数据枚举、 FreezeThawPrepareForSnapshotPostSnapshot 协调(有关详细信息,请参阅数据流关系图)。

完整备份和还原

SQL 编写器支持在非基于组件的模式和基于组件的模式下执行完整备份和还原作。

非组件化的备份和还原

在非基于组件的备份和还原中,请求者指定要备份和还原的卷或文件夹树。 指定卷和文件夹中的所有数据都已备份和还原。

备份

在非基于组件的备份中,SQL 写入器通过使用快照集中的卷列表来隐式选择数据库。 编写器检查损坏的数据库,如果发现则引发错误。 损坏的数据库是指其中的文件子集由卷列表选择的数据库。 SQL 编写器不支持还原后前滚(差异还原或日志还原)。

还原

请求者还原已以非组件模式备份的数据库。 此类还原之后不能执行前滚还原,如日志还原或差异还原。

对于非基于组件的还原作,必须使用 SQL Server 实例脱机执行还原,否则目标数据库将被删除/分离,以确保文件处于脱机状态。 就地复制文件,然后附加数据库。 所有这些都发生在 SQL 编写器的作用域之外。

基于组件的备份和还原

在基于组件的备份中,请求程序显式地选择要备份/还原的数据库组件(从 SQL 编写器返回给客户端的元数据中)。

备份

在基于组件的备份中,所选数据库的所有备份卷都应包含在卷快照集中。 否则,SQL 编写器将检测损坏的数据库(备份卷在快照集外部)并使备份失败。 完整备份将备份数据库数据和在还原时使数据库处于事务一致状态所需的所有日志文件。

完整还原且不前滚

数据库备份的完整还原有时不需要执行任何额外的前滚。 这可能是因为没有元数据来帮助实现前滚,或者在某些情况下不需要前滚。 本部分简要介绍这两种情况。

无元数据/无前滚

如果在备份操作期间未保存编写器元数据(基于组件的备份元数据),则必须在 SQL Server 实例脱机的情况下执行还原,或者删除/分离目标数据库以确保文件处于脱机状态。 就地复制文件,然后附加数据库。 所有这些都发生在 SQL 编写器的作用域之外。

元数据存在,但不需要额外的前滚

请求者还原在组件化模式下备份的数据库,但没有请求执行前滚操作。 在这种情况下,SQL Server 在还原过程中对数据库执行崩溃恢复。

完整还原并额外前滚

请求者可以发出还原请求,并指定SetAdditionalRestores(true)选项。 此选项表示请求程序将继续进行更多前滚还原(如日志还原、差异还原等)。 这指示 SQL Server 不在还原操作结束时执行恢复步骤。

只有当编写器元数据是在备份期间保存的,并且在还原时可供 SQL 编写器使用时,才可以执行此操作。 在请求程序指示 VSS 执行还原活动之前,必须先运行 SQL Server 服务。

SQL 编写器需要以下序列:

  1. 准备还原每个数据库。 此活动涉及关闭所有文件句柄,以便允许请求程序应用程序复制/装载数据库文件。

  2. 文件由请求程序应用程序复制/装载。

  3. 完成还原(使用 NORECOVERY)。 数据库已联机,但处于正在还原状态

然后,可以使用常规的 SQL Server 备份(差异或日志)通过 VDI 或 Transact-SQL 前滚数据库,或者使用 VSS 框架应用差异还原。

全文支持

SQL 编写器在编写器元数据文档的数据库组件下报告包含递归文件规范的全文目录容器。 选择数据库组件时,它们会自动包含在备份中。

差异备份和还原

差异备份操作仅备份自最新基本完整备份后发生更改的数据。 差异备份仅包含已更改的数据库文件的那些部分。 为了执行此类备份,请求程序(备份应用程序)需要有关数据库文件中更改的位置的信息,以便可以备份相应的文件部分。 在差异备份作期间,SQL 编写器以 VSS 部分文件信息指定的格式提供此信息。 此信息可用于仅备份数据库文件的已更改部分。

备份

在使用 VSS 启动备份操作时,请求者可以通过在备份组件文档中设置DIFFERENTIAL选项VSS_BT_DIFFERENTIAL来发出差异备份。 SQL 编写器将部分文件信息(由 SQL Server 返回)传递给 VSS。 请求者可以通过调用 VSS API 的 IVssComponent::GetPartialFile来获取此文件信息。 此部分文件信息允许请求者只选择已更改的字节范围来备份数据库文件。

在备份前任务阶段,SQL 编写器可确保每个所选数据库存在单个差异基础。

PostSnapshot在事件发生期间,SQL 编写器从 SQL Server 获取部分文件信息,并使用调用将其添加到备份组件文档IVssComponent::AddPartialFile

注意

对于差异备份,SQL 编写器仅支持单个差异基准。 不支持多个基线。

部分文件信息格式

对于在差异备份期间备份的每个数据库,SQL 编写器将存储每个数据库文件的部分文件信息。 请求程序或备份应用程序使用此信息在文件的实际备份期间仅将文件的相关部分复制到备份介质。

有关此部分文件信息的格式的详细信息,请参阅卷影复制服务(VSS)。

请求程序可以通过调用 IVssComponent::GetPartialFileCountIVssComponent::GetPartialFile 来确定这些文件。 IVssComponent::GetPartialFile 返回指向该文件的路径和文件名,以及一个范围字符串,指示需要在文件中备份的内容。

有关部分文件信息检索的详细信息,请参阅 VSS 文档

备份文件

在此阶段,备份应用程序应查看存储在备份组件文档中的编写器元数据,并仅备份文件的相关部分。 (对于全文目录文件,应根据文件时间戳完成此备份。本文稍后将对此进行介绍。

差异备份始终与数据库中现有的最新基础备份相关。 在还原时,SQL Server 检测到基础备份和差异备份不匹配。 因此,备份应用程序或系统管理员负责确保差异相对于预期的完整备份。 如果某些带外过程进行了另一次完整备份,则备份应用程序可能无法还原差异,因为它不拥有基础备份。

目前,如果字节范围信息(部分文件信息)太大(缓冲区大小超过 64 KB),SQL Server 将引发错误,指示用户执行完整备份。

故障排除

文件添加/删除/收缩/增长/逻辑重命名/物理重命名在备份故障排除过程中将生成有趣的案例。

获取基准后新添加的文件

这些文件包含在部分规范中,因为数据库文件的每个标头都需要位于部分规范中。 除标题页之外,所有分配的页都需要包含在部分规范中。

获取基准后删除的文件

获取基准后,可以删除数据文件。 差异备份期间,此类文件不包括在编写器元数据文档中。 此外,不会有部分信息与已删除的文件相关联。

获取基准后收缩的文件

在服务器中禁用文件收缩之前,不会从文件收集部分信息。 这可确保 VSS 永远不会包含与数据文件的收缩区域对应的任何部分信息。

获取基准后增长的文件

如果在收集部分信息之前发生了增长,那么部分信息应当包括增长区域内已分配的页面。 如果在收集部分信息后发生增长,则部分信息不包括增长区域的变化。 在下面的部分,你将看到此类更改已由日志前滚还原。

获取基准后以逻辑方式重命名的文件

文件的逻辑重命名不会影响备份或还原,因为文件逻辑名称不会在编写器元数据文档或备份组件文档中的任意位置引用。

有关详细信息,请参阅 编写器元数据文档: 本文后面的示例。

获取基准后以物理方式重命名的文件

在数据库重启之前,物理数据库文件重命名不会生效。 因此,部分信息缓冲区中的数据库配置信息或文件路径信息仍然基于旧的物理路径,这些物理路径是快照上这些数据库文件的惟一有效路径。

还原

在差异还原期间,请求程序返回给 SQL 编写器的备份元数据具有备份类型信息。 因此,不需要对 SQL 编写器进行特殊处理。 SQL Server 会发现它本身就是一个差异还原。 SQL Server 处理这种差异还原的方式与处理不通过 VSS 执行的本机差异还原的方式相同。

还原前阶段

在此阶段,SQL Server 会根据差异备份的文件元数据将所有文件的大小调整为适当的大小。 如果文件已增长,SQL Server 会将增长部分归零。 如果必须创建一个新文件(该文件是在基础创建后创建的),SQL Server 会从中排除新文件。 它还会关闭所有文件句柄,以便备份应用程序能够用备份介质中恢复的数据覆盖文件。

还原文件

客户端应根据部分文件规范恢复文件。 如编写器元数据中存储的部分文件规范中所述,应将数据还原到数据库文件的相同偏移量/范围。

在还原时,数据库文件的添加、删除、增长、收缩、逻辑重命名和物理重命名再次构成了有趣的故障排除案例。

如果数据库文件是在获取完整基准后添加的

在还原准备阶段,SQL Server 必须预先创建此类文件。 它们应已扩展到正确大小,并已归零。客户端只需要按照部分规范放置数据(部分规范包括所有分配的区段)。

如果数据库文件是在获取完整基准后删除的

SQL Server 提供的部分信息不包括此类文件删除的任何跟踪信息。 SQL Server 负责检测要删除的文件,方法是将还原的文件元数据与现有容器进行比较,并实际删除它们。 在还原之前完成此作,作为准备步骤。

如果数据库文件是在获取完整基准后增长的

在还原准备阶段,SQL Server 必须将此类文件扩展到正确的大小。 扩展区域也必须由 SQL Server 清零。 因此,客户端甚至可以按照部分规范在增长区域中安全地布局数据。 如果文件是在获取部分信息之后生成的,则将通过重新播放与差异备份一起备份的日志来还原增长区域中的更改。

如果数据库文件是在获取完整基准后收缩的

SQL Server 负责根据元数据将文件截断到所需的大小。 在还原之前完成此作,作为准备步骤。

如果数据库文件是在获取完整基准后以逻辑方式重命名的

这不会影响还原,因为逻辑名称不会显示在编写器元数据文档或备份组件文档中。 当客户端将更改应用于包含系统目录信息的主数据库文件时,将还原逻辑名称更改。

如果数据库文件是在获取完整基准后以物理方式重命名的

如果在差异备份时,重命名未生效,客户端仍将数据还原到旧位置。 数据库在还原后重启会导致物理重命名生效。 如果在差异备份时,物理文件重命名已生效,则从新的物理路径备份部分数据(如果有)。

还原后

在还原后事件期间,SQL 编写器执行数据库的正常重做操作和恢复(如果 SetAdditionalRestores() 被设置为 False)。

全文目录的差异备份和还原

SQL Server 全文目录是需要与其他数据库文件一起备份或还原的数据库资源的一部分。 对于全文目录,差异备份是基于时间戳的。 SQL Server VSS 差异备份和还原具有单个基准备份。 换句话说,不同的容器不会有不同的基准。 对于 VSS 全文目录备份,这意味着对于所有全文目录容器,差异备份是基于单时间戳的,与本机 SQL Server 差异备份的情况不同,其中每个全文目录容器有一个时间戳基础。

在 VSS 中,此时间戳表示为组件范围内的属性,该属性在完整备份期间进行设置并在后续差异备份期间使用。

OnIdentify

OnIdentify中,SQL 编写器调用 IVssCreateWriterMetadata::SetBackupSchema() 以设置值 VSS_BS_TIMESTAMPED。 这向备份应用程序指示 SQL 编写器拥有对差异基准的管理。

设置基本时间戳

基本时间戳在完整备份期间进行设置。 在 OnPostSnapshot() 中,编写器调用 IVssComponent::SetBackupStamp(),将时间戳与组件一起存储在备份文档中。

差异备份

备份应用程序从基础完整备份中检索此时间戳,并通过调用 IVssComponent::GetBackupStamp() 从上一个基础备份中检索基戳,使该时间戳可供编写器使用。 然后,通过调用 IVssBackupComponent::SetPreviousBackupStamp() 使它对编写器可用。 然后,编写器通过调用 IVssComponent::GetPreviousBackupStamp() 检索该时间戳,并将其转换为可用于 IVssComponent::AddDifferencedFilesByLastModifyTime() 的时间戳。

备份应用程序在差异备份期间的责任

在差异备份期间,备份应用程序负责:

  • 备份上次修改时间戳大于组件中文件集的上次修改时间指定的时间戳的任何文件(整个文件)

  • 跟踪和检测已删除的文件。

备份应用程序在差异还原期间的责任

在差异还原期间,备份应用程序负责:

  • 还原已备份的所有文件,无论是创建新文件(如果该文件尚不存在),还是覆盖现有文件(如果已存在)。

  • 如果还原的文件比现有文件大,则在放置内容之前先增大文件。

  • 如果还原文件小于现有文件,则将该文件截断为与还原文件相同的大小。

  • 删除应删除的所有文件;也就是说,从差异备份的时间点开始,不应存在这些文件。

仅限复制的备份

有时有必要为特殊目的进行备份。 例如,出于测试目的,可能需要创建数据库的副本。 此备份不应影响数据库的整体备份和还原过程。 COPY_ONLY使用此选项指定备份是在带外完成的,不应影响备份的正常顺序。 SQL 编写器支持 SQL Server 实例的仅复制备份类型。

在备份发现阶段,SQL 编写器将使用 IVssCreateWriterMetadata::SetBackupSchema 调用来设置受支持的备份架构选项 VSS_BS_COPY,从而表明它执行仅复制备份的能力。 请求者可以通过调用IVssBackupComponents::SetBackupStateVSS_BACKUP_TYPE选项设置为VSS_BT_COPY,将备份类型设定为仅复制备份。

选择仅复制备份时,假定磁盘上的文件会复制到备份介质(由请求者),而不管每个文件的备份历史记录的状态如何。 SQL Server 不会更新备份历史记录。 这种类型的备份不会构成将来进行差异备份操作的基础备份,也不会干扰之前的差异备份历史记录。

还原并移动

VSS 允许请求程序(备份应用程序)使用 IVssComponent::SetNewTarget 调用指定新的还原目标。 在 PreRestore()PostRestore() 中,SQL 编写器都会检查是否至少指定了一个新的对象。 备份应用程序负责在实际文件还原/复制时间将文件物理复制到新位置。

只允许备份应用程序为物理路径指定新目标,而不允许指定文件规范。 例如,对于位于的数据库 c:\data\test.mdf文件,无法更改实际文件名 test.mdf 。 只能更改路径 c:\data 。 对于位于 c:\ftdata\foo 的全文目录容器,由于在 VSS 中的文件规范是 "*",而路径规范是 c:\ftdata\foo,因此可以更改整个路径。

数据库重命名

请求者可能需要使用新名称还原 SQL Server 数据库,尤其是在数据库与原始数据库并排还原时。 在还原操作期间,请求者可以在使用 VSS 调用IVssBackupComponents::SetRestoreOptions()(在wszRestoreOptions参数中)时,通过将自定义还原选项设置为“新建组件名称”= <“新建名称”>来指定这个选项。

SQL 编写器获取新组件名称值的整个内容,并将其用作已还原数据库的新名称。 如果未指定任何选项,SQL Server 将还原其原始名称(组件名称)的数据库。

注意

SQL 编写器当前不支持 跨实例重命名 ,无法将数据库移动到新实例。

自动恢复的快照

通常,通过使用 VSS 框架获得的 SQL Server 数据库快照会处于未恢复状态。 在进入恢复阶段以回滚运行中的事务并将数据库置于一致状态之前,无法安全地访问快照中的数据。 由于快照处于只读状态,因此无法通过附加数据库的正常过程来恢复快照。

在快照创建过程中,可以自动恢复快照。 作为编写器元数据文档的一部分,SQL 编写器使用 VSS_CF_APP_ROLLBACK_RECOVERY 组件标志指示在访问数据库之前需要对数据库执行恢复。在指定快照集时,请求者可以指定快照是应用回滚快照(即,所有数据库文件应处于应用程序使用的一致状态)或用于备份的快照(在系统故障时用于备份以后要恢复的数据)。

请求程序应设置 VSS_VOLSNAP_ATTR_ROLLBACK_RECOVERY,以指示应出于非备份目的备份此组件。 然后,VSS 将 SQL 编写器在选定的组件上指定的 VSS_CF_APP_ROLLBACK_RECOVERYVSS_VOLSNAP_ATTR_ROLLBACK_RECOVERY 相关联,并确认正在进行自动恢复。 VSS 使快照在有限的时间内可写入,并自动将 VSS_VOLSNAP_ATTR_AUTORECOVERY 位添加到快照上下文。

在 SQL Server 中,自动恢复应仅应用于应用回滚快照,但不适用于备份快照。 对于应用程序回滚快照,SQL 编写器在 PostSnapShotevent 期间启动自动恢复过程。 此过程针对请求者显式选择的快照集中的每个 SQL Server 数据库执行以下操作:

  • 将快照数据库附加到原始 SQL Server 实例(即原始数据库附加到的实例)。

  • 恢复数据库(这是“附加”操作的一部分)。

  • 收缩日志文件。

    这减少了 VSS 框架需要进行的不必要的写时复制操作(如果 VSS 提供程序是软件提供程序)。 收缩日志文件是默认行为。 可以通过将值设置为以下注册表项 1来禁用此功能。

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SQLWriter\Settings\DisableLogShrink
    

    在快照可用于从日志中导出特定页面(在特定时间点)中的数据以修复联机数据库中的问题的情况,这可能很有用。

  • 分离数据库。

现在,可以附加一致的已恢复快照用于查询。

多数据库事务

在较旧版本的 SQL Server 中,快照数据库有时可能包含一些正在进行的多数据库事务。 在恢复操作期间,SQL 编写器将使用假定中止选项将数据库附加到快照上。 这会回滚尚未提交的任何多数据库事务(包括处于“准备提交”状态的任何事务)。 这可能会导致快照集中的数据库之间出现一些不一致。

例如,考虑两个数据库 A 和 B。这两个数据库之间存在分布式事务,此事务在数据库 A 中处于已提交状态,在数据库 B 中处于“准备提交”状态。作为自动恢复过程的一部分,此事务在数据库 A 中提交,并在数据库 B 中回滚。这可能会导致快照集中出现一些不一致。

较新版本的 Windows 改进了Microsoft分布式事务处理协调器(MS DTC)组件,可修复跨 SQL Server 实例跨数据库的事务的这种不一致问题。 较新版本的 SQL Server 修复了跨 SQL Server 实例中的数据库的事务的这些不一致问题。

自动恢复快照的安全隐患

对于 VSS 快照,在自动恢复后,使用访问控制列表(ACL)保护文件,以仅允许访问 SQL Server 帐户所属的特殊内置组。 这意味着“box 管理员”或该特殊组的成员将能够附加数据库。 请求在快照上附加数据库文件的客户端必须是 Builtin/Administrators 或 SQL Server 帐户的成员。

简单恢复模式用户数据库

如果使用简单恢复模式的用户数据库与master数据库一起还原,则可以使用与master数据库相同的技术来还原用户数据库:在实例关闭时,只需复制或装载卷即可。 启动 SQL 实例时,所有内容都将恢复。

前滚用户数据库

如果要同时恢复 master 数据库,并前滚用户数据库,则实例不得同时启动并恢复 master 数据库和用户数据库。

该过程如下:

  1. 确保 SQL Server 实例已停止。

  2. 分两个阶段执行还原。

    1. 通过 VSS 的文件复制或卷装载,还原应同时恢复的系统数据库和用户数据库(即简单恢复模型中的用户数据库)。

      • 如果要前滚的用户数据库与系统数据库不在同一卷上,则此时不应恢复该卷。 此方案需要在备份之前进行规划。

      • 如果用户数据库与系统数据库位于同一卷上,则需要对 SQL Server 隐藏用户数据库。

    2. 使用 -f 参数启动 SQL Server 实例。 使用 -f 启动选项时,只能还原该 master 数据库。

      1. 针对要前滚的每个数据库发出 ALTER DATABASE <database> SET OFFLINE(或分离数据库)。

      2. 停止 SQL Server 实例。

      3. 启动 SQL Server 实例(用户数据库的文件无法被 SQL Server 访问,因此无法进行前滚操作)。

使用 VSS 还原用户数据库 WITH NORECOVERY,如完整还原并额外前滚中所述。

编写器元数据文档:示例

在计算机Server1上的 SQL Server 实例Instance1中,一个名为DB1的数据库包含以下数据库/日志文件:

  • 存储在 c:\db\DB1.mdf 中名为“primary”的数据库文件
  • 存储在 c:\db\DB1.ndf 中名为“secondary”的数据库文件
  • 存储在 c:\db\DB1.ldf 中名为“log”的数据库日志文件
  • 存储在目录c:\db\ftdata\foo下的名为“foo”的全文检索目录
  • 名为“bar”的全文目录存储在目录c:\db\ftdata\bar下。

下面是数据库的编写器元数据:

数据库级文件组组件

主数据库文件:

ComponentType: VSS_CT_FILEGROUP
LogicalPath: "Server1\Instance1"
ComponentName: "DB1"
Caption: NULL
pbIcon: NULL
cbIcon: 0
bRestoreMetadata: FALSE
NotifyOnBackupComplete: TRUE
Selectable: TRUE
SelectableForRestore: TRUE
ComponentFlags: VSS_CF_APP_ROLLBACK_RECOVERY

辅助数据库文件:

LogicalPath: "Server1\Instance1"
GroupName: "DB1"
Path: "c:\db"
FileSpec: "DB1.mdf"
Recursive: FALSE
AlternatePath: NULL
BackupTypeMask: VSS_FSBT_ALL_BACKUP_REQUIRED | VSS_FSBT_ALL_SNAPSHOT_REQUIRED
Filegroup file
LogicalPath: "Server1\Instance1"
GroupName: "DB1"
Path: "c:\db"
FileSpec: "DB1.ndf"
Recursive: FALSE
AlternatePath: NULL
BackupTypeMask: VSS_FSBT_ALL_BACKUP_REQUIRED | VSS_FSBT_ALL_SNAPSHOT_REQUIRED

全文文件日志:

LogicalPath: "Server1\Instance1"
GroupName: "DB1"
Path: "c:\db"
FileSpec: "DB1.ldf"
Recursive: FALSE
AlternatePath: NULL
BackupTypeMask: VSS_FSBT_ALL_BACKUP_REQUIRED | VSS_FSBT_ALL_SNAPSHOT_REQUIRED

全文文件 foo

LogicalPath: "Server1\Instance1"
GroupName: "DB1"
Path: "c:\db\ftdata\foo"
FileSpec: "*"
Recursive: TRUE
AlternatePath: NULL
BackupTypeMask: VSS_FSBT_ALL_BACKUP_REQUIRED | VSS_FSBT_ALL_SNAPSHOT_REQUIRED

全文文件栏

LogicalPath: "Server1\Instance1"
GroupName: "DB1"
Path: "c:\db\ftdata\bar"
FileSpec: "*"
Recursive: TRUE
AlternatePath: NULL
BackupTypeMask: VSS_FSBT_ALL_BACKUP_REQUIRED | VSS_FSBT_ALL_SNAPSHOT_REQUIRED

如果服务器实例是计算机上的默认实例,则逻辑路径将成为一部分: Server1

特殊情况

本节介绍基于 SQL 编写器的备份和还原操作期间遇到的一些特殊情况。

自动关闭数据库

对于非基于组件的备份,在检查撕裂条件时,会自动关闭数据库,但在备份操作期间,自动关闭的数据库不会被显式冻结。

此处的预期方案是,许多关闭的数据库可能存在,并且你想要将快照的成本降到最低。 自动关闭的数据库通常用于资源稀缺的低端配置。

文件列表

每个数据库的文件列表在准备备份事件前的枚举步骤中确定。 如果数据库文件列表在枚举和冻结之间发生更改,则数据库可能会被删除,除非应用程序重新检查文件列表。 虽然这种情况不太可能,但供应商需要注意。

停止的实例

如果在枚举步骤发生时未运行 SQL Server 实例,则无法选择这些实例的数据库。

如果实例在枚举和“准备备份”事件之间的间隔内停止,则将忽略已停止实例中的任何数据库。

系统和用户数据库

SQL Server 中的系统数据库包括mastermodelmsdb作为 SQL Server 的一部分随附和安装的数据库。 本节介绍如何在 VSS 快照备份过程中处理这些数据库。

master只能通过停止实例来还原数据库,替换数据库文件(由备份应用程序完成),然后重启实例。 无法前滚。

SQL 编写器支持联机还原 modelmsdb 数据库,而无需关闭实例。