还原差异备份会创建 DEFUNCT 日志文件吗?

Fil*_*ies 11 sql-server backup restore sql-server-2012

这是我的问题。我正在尝试通过完整还原将数据库移动到新服务器,然后通过快速差异备份/还原进行切换。我可以毫无问题地进行完整还原,但是在还原差异备份时,我收到以下警告:

消息 3127,级别 16,状态 1,第 1 行 恢复的数据库 'DatabaseName' 的文件 'Database_Log2' 处于失效状态,因为该数据库正在使用简单恢复模型并且该文件被标记为可读写访问。因此,只能通过分段还原来恢复只读文件。

数据库恢复并被视为联机,但由于此 DEFUNCT 文件导致任何备份操作失败,并出现以下错误:

消息 3636,级别 16,状态 2,第 1 行处理数据库 ID 10 文件 ID 6 的“BackupMetadata”元数据时出错。消息 3046,级别 16,状态 2,第 1 行遇到不一致的元数据。唯一可能的备份操作是使用 WITH CONTINUE_AFTER_ERROR 或 NO_TRUNCATE 选项的尾日志备份。消息 3013,级别 16,状态 1,第 1 行 BACKUP DATABASE 异常终止。

如果我在完整和差异上执行 RESTORE FILELISTONLY 都会给我相同的输出,这与我从源数据库上的 sys.database_files 看到的相匹配。服务器为 SQL2012 SP1,开发版。

我可以做一个完整的备份,然后立即做一个差异,并将这些文件还原到同一服务器上的不同数据库,并看到完全相同的问题,因此差异是如何创建的。如果我使用 RECOVERY 还原完整备份,则没有问题。我不知道这个文件是否曾经存在于这个数据库中,但完全有可能这个文件曾经存在并且很久以前被删除了。如果我在恢复的数据库上查询 sys.database_files,DEFUNCT 文件具有 drop_lsn 的值,这似乎证实了这一点。目前在源数据库中只有一个文件组 (PRIMARY)、4 个数据文件和一个日志文件。

有任何想法吗?

Fil*_*ies 5

以下是在 SQL 2012 SP1 Developer Edition 上测试的重现此问题的步骤。这不会发生在 SQL 2008 上。总而言之,当模型数据库处于 SIMPLE 恢复状态时,在 SQL 2012 中创建的数据库在存在额外日志文件时进行了完整备份,如果该额外日志文件存在,则无法创建可用的差异备份曾经删除。

ALTER DATABASE [model] SET RECOVERY SIMPLE
GO
CREATE DATABASE [DefunctTest]
GO
ALTER DATABASE [DefunctTest] ADD LOG FILE ( NAME = N'DefunctTest_log2', FILENAME = N'D:\DefunctTest_log2.ldf' , SIZE = 25600KB , FILEGROWTH = 10%)
GO
BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestPostLogFile.bak' WITH INIT
GO
ALTER DATABASE [DefunctTest]  REMOVE FILE [DefunctTest_log2]
GO

BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestFull.bak' WITH INIT
GO
BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestDiff.bak' WITH DIFFERENTIAL, INIT
GO
--Show that the backups only have the one log file.
RESTORE FILELISTONLY FROM DISK = 'D:\DefunctTestFull.bak'
RESTORE FILELISTONLY FROM DISK = 'D:\DefunctTestDiff.bak'
GO
RESTORE DATABASE [DefunctTest2] FROM DISK = 'D:\DefunctTestFull.bak' WITH 
MOVE 'DefunctTest' TO 'D:\DefunctTest2.mdf',
MOVE 'DefunctTest_log' TO 'D:\DefunctTest2_log.ldf', REPLACE, NORECOVERY
GO
--This restore will have the error.
RESTORE DATABASE [DefunctTest2] FROM DISK = 'D:\DefunctTestDiff.bak' WITH RECOVERY
GO

USE [DefunctTest2]
SELECT * FROM sys.database_files
GO
Run Code Online (Sandbox Code Playgroud)

在此处提交了此错误的连接项目。我能够删除这个失效文件的唯一方法是分离数据库,并使用 ATTACH_REBUILD_LOG 重新附加。

更新:在我的重现脚本中创建此场景的错误似乎已被此知识库修复:https : //support.microsoft.com/en-us/kb/2830400。从评论看来,SQL2012/2014 有一个额外的修复程序可用,场景看起来非常相似:https : //support.microsoft.com/en-us/kb/3009576

  • 上周我与这个问题发生了争执,这个线程帮助我解决了这个问题,所以谢谢你。看起来修复程序在 SQL 2012 SP2 CU3 中:https://support.microsoft.com/en-us/kb/3009576 (2认同)