KB2926217 - 修复:当数据库锁定活动在 SQL Server 中增加时,会出现性能问题

应用对象
SQL Server 2012 Enterprise SQL Server 2012 Developer SQL Server 2012 Standard SQL Server 2012 Express SQL Server 2012 Web SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use) SQL Server 2008 Service Pack 3 SQL Server 2008 Developer SQL Server 2008 Enterprise SQL Server 2008 Standard SQL Server 2008 R2 Service Pack 2 SQL Server 2008 R2 Developer SQL Server 2008 R2 Enterprise SQL Server 2008 R2 Standard

默认情况下,SQL Server 2014 Service Pack 1 和 SQL Server 2012 Service Pack 3 包含此修补程序,您无需添加任何跟踪标志即可启用该修补程序。 若要在安装“解决方案”部分中的某个累积更新后启用修补程序,必须通过将跟踪标志 1236 添加到启动参数来启动 Microsoft SQL Server。

症状

假设在包含许多处理器的计算机上运行 Microsoft SQL Server 2014、SQL Server 2012、SQL Server 2008 或 SQL Server 2008 R2 的实例。 当特定数据库的锁 (资源类型 = DATABASE) 超过某个阈值时,会遇到以下性能问题:

  • LOCK_HASH旋转锁计数出现升高的值。

    注意:有关如何监视此旋转锁的信息,请参阅“详细信息”部分。

  • 需要数据库锁定的查询或操作需要很长时间才能完成。 例如,你可能会注意到以下性能延迟:

    • SQL Server 登录名
    • 链接服务器查询
    • sp_reset_connection
    • Transactions

注意 要查找给定数据库上资源类型 = DATABASE) (锁的列表,请参阅“更多信息”部分。 阈值因环境而异。

解决方法

累积更新信息

此问题已首先在 SQL Server 的以下累积更新中修复。

SQL Server 2008 R2 SP2 的累积更新 13 /en-us/help/2967540

SQL Server 2008 SP3 的累积更新 17 /en-us/help/2958696

SQL Server 2014 累积更新 1 /en-us/help/2931693

SQL Server 2012 SP1 的累积更新 9 /en-us/help/2931078

关于 SQL Server 的累积更新

SQL Server 的每个新累积更新都包含上一个累积更新中包含的所有修补程序和所有安全修补程序。 查看 SQL Server 的最新累积更新:

      

修补程序信息
 Microsoft 提供了一个受支持的修补程序。 但此程序只用于解决本文中提到的问题。 仅将此修补程序应用于遇到此特定问题的系统。

如果修补程序可供下载,则本知识库文章顶部的“修补程序下载可用”部分。 如果此部分不存在,请向 Microsoft 客户服务和支持部门提交请求以获取该修补程序。

注意 如果发生其他问题或需要进行任何故障排除,您应该另行创建服务请求。 通常的支持费用将应用于不符合此特定修补程序条件的其他支持问题。 若要获取 Microsoft 客户服务和支持部门的完整电话号码列表或另行创建服务请求,请访问以下 Microsoft 网站:

/contactus/?ws=support 注意 “修补程序下载可用”窗体显示了修补程序的可用语言版本。 如果您找不到需要的语言,则说明该语言版本的修补程序未提供。

状态

Microsoft 已确认在 "适用于" 部分中所列的 Microsoft 产品中存在问题。

详细信息

当应用程序连接到 SQL Server 时,它首先会建立数据库上下文。 默认情况下,连接将尝试获取 SH 模式下的 DATABASE 锁。 当连接在连接生存期内停止连接或更改数据库上下文时,将释放 SH-DATABASE 锁。 如果有许多使用相同数据库上下文的活动连接,则可以为该特定数据库拥有许多 DATABASE 资源类型的锁。

在具有 16 个或更多 CPU 的计算机上,只有表对象使用分区锁定方案。 但是,数据库锁未分区。 因此,数据库锁的数量越多,SQL Server 获取数据库锁所需的时间就越长。 大多数应用程序不会遇到由此设计引起的任何问题。 但是一旦数量超过某个阈值,就需要额外的工作和时间来获得锁。 尽管每个额外锁的成本仅为微秒,但总时间会迅速增加,因为锁哈希桶受旋转锁保护。 这将导致额外的 CPU 周期并等待其他辅助角色获取锁定。

此修补程序在启动时启用跟踪标志 T1236 时引入了数据库锁分区。 对 DATABASE 锁进行分区可使锁列表的深度在每个本地分区中保持可管理。 这显著优化了用于获取 DATABASE 锁的访问路径。

若要监视 LOCK_HASH 旋转锁,可以使用以下查询。SET NOCOUNT ON
CREATE TABLE #spinlock_stats ([CaptureTime] datetime,[name] nvarchar (512) ,[collisions] bigint,
[spins] bigint,[spins_per_collision] real,[sleep_time] bigint,[backoffs] int)
DECLARE @counter int = 1
而 100 @counter<
      BEGIN
            INSERT INTO #spinlock_stats SELECT GETDATE () as “CaptureTime” , * FROM sys.dm_os_spinlock_stats WHERE [name] = 'LOCK_HASH'
            WAITFOR DELAY '00:00:05'
            SET @counter +=1
      End
SELECT * FROM #spinlock_stats ORDER BY [CaptureTime]
DROP TABLE #spinlock_stats 有关诊断和解决 SQL Server上的旋转锁争用的更多信息,请转到以下文档:

诊断和解决 SQL Server 上的旋转锁争用 注意 尽管本文档是针对 SQL Server 2008 R2 编写的,但该信息仍然适用于 SQL Server 2012。

参考资料

有关 SQL Server 2012 中跟踪标志的更多信息,请转到以下 TechNet 网站:

有关 SQL Server 2012 中跟踪标志的信息
有关如何查找每个数据库的用户中的数据库锁数量的详细信息,请使用以下查询来计算此值:select Resource_database_id, resource_type, request_mode, request_status,
count (*) 'LockCount' from sys.dm_tran_locks
按Resource_database_id、resource_type、request_mode request_status分组