【发布时间】:2019-06-05 19:13:33
【问题描述】:
几个月来,我们一直受到一个问题的困扰,即为两个 Web 服务器提供服务的数据库的 CPU 飙升至 100% 并在我们允许的情况下停留数小时。所有 6 个处理器。这种情况每隔几天就会在一天中的不同时间发生。 CPU使用率是由于sqlserver.exe。
这不是一般的 SQL Server 性能问题(“如何使我的查询更高效”)。发生事故时,CPU 会从其典型的 20% 上升到 100%,并一直保持在那里,直到服务器重新启动。
我们正在使用 SQL Server 2016 SP2 累积更新 6。
我们添加了一些日志记录,发现在最近的 CPU 事件中,OPT_IDX_STATS 上的自旋锁数量猛增至每次碰撞 5775813 次自旋。不确定这是原因还是症状?
Before CPU 100% incident
name collisions spins spins_per_collision sleep_time backoffs
---- ---------- ----- ------------------- ---------- --------
OPT_IDX_STATS 787 200250 254.4473 0 5
LOCK_HASH 2137398 630970500 295.205 1410 52938
1 minute later
name collisions spins spins_per_collision sleep_time backoffs
---- ---------- ----- ------------------- ---------- --------
OPT_IDX_STATS 12 69309750 5775813 7 27
LOCK_HASH 17292 49187101 2844.5 47 555
当事件提示时,我们看到大约 40 个查询正在运行。它们通常是相同的两个 LINQ 查询的实例。没有一个查询的 elapsedMS 超过 20,000 毫秒,所以它不是一个长时间运行的查询会压垮 CPU。它们是昂贵的查询,但这似乎是问题的征兆,而不是原因 - 我们看到这些查询堆积如山,因为数据库运行速度如此之慢,因为 CPU 如此之高。那些相同的查询(以及其他查询)一直在执行,包括在数据库服务器重新启动之后,并且在重新启动后它们不会导致问题。
服务器有 36 GB 内存,我们认为使用率不会超过 22%。
其他一些有趣的信息,终止当前正在运行的查询会使 CPU 下降,但只是短暂的(随着 Web 服务器发送更多查询再次上升)。暂停数据库以让查询完成,只要它暂停,CPU 就会下降,但是当数据库恢复时它会迅速上升。重新启动数据库服务器总是解决了这个问题。在数据库重新启动之前和之后,网络服务器应该发送相同类型的查询,这表明 SQL Server 存在问题 - 否则为什么重新启动会解决问题?
更新:我编写了一个 PowerShell 脚本,如果 CPU > 95% 持续 45 秒,它会清除计划缓存,这似乎已经解决了这个问题。不过还是不知道是什么问题。
【问题讨论】:
-
TrustedInstaller。 Windows 更新总是试图做一些事情……至少对我来说很好。
-
您能否将 CPU 使用率与 sys.dm_exec_requests 中的 cpu_time 请求或 sys.dm_exec_sessions 中的会话关联起来?
-
@DavidBrowne-Microsoft 我添加了一些关于当前正在运行的查询的更多信息(倒数第二段)。
-
接下来要检查的是您的计划缓存等。如果您有随请求变化的硬编码 SQL 查询(未参数化),您的计划缓存可能受到严重污染。尝试打开“高级选项”下的“优化即席查询”选项。尝试清除所有缓存,看看这是否会影响性能(无需重新启动)。
-
好的。打开查询存储,查看特定查询的查询执行成本在问题发生和不发生之间是否存在差异。 是一个不同的查询计划导致问题,查询存储将允许您强制执行良好的计划。 docs.microsoft.com/en-us/sql/relational-databases/performance/…
标签: sql-server cpu-usage