在几天的时间里,我们的数据库服务器上的被盗内存增长缓慢。它似乎稳定在 130-140GB 左右,此时我们开始遇到更大的问题,例如内存不足错误、多秒冻结和 AG 故障转移。重新启动后大约一周开始出现问题。我已经开始记录被盗内存的历史,如下图:
查看sys.dm_os_memory_clerks
,似乎其中大部分来自记录在 NUMA 节点 0 上的缓冲池中的非页面内存:
pages_kb
随着时间的推移跟踪缓冲池的总数显示页面数量随着virtual_memory_committed_kb
增长而下降。(4 月 13 日,服务器因 windows 更新而重新启动。缓冲池在大约一个小时内填充到 400GB)
有没有人见过这种行为?
我们正在运行 SQLServer 2016 CU12 13.0.5698.0 服务器是一个 64 核的 AWS EC2 i3.16xlarge 实例。我们有许多其他相同大小的集群都显示了这个问题。我们在 32 核 i3.8xlarge 实例上也有一些集群,这些集群也显示了被盗内存的增长,但它们最终不会停止/抛出内存不足错误。唯一的区别(除了规模)是 64 核服务器有 2 个 NUMA 节点。
更新: MS 表示 KB4536005 中的错误修复没有被反向移植到 SQL2016。
我有一个怀疑。首先 - 您可以向 Microsoft 开具支持票吗?
检查我的怀疑的最简单方法是捕获两个 NUMA 节点的 [\SQLServer:Memory Node(*)\Stolen Node Memory (KB)],并将总和与 [\SQLServer:Memory Manager\Stolen Server Memory (KB)] 进行比较。如果我的怀疑是正确的,那么当麻烦正在酝酿时,两者之间的差异——似乎他们应该总是同意——将会非常高。另一个明显的特征:最多 N-1 个 SQLOS NUMA 节点可能具有这种关系(其中 N 是 NUMA 节点的计数)[数据库节点内存] + [被盗节点内存] + [空闲节点内存] > [总节点内存]
我在这些博客文章中描述了这个问题。
https://sql-sasquatch.blogspot.com/2018/07/sql-server-2016-memory-accounting.html
https://sql-sasquatch.blogspot.com/2018/10/sql-server-2016-memory -accounting-part.html
基本核算问题是,有时缓冲池增长的方式是缓冲描述符块从 SQLOS 节点 A 分配,但 bdbs 中引用的页面实际上来自 SQLOS 节点 B。这种情况的结果是一部分物理内存由 SQLOS 控制的内存被重复计算:相同的内存在节点 A(bdb 所在的位置)上计为 [Database Node Memory]并且在 SQLOS 节点 B 上计为 [Stolen Node Memory]。这种情况令人困惑且效率低下……但这还不是问题的全面发展。
当如此多的节点 B [被盗节点内存] 也是节点 A [数据库节点内存] 以至于节点 B [数据库节点内存] 下降到节点 B [目标节点内存] 的 ~2% 时,问题就完全爆发了。当这种情况发生时,[\SQLServer:Buffer Manager\Free liststalls/sec] 的速率会飙升——当这种情况发生在我们身上时,我们看到了 2000/秒。SQL Server 正在尝试通过修剪节点 B 上的各种类型的缓存来纠正节点 B 上的问题([数据库节点内存] 太少)。但它不能!因为 [被盗节点内存] 不在任何预期的缓存类型中。
临时解决:当[total node memory]接近[target node memory]但[database node memory]接近[target node memory]的2%时,执行DBCC DROPCLEANBUFFERS。
kb4536005 解决了 SQL Server 2017 CU20 和 SQL Server 2019 CU2 中的此问题。 https://support.microsoft.com/en-us/help/4536005/improvement-fix-incorrect-memory-page-accounting-that-causes-out-of-me
SQL Server 2016 SP2 CU5,kb4470916 中有类似的声音修复。 https://support.microsoft.com/en-ca/help/4470916/fix-out-of-memory-error-occurs-when-database-node-memory-kb-drops-belo
但是,我不相信 kb4470916 解决了双重会计问题。因此,虽然它可以改善 SQL Server 对 [数据库节点内存] 处于 ~2% 阈值的单个 SQLOS 节点的响应,但我认为由于这种重复计算,它留下了戳熊的可能性。这可能就是你所处的情况。
但是,如果两个节点的 [stolen node memory] 总和始终与实例中的 [stolen server memory] 一致,那么您可以忘记这一切,就好像这是一场噩梦。:-)