无法还原(错误3456)


9

我的情况不容易弄清楚,以为我会在这个论坛上问其他人是否有建议。

我正在Windows Server 2008R2 Enterprise上运行SQL Server 2008 R2 Standard SP3。

数据库需要一些维护,事实上,我需要在另一台服务器上进行还原。我使用COPY_ONLY进行了完整的数据库备份,再加上一组4个日志备份。

  1. 在开始之前,创建tlogbackup1
  2. 从转换FULLBULK_LOGGED恢复模式
  3. 添加新文件组
  4. 将文件添加到newfilegroup
  5. 将newfilegroup设置为默认
  6. 选择进入表(在newfilegroup上)
  7. 放下原始表
  8. 删除原始文件
  9. 删除原始文件组
  10. 更改新表的名称以匹配原始表
  11. 更改newfilegroup的文件名以匹配原始文件组
  12. 更改目录中的文件名以匹配原始文件名
  13. 在操作系统级别更改文件名以匹配原始文件名
  14. 将默认文件组设置为原始文件组
  15. 使数据库联机
  16. 从转换BULK_LOGGEDFULL恢复模式
  17. 完成所有步骤后,创建tlogbackup2

由于还原服务器上驱动器号的更改,所有备份的还原必须使用WITH MOVE。

恢复步骤:

RESTORE database SomeDB FROM DISK = 'D:\REPRO\SomeDB.bak'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup1.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup2.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

最终的日志恢复达到100%,然后失败,并显示错误3456:

已处理368页的数据库'SomeDB',文件'SystemData'的文件1。

已处理数据库'SomeDB'的7656520页,文件1上的文件'SystemDataPDS'。

已处理数据库``SomeDB''的172430页,文件1上的文件``SystemData_log''

消息3456,级别16,状态1,行1
无法重做日志记录(210388:123648:232),页面(4:8088)上的数据库'SomeDB'(数据库ID 6)的事务ID(0:1016710921) 。页面:LSN =(0:0:1),类型=11。日志:操作码= 4,上下文11,PrevPageLSN:(210388:122007:1)。从数据库备份还原,或修复数据库。消息3013,级别16,状态1,第1行RESTORE LOG正在异常终止。

只是为了验证完整的数据库备份正常,我将其还原为ran CHECKDB,并且没有错误。

欢迎所有反馈。

提前致谢,

内德·奥特


1
您能否详细说明为什么您认为自己拥有完整的日志链?当您将数据库切换为BULK_LOGGED模式并开始弄乱架构的那一刻,所有关闭日志链的押注都被取消了。
Thomas Kejser 2015年

谢谢您的答复,托马斯。我现在看到我的帖子标题不正确。我不需要时间点恢复,而是完全还原到第4个tlog备份的结尾。因此,设置BULK_LOGGED应该不会引起任何问题。我看不到我的所作所为会导致第二次tlog备份失败-SQL Server支持所有命令,并且我在较小的数据库中执行了完全相同的步骤(尽管不是在相同的数据上),并且能够恢复第二个tlog备份而没有问题。
NedOtter

该错误看起来像损坏。这是一个内部错误。您可以验证所有备份文件的完整性吗?他们有校验和吗?
usr

我确实通过运行CHECKDB验证了完整的数据库备份是否存在0个错误。我将不得不检查是否使用了CHECKSUM。
NedOtter 2015年

1
如果备份启用了校验和,则还应将校验和用于还原。页面类型11是PFS页面,这意味着您无法对其进行修复,只能进行完全还原。另外,您不说何时进行仅复制备份。时间线上的备份在哪里?
罗伯特·戴维斯

Answers:


9

为了理解为什么会引发错误3456,我们需要退后一步,并了解SQL Server如何处理这一恢复的角落。

当SQL Server重做操作时,并且该重做是页面修改,它将进行快速检查。在页面标题中,最终将有一个PageLSN,指示该页面记录的最后一个修改该页面的LSN。这样考虑一下,该页面会跟踪上次对其进行修改的LSN。这是PageLSN

每次进行日志页面修改操作时,该日志记录都会包含一些LSN。即,日志记录的LSN(认为... 当前LSN),然后具有所谓的上一页LSNPrevPageLSN向前)。因此,当我们修改页面时,放入日志记录的数据片段之一就是页面指示您修改页面之前最后一个LSN

像这样想吧...您的汽车需要做一些工作。机械师约翰在您的汽车上工作,在发动机舱中有一个小标签,机械师约翰写道“约翰最后在这辆车上工作”。然后,下次您将汽车带到另一家商店时,Mechanic Mark看着引擎舱,然后看到Mechanic John在这辆车上工作了。他在数据表中写下了这些信息。与SQL Server相同。

这可能会造成一些混乱,因此请在下面的连续页面修改中查看此图,以及PageLSNand的PrevPageLSN关系:

在此处输入图片说明

让我们再来一遍,因为当您需要在页面上重做操作(还原,恢复,HA等)时,所有这些都将发挥作用。当SQL Server需要重做页面操作时,它会进行完整性检查,以查看PageLSN页面上的PrevPageLSN是否与日志记录包含的匹配。如果不相等,则将引发错误3456。

PageLSN是否等于PrevPageLSN?没有???停止并引发错误3456 ...

让我们分析您的错误消息,其中包括如何:

无法重做页面(4:8088)上数据库'SomeDB'(数据库ID 6)的事务ID(0:1016710921)的日志记录(210388:123648:232)。页面:LSN =(0:0:1),类型=11。日志:OpCode = 4,上下文11,PrevPageLSN:(210388:122007:1)。从数据库备份还原,或修复数据库。消息3013,级别16,状态1,第1行RESTORE LOG正在异常终止。

我已将具有不等式导致错误的两个数据加粗。您可以看到我们的PageLSN0:0:1(在页面的标题中找到了),我们的PrevPageLSN210388:122007:1(在试图重做的日志记录中的数据中找到了)。这些显然不相等,因此为err3456。

因此,要找出此事件的原因,就是要找出这里存在差异的原因。我们确实需要跟踪4:8088页的生命周期,并查看断开连接的位置。不幸的是,没有进一步的信息或动手的故障排除,除了向您提供此恢复操作的背景以及导致错误的原因之外,我无能为力。


我知道已经有一段时间了,但还是...好东西,感谢您的详尽解释!
RThomas
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.