修复: 速度慢或死锁时还原数据库和 SQL Server 2012年中同时执行语句

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 2725950
Microsoft 将 Microsoft SQL Server 2012年修补程序分发作为一个可下载的文件。修补程序是累积性的因为每个新版本包含的所有修补程序和所有安全修补程序包含上一个 SQL Server 2012年修补程序版本。
症状

情境 1

请考虑以下情形:
  • 在 Microsoft SQL Server 2012年数据库还原。
  • 在数据库还原操作完成之前,另一个进程引用sys.database_recovery_status目录视图,并且需要在同一个数据库上的锁。例如,您可以执行以下SELECT语句:

    SELECT * FROM sys.database_recovery_status
在这种情况下,性能降低发生在其中一个SELECT语句的过程将等待,直到数据库还原过程完成。

情境 2

请考虑以下情形:
  • 您还原 SQL Server 2012年中的数据库。
  • 在数据库还原操作完成之前,您可以执行以下语句:

    IF EXISTS (SELECT * FROM sys.database_recovery_status WHERE database_id= DataBaseID AND database_guid IS NOT NULL)
    注意" 服务器定义数据库 Id 表示在其上执行数据库还原操作的数据库 ID。
在这种情况下,数据库恢复过程中发生死锁。此死锁导致数据库还原过程失败。
原因
"症状"一节所述的两个方案都由同一原因引起。

在"Scenario1"部分中,出现问题的原因的数据库还原过程中需要在数据库上的排他锁。当执行语句在该节中提到时,对同一个数据库需要共享的锁。因此,共享的锁等待的排它锁独占锁定被释放之前。

在"方案 2"部分中,当您执行该语句在该部分中,提到共享的锁则需要同时在同一个数据库和sys.sysdbreg表。数据库还原过程的最后一个阶段的过程中需要更新的sys.sysdbreg表锁。但是,不是从数据库释放共享的锁。因此, sys.sysdbreg表发生死锁,并且数据库还原过程被确定为死锁牺牲品。

解决方案

累积更新信息

对于 SQL Server 2012 Service Pack 1 的累积更新包 1

此问题的修补程序是累积更新 1 中首次推出。有关如何为 SQL Server 2012 Service Pack 1 获取此累积更新包的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2765331 对于 SQL Server 2012 Service Pack 1 的累积更新包 1
注意 生成是累积性的因为每个新修补程序版本包含的所有修补程序和所有安全修补程序包含上一个 SQL Server 2012年修补程序版本。我们建议您考虑将应用了最新的修补程序版本包含此修复程序。有关详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2772858 在 SQL Server 2012 Service Pack 1 发布之后发布的 SQL Server 2012年生成

累积更新包 3 为 SQL Server 2012

此问题的修补程序是累积更新 3 中首次推出。有关如何为 SQL Server 2012年获取此累积更新包的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2723749 对于 SQL Server 2012年累积更新 3
注意 生成是累积性的因为每个新修补程序版本包含的所有修补程序和所有安全修补程序包含上一个 SQL Server 2012年修补程序版本。我们建议您考虑将应用了最新的修补程序版本包含此修复程序。有关详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2692828 在 SQL Server 2012年发布之后发布的 SQL Server 2012年生成
状态
Microsoft 已经确认这是在"适用于"一节中列出的 Microsoft 产品中的问题。
替代方法
要解决情形 2 中的问题,请使用下列方法之一。
方法 1


修改语句,以避免使用"NOLOCK"提示的sys.sysdbreg表上的共享的锁。
IF EXISTS (SELECT * FROM sys.database_recovery_status with(NOLOCK) WHERE database_id= DataBaseID AND database_guid IS NOT NULL)
方法 2
设置死锁优先级的语句为"低"。
SET DEADLOCK_PRIORITY LOWIF EXISTS(SELECT * FROM sys.database_recovery_status where database_id = DataBaseID AND database_guid IS NOT NULL)
注意当您使用第二种方法来避免死锁在语句和数据库还原过程中时,将不会执行 IF 语句中的代码。
参考
有关排它锁、 共享的锁,并更新锁的详细信息,请访问以下 MSDN 网站:有关更多的增量服务模式的 SQL Server,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
935897 增量服务模式,可从 SQL Server 项目组提供报告的问题的修补程序
有关更新 SQL Server 的命名架构的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
822499 Microsoft SQL Server 软件更新程序包的命名架构
有关软件更新术语的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
824684 用于描述 Microsoft 软件更新的标准术语的说明

警告:本文已自动翻译

属性

文章 ID:2725950 - 上次审阅时间:11/20/2012 23:27:00 - 修订版本: 2.0

Microsoft SQL Server 2012 Developer, Microsoft SQL Server 2012 Enterprise, Microsoft SQL Server 2012 Express, Microsoft SQL Server 2012 Standard, Microsoft SQL Server 2012 Web

  • kbtshoot kbqfe kbfix kbsurveynew kbexpertiseadvanced kbmt KB2725950 KbMtzh
反馈