我们在 Windows Server 2022(具有 32GB RAM 的虚拟机)上运行 MS SQL Server 2022(标准版 16.0.4095.4)的实例,并遇到 sqlservr.exe 进程消耗的“修改内存”问题。
SQL Server内存配置如下:
总体内存消耗如下所示:
当我查看什么消耗了修改后的内存时,我可以看到它是 SQL Server:
内存的“修改”部分不断增长,并且似乎永远不会下降(它已经连续几天保持在较高水平)。SQL Server 性能统计信息目前并未表明存在任何性能问题。
此外,DBCC MEMORYSTATUS 的输出没有给我任何关于这个“修改的内存”部分可能是什么的线索。据我了解输出(见下文),DBCC MEMORYSTATUS 报告的内存消耗符合“最大服务器内存”中设置的限制。
您是否知道什么可能导致内存消耗远高于“最大服务器内存”中设置的值,或者我如何进一步调查?
我们拥有的任何其他实例上都不会出现此问题 - “修改的内存”只是内存消耗的一小部分。此实例与其他实例之间的唯一区别在于,此框中有几个基本可用性组设置。那里不允许任何其他“可疑功能”(没有列存储索引,没有内存中 OLPT ...)。
我只是出于好奇而尝试减少“最大服务器内存”值。唯一的影响是,由此释放的“正在使用的内存”在一段时间内缓慢但肯定地切换到了“修改的内存”。我正在考虑增加虚拟机内存,但我担心这可能会导致更大的“修改内存”消耗......
修改的内存实质上是已经被修改的内存,必须先写入磁盘才能重新使用。SQL Server 有一个缓冲池(以及各种其他内部和外部内存项),其工作是按字面意思读取和写入数据。为此,SQL Server 将数据缓存在内存中。SQL Server 将修改大量内存。您可以随意使用 etw 跟踪来查找内存更改,转储这些页面并查看修改的内容,但这毫无意义。让我给你答案,有人运行了一个查询,它需要数据或对数据进行了更改,内存被修改了。对于已配置的服务器(以及正在运行的其他所有内容)来说,最大服务器内存设置得太高,现在您会看到修改后的内存计数器。
现在您已经有了答案,这有什么帮助?正如我所说,它不会。
你有一个 XY 问题。你专注于错误的事情并且不会放手。是时候放手了,看看森林,停止违背你所寻求帮助的人告诉你的事情。
除了我给出的链接之外,这里还有许多资源解释最大服务器内存:
从您自己的屏幕截图来看,最大服务器内存是按照配置的。
正如我所说,假设 SQL 将仅使用20 GB ,这是不正确的。图像、线程堆栈、堆分配和一大堆其他内容不属于最大服务器内存范围,就像我之前给您的链接中所述。你备份吗?很酷,外面也一样。我看到 SQL 代理正在运行,您考虑到了吗?SSMS 也在运行,那怎么样?我看到很多第 3 方项目,所有内存也都被占用了吗?线程堆栈、图像、第 3 方 dll 及其堆分配等都包含在这分配的神奇 32 GB 内存中?
将最大服务器内存设置得较低,删除任何第一方或第三方 dll(链接服务器等),并且不要在服务器上运行大量其他内容。
请让修改内存的事情过去吧,正如我之前所说,它在这种情况下毫无用处。
尽管对此感到沮丧,并且由于我不认为 sqlsvr.exe 锁定的不断增加的“修改内存”量是标准且健康的行为,我继续调查并最终找到了我们环境中问题的根本原因。
简单回顾一下一开始的环境和问题:
当我们不是从其所属进程的角度而是从文件的角度查看“修改的内存”时,我们发现增加的分配似乎保存在 WFCS 事件日志文件中,如下所示:
尽管 ClusterLogLevel 设置为 3,但仍以高节奏生成大量“详细级别”事件。
曾有过这样的事件:
经过多次尝试,我们无法强制不记录详细级别的事件。
最后,我们决定禁用 Windows 事件日志中的整个 FailoverClustering 日志。从那时起,内存消耗就以“正常方式”运行,消耗的“修改内存”量可以忽略不计,正如我们在其他服务器中所习惯的那样。
问题似乎出在 WFCS 和服务器上的 AG 数量中,因为原则上 AG 的数量是该环境(2 个服务器)与我们运营的所有其他环境不同的唯一方面。