使用具有多条带化的 VDI 应用程序还原 SQL Server 数据库可能会失败,并出现错误 3456

本文可帮助你解决使用基于虚拟设备接口(VDI)的应用程序还原 SQL Server 数据库时发生的问题。

现象

在 SQL Server 2019 或更高版本上还原多条带 虚拟设备接口(VDI) 完整备份时,可能会遇到错误 MSSQLSERVER_3456

Msg 3456, Level 16, State 1, Line <LineNumber>
Could not redo log record (120600:18965748:1), for transaction ID (0:1527178398), on page (14:1987189), allocation unit 72057761533001728, database 'DB1_STRIPE' (database ID 8).
Page: LSN = (120598:23255372:8), allocation unit = 72057761317781504, type = 1. Log: OpCode = 6, context 2, PrevPageLSN: (120600:18965371:85).

原因

当 SQL Server 备份到 VDI 时,它会通过缓冲区将数据传递到 VDI。 然后,VDI 处理如何存储该备份的格式。 但是,在许多情况下,VDI 客户端可能只需要每个数据页的单个副本。

将备份条带到 VDI 时,多个备份设备共同构成了完整备份的内容。 数据以异步方式写入,数据复制顺序由 VDI 客户端的逻辑处理。 由于数据复制阶段是异步的,因此可以按顺序写入数据。 但是,在 SQL Server 2019 之前的完整备份方案中,每个数据页只有一个副本。 因此,当 VDI 客户端将数据发送到 SQL Server 从中读取的缓冲区进行还原时,SQL Server 仍能够确切地知道每个数据页的还原位置以及如何还原。 随着 SQL Server 2019 中延迟日志固定的引入,可以在备份文件中找到数据页的多个副本。 由于完整备份中发生小型差异备份,存在多个副本(有关详细信息,请参阅 “详细信息 ”部分)。 VDI 客户端要么不需要同一数据页的多个副本,要么按错误顺序将数据页传回 SQL Server。 此行为会导致还原失败。 错误 3456 Could not redo log record 指示 SQL Server 尝试应用需要最新版本的数据页的日志记录,但会发现较旧版本。

解决方法

  1. 根据配置,需要为 SQL Server 实例启用一个或多个跟踪标志作为启动参数:

    • 如果在实例充当主副本或没有可用性组的实例时执行完整备份,请启用跟踪标志 3471 以禁用完整备份的延迟日志固定功能。

    • 如果在实例充当主副本或没有可用性组的实例时进行差异备份,请启用跟踪标志 3475 以禁用差异备份的延迟日志固定功能。

    • 如果在实例充当辅助副本时使用 COPY_ONLY执行完整备份,请启用跟踪标志 3472 以禁用差异备份的延迟日志固定功能。

  2. 请重新启动 SQL Server。

  3. 再次执行完整备份或差异备份。

注意

还可以使用 DBCC TRACEON 命令暂时启用这些跟踪标志。

DBCC TRACEON(3471,3472,3475,-1)

如果无法立即重启 SQL Server 实例,可以使用此命令来缓解此问题。

重要

由于此问题,如果满足以下条件,则现有备份可能无法还原:

  • 备份是在启用延迟日志固定功能的情况下进行的。
  • 备份工具正在使用 VDI。
  • 备份是使用多条带化完成的(备份到多个文件)。

我们鼓励你在测试服务器上还原现有备份,以检查是否可以成功还原这些备份。

详细信息

SQL Server 2019 引入了一项称为延迟日志固定的功能。 在引入此功能之前,在完整数据库备份期间,SQL Server 会阻止发生任何事务(固定日志),复制数据和日志,然后在开头删除该引脚。 使用此功能时,SQL Server 会将事务从发生(固定日志)延迟到备份持续时间的末尾,而不是在开始时立即停止。 此功能旨在避免完整备份期间出现完整事务日志问题(MSSQLSERVER_9002 错误),而完整备份需要很长时间才能完成。 由于日志固定延迟,因此在备份正在进行时,仍允许将事务应用于数据库的数据页。 SQL Server 维护一个位图来标识自正在进行的完整备份开始时间以来已更改的页面,以便它可以进行小型差异备份。 这样,它就会获取备份整个数据库时更改的每个数据页的更新副本。 这会导致某些数据页的额外副本。 此外,将创建完整备份的这一额外部分。