TempDB争用


14

我们在SQL Server 2014 SP1上有一个活动的OLTP 40GB数据库。发现查询随着IO_Completion等待而变慢,磁盘队列长度增加到900,并且SQL Server停止响应。我们尝试了什么:

  1. 重新启动实例,并在一分钟后开始以相同的方式运行。

  2. 第二次重新启动后,我们更改了每个tempdb数据文件的初始大小(创建了16个数据文件),它开始正常工作。

注意:我们将表变量用于中间结果集。这些结果集很小。

一个月内发生了两次。每次我手动向数据文件添加一点空间时,它就会开始正常工作。更有趣的是,我们在SQL Server 2008 R2和SQL Server 2012上使用的相同设置(相同的硬件,相同的文件夹和文件设置,相同的工作负载)可以正常工作。

请帮助我们找到永久的解决方案。

所有数据文件的初始大小都相同,为1000MB,当前为1500MB。都是一样的。每个自动增长为100MB。在此之前,我们面临着PFS和GAM页面争用的问题,我们增加到16个,问题得以解决。跟踪标记1117和1118均被启用。2个NUMA节点上的24个内核。所有数据文件都在同一卷上。简单磁盘,无SAN。

实例在物理计算机上。带表变量的查询和带哈希联接的查询是最常见的生成IO_Completion等待的方法。


wBob的详细回答促使我们进行了更详细的搜索。我们以前是怎么错过它的:

用户取消了数据库“ tempdb”中文件“ templog”的自动增长,或者在7704毫秒后超时。使用ALTER DATABASE可以为此文件设置较小的FILEGROWTH值,或显式设置新的文件大小。

每当发生这种类型的问题时,我们都会在日志中找到此问题。我们正在将TempDB移至单独的快速驱动器。

Answers:


6

我认为您的tempdb碎片过多,并且服务器CPU和磁盘设置之间不匹配,但是让我们收集一些更多信息:

问题/需要更多信息

  • 请确认处理器名称和类型(我基本上是在尝试确定它是否为HT的2 x十六进制内核)。使用系统信息(例如,控制面板>系统和安全性> Windows Server 2012 R2上的系统)和/或sysinternals工具CoreInfo进行确认。
  • 请确认服务器maxdop(例如EXEC sp_configure 'max degree of parallelism')。如果CPU是十六进制核心,则服务器maxdop最多应为6(按照此处),或者在OLTP系统上可以说更低。我通常将tempdb文件与服务器DOP保持一致,最多不超过8个,但我们将继续讨论。
  • 请在包装盒上确认服务器总内存和SQL Server内存上限(例如EXEC sp_configure 'max server memory (MB)')。
  • 请确认包装盒上是否正在运行其他任何服务(例如SSIS,SSAS,SSRS,应用程序,iTunes等)
  • 请确认已为SQL Server服务帐户启用即时文件初始化。(可以在这里进行测试)。
  • 为什么CPU(2个节点的NUMA设置)与一个磁盘(家用PC)之间存在如此巨大的差异?考虑为tempdb添加磁盘,条带化,SSD(尽管要避免反应过度:)
  • 请为其中一个问题查询添加实际的执行计划。如果需要,可以使用SQL Sentry Plan Explorer进行匿名处理。
  • 哈希与OLTP系统中的表变量联接?这表明缺少表变量,主表或两者的索引。您是否在声明这样的表变量(没有索引)?

    DECLARE @t TABLE ( x INT )
  • 即使表变量定义包含小的结果集,也不要忽略它。始终最好为优化器提供尽可能多的信息,以便无论索引是否是集群的/非集群的,都应具有可空性,唯一性,以使其明确。

    DECLARE @t TABLE ( x INT PRIMARY KEY )
    DECLARE @u TABLE ( x INT PRIMARY KEY NONCLUSTERED, u INT NOT NULL UNIQUE CLUSTERED, z INT NOT NULL UNIQUE, a CHAR(1) NULL ) -- not sure why you would do this but you can
    DECLARE @v TABLE ( x INT NOT NULL, y INT NOT NULL, PRIMARY KEY ( x, y ) )   -- multi-column primary key
  • 发布执行计划将有助于对此进行诊断。

  • 请按此处此处)检查防止表变量缓存的代码。我认为用RECOMPILE执行的动态SQL和proc是唯一影响表变量的变量。

    DECLARE @u TABLE ( x INT )
    
    INSERT @u
    EXEC('DECLARE @t TABLE ( x INT ); INSERT INTO @t VALUES ( 1 ); SELECT x FROM @t;' )
    
    SELECT *
    FROM @u
  • 检查SQL Server日志(“对象资源管理器”>“管理”>“ SQL Server日志”)以获取消息,例如IO警告。

  • 检查Windows事件查看器
  • 自SP1以来,已经发布了许多版本。查看自SP1以来放入CU修复程序。可能在后续的CU中修复了SP1中的错误,例如FIX:当估计的行数和行大小正确时,排序运算符溢出到SQL Server 2012或SQL Server 2014中的tempdb https://support.microsoft.com/zh-我们/ kb / 3088480
  • 在应用任何修补程序之前,请确定这是您的原因,尽管由于新功能(内存中的OLTP,群集列存储)的数量,保持最新与SQL Server 2014的CU更为重要。
  • 最后,每个内核只需要一个tempdb文件是一个神话,在查看磁盘设置时,我猜想tempdb过于分散。我有点you不休,觉得您只有一个磁盘头,tempdb有一个文件组,很多文件。

但是忘记我们认为我们知道的东西;创建一个可以重现您的问题的测试设备,并尝试减少临时文件的数量...从1、2、4、6等开始收集信息,以做出基于证据的决策。现在,这比较困难,因为您的问题似乎是断断续续的,您可能无法弄乱tempdb的设置,但这就是我要解决的方法。

祝好运。让我们知道您的身体情况如何。


2
非常感谢,您的详细回答促使我们进行了更详细的搜索。在用户取消数据库'tempdb'中文件'templog'的自动增长或在7704毫秒后超时之前,我们怎么错过它。请使用ALTER DATABASE为此文件设置较小的FILEGROWTH值或明确设置新的文件大小。 ” 每当发生这种类型的问题时,我们都会在日志中找到此问题。我们正在将TempDB移至单独的快速驱动器。
aasim.abdullah

2
最近我们发现,TempDB仍然面临压力,而且它的发生是因为我们正在使用“包含表”并且SQL Server在每次执行时都创建了一个Hash Join。基本上是SQL Server 2014中的错误。已通过使用最新的CU修复,此问题已解决。support.microsoft.com/en-us/kb/2999809
aasim.abdullah
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.