J.D*_*.D. 4 sql-server memory wait-types sql-server-2016 waits
我的服务器正在运行 SQL Server 2016。该环境的工作负载相当高,全天有大量写入事务和读取数据。我有一种预感,服务器没有配备足够的内存,我想深入了解是否是这样。确定服务器上的可用内存量是否以及产生了多少争用的最佳方法是什么?
我确实查看了 DMV sys.dm_os_wait_stats,当按 waiting_tasks_count desc 排序时,前两个等待类型是“MEMORY_ALLOCATION_EXT”和“RESERVED_MEMORY_ALLOCATION_EXT”,其数量级比任何其他等待类型任务计数都大。还有其他地方可以检查内存压力或争用吗?
编辑:此服务器上所有数据库的总大小为 3 TB,事务最多的主数据库为 2 TB,服务器上的 RAM 总量为 32 GB。
这里有几个 perfmon 计数器,您可以将其用作入门。
Memory Grants Pending - 这是一个计数器,告诉您是否有任何查询在等待内存授予(内存分配)。这实际上应该是 0。如果它一直超过这个值,你就有问题了。
页面预期寿命 - 这是页面在内存中停留的估计时间(以秒为单位)。越高越好,但是有一个公式可以计算您的serer的最小值实际上应该是多少。过去最少需要 300 秒,但这是一个旧计算,现在应该是每 GB 100 秒。我在 SQL 周六会议期间从 Richard Douglas 那里得到了这个,所以归功于他。他为 SentryOne 工作。小于该值表示分配的内存太少。还可以将此计数器与 Checkpoint pages/sec 结合使用。请注意,每个 NUMA 节点都有自己的 PLE 值(如果 SQL Server 上有多个 NUMA 节点)。SQL Server 开始将资源分配到分配的 8 个核心以上的(软)NUMA 节点。
延迟写入/秒 - 当 SQL Server 遇到内存压力时,延迟写入进程会从缓存中清除旧页面。值始终高于 20 是一个问题(也是从 Richard Douglas 那里得到的)。但是,请将其与 Page Life Expectancy 结合使用。如果您看到高 PLE 以及延迟写入/秒的峰值,则说明某些原因导致 SQL 从其缓存中删除页面并插入新页面。有关我的家庭实验室的示例,请参见下面的屏幕截图。
我敢肯定,这里的一些专家对内存管理员了解得更多一些,仍然在我的列表中可以深入研究,所以也许有人为您提供了一些额外的信息(我也对这些信息非常感兴趣:-))。
编辑:如果您愿意,您还可以使用 sys.dm_os_performance_counters 通过查询即时获取它们。
2020 年 6 月 24 日编辑:
@JD 关于您 6 月 23 日的评论;由于@Dominique Boucher 和这篇文章的评论,我也更深入地研究了内存压力:https ://www.brentozar.com/archive/2020/06/page-life-expectancy-doesnt-mean-杰克和你应该停止看它/. 当我在邮箱里收到这个时,我笑了;也许他看到了这个帖子。:-) 这篇文章告诉我们不要再看它了。好吧,虽然布伦特肯定比我更有经验,但我认为我不能完全同意他永远不看它的说法。我在他的 sp_BlitzFirst 上下文中理解了他的观点,单个查询使用最多 25% 的缓冲区缓存,它是一个滞后指标等。但是对于趋势分析和历史记录,我仍然会查看 PLE 与 Lazy Writer。如果我想确定服务器随着时间的推移是否有内存压力,这就是我将与等待内存授予结合使用的方法。此外,来自 RedGate 和 Quest 的监控工具仍然使用它。现在@Dominique Boucher 说要查看 RESOURCE_SEMAPHORE 等待,我同意这一点,但这很可能与待处理的内存授予数量一致(您可以轻松地向 perfmon 注册)。如果您有一个恒定的内存授权队列(它适用于 FIFO 队列),那么您确实有内存压力。
作为参考,这是这个 Universe 中某个系统的 Lazy Writer(32 GB 内存,1 TB 数据库,尽管工作负载类型也很重要)。黄色是批量请求p/s,10表示1000,所以可以看出绝对不是空闲的。
这也是我的家庭实验室关于内存授予与 RESOUCE_SEMPAPHORE 等待的快照(我还看到我突出显示了 tempdb 写入,这就是 david 所说的,内存太少,所以溢出到 tempdb):
现在,看看你的 perfmon 计数器,我认为你肯定有内存问题。我的意思是; 有些东西不断地迫使 SQL Server 从缓冲区缓存中删除页面。如果这只是一次,好吧,但它似乎一直忙于这样做……但是,我希望将它们与 PLE 进行比较。这可以清楚地表明存在内存压力(随着时间的推移,我仍然这么认为)。其次,您还想查看待处理的内存授予。现在,我之前没有说过,但回过头来看,我确实认为您想查看 Brent 和 Dominque 所说的等待统计数据。但是,随着时间的推移,这有点困难。等待统计数据是累积收集的,因此您需要先清除它们(我不喜欢),然后在 RESOURCE_SEMAPHORE 相加时查看它们。
清除等待统计信息:https : //docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-sqlperf-transact-sql? view = sql-server- ver15
您也可以使用 sp_BlitzFirst 来监视它,但这只是您运行它时的快照。sp_BlitzFirst(或我不记得的 sp_Blitz)有一个选项可以定期将其记录在表中,因此您也可以查看它。或者只是以其他方式查询 dm_os_wait_stats 也可以。一般来说,我个人的偏好是随着时间的推移收集数据来分析这一点。我使用 Steve Stedman 的 Database Health Monitor 执行此操作:databasehealth.com。我的家庭实验室截图:
通过这种方式,您可以更好地监控等待统计数据,尽管它会花费您一点资源。
如果你有 SQL Server 2017 或更高版本(我们的环境中还没有),那么你也可以使用查询存储。自 SQL Server 2017 查询存储还记录等待统计信息(这是一个可配置的选项)。不过要小心,我读过有关 Query Store 使非常繁忙的服务器瘫痪的故事(您可以使用等待统计信息 :-P 监控)。当然,在 prod 中实现功能之前,您应该始终进行测试。我们确实使用了它,并且效果很好,但是我们有 2016 年,所以我们确实错过了等待统计选项:-(。
顺便一提; 我的策略是收集信息(性能,如果可能,等待统计数据),如果您认为存在内存压力,请升级 RAM(如果 VM 很容易),然后收集性能指标并检查它们是否有所改善。一点也不费脑子,但后者经常被遗忘或做得不好。