SQL Server 的“服务器总内存”消耗停滞了数月,还有 64GB 以上的可用空间

Pic*_*llo 39 performance sql-server memory sql-server-2016 sp-blitz

我遇到了一个奇怪的问题,SQL Server 2016 标准版 64 位似乎将自己限制在分配给它的总内存的一半(128GB 中的 64GB)。

的输出@@VERSION是:

Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4 (X64) 2017 年 12 月 22 日 11:25:00 版权所有 (c) Windows Server 2012 R2 Datacenter 6.3 上的 Microsoft Corporation 标准版(64 位)(内部版本 9600:)(管理程序)

的输出sys.dm_os_process_memory是:

sys.dm_os_process_memory

当我查询时sys.dm_os_performance_counters,我看到Target Server Memory (KB)是在131072000Total Server Memory (KB)是 at 的一半以下65308016。在大多数情况下,我认为这是正常行为,因为 SQL Server 尚未确定它需要为自己分配更多内存。

然而,它已经“卡住”在 64GB 左右超过 2 个月了。在此期间,我们对一些数据库执行了大量内存密集型操作,并向实例添加了近 40 个数据库。我们总共有 292 个数据库,每个数据库都有 4GB 的预分配数据文件和 256MB 的自动增长速率和 2GB 的日志文件,具有 128MB 的自动增长速率。我每晚在中午 12:00 执行一次完整备份,并在周一至周五的上午 6:00 至晚上 8:00 开始以每 15 分钟为间隔进行事务日志备份。这些数据库的整体吞吐量相对较低,但我怀疑是否有问题,因为 SQL Server 还没有逐渐接近Target Server Memory 自然地通过新的数据库添加、正常的查询执行以及已运行的内存密集型 ETL 管道。

SQL Server 实例本身位于虚拟化 (VMware) Windows Server 2012R2 服务器上,该服务器具有 12 个 CPU、144GB 内存(128GB 到 SQL Server,16GB 为 Windows 保留)和 4 个虚拟磁盘,位于具有 15K SAS 驱动器的 vSAN 上. Windows 自然位于 64GB C: 磁盘上,页面文件为 32GB。数据文件位于 2TB D: 磁盘上,日志文件位于 2TB L: 磁盘之上,tempdb 位于 256GB T: 磁盘上,包含 8x16GB 文件且没有自动增长。

我已经验证除了MSSQLSERVER.

服务

该服务器完全专用于 SQL Server 实例,因此我们没有在其上运行可能消耗内存的其他应用程序或服务。

资源监视器

我使用 RedGate SQL Monitor 进行分析,下面是过去 18 天的Total Server Memory. 如您所见,除了 4 月初约 300MB 的单次上升外,内存利用率一直完全停滞不前。

RedGate SQL 监视器

这可能是什么原因?为了确定 SQL Server 不想使用分配给它的额外 64GB+ 内存的原因,我可以仔细查看哪些内容?

运行的输出sp_Blitz

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1;
Run Code Online (Sandbox Code Playgroud)

优先级 50:性能

  • CPU 调度程序脱机 - 由于关联屏蔽或许可问题,SQL Server 无法访问某些 CPU 内核。

  • 内存节点脱机 - 由于关联屏蔽或许可问题,某些内存可能不可用。

优先级 50:可靠性

  • 远程 DAC 已禁用 - 未启用对专用管理连接 (DAC) 的远程访问。当 SQL Server 没有响应时,DAC 可以使远程故障排除变得更加容易。

优先级 100:性能

  • 一个查询的多个计划 - 计划缓存中的单个查询有 300 个计划 - 这意味着我们可能存在参数化问题。

  • 启用服务器触发器

    • 服务器触发器 [RG_SQLLighthouse_DDLTrigger] 已启用。确保您了解触发器正在做什么 - 它所做的工作越少越好。

    • 服务器触发器 [SSMSRemoteBlock] 已启用。确保您了解触发器正在做什么 - 它所做的工作越少越好。

优先级 150:性能

  • 查询强制加入提示 - 自重新启动以来已记录了 1480 次加入提示实例。这意味着查询正在支配 SQL Server 优化器,如果他们不知道自己在做什么,这可能弊大于利。这也可以解释为什么 DBA 调优工作不起作用。

  • 查询强制订单提示 - 自重启以来已记录了 2153 次订单提示实例。这意味着查询正在支配 SQL Server 优化器,如果他们不知道自己在做什么,这可能弊大于利。这也可以解释为什么 DBA 调优工作不起作用。

优先级 170:文件配置

  • C盘系统数据库

    • master - master 数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在空间不足时导致服务器崩溃。

    • 模型 - 模型数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在空间不足时导致服务器崩溃。

    • msdb - msdb 数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在空间不足时导致服务器崩溃。

优先级 200:信息性

  • 代理作业同时启动 - 多个 SQL Server 代理作业配置为同时启动。有关详细的时间表列表,请参阅 URL 中的查询。

  • Master 数据库 master 中的表 - master 数据库中的 CommandLog 表由最终用户于 2017 年 7 月 30 日下午 5:22 创建。发生灾难时,可能无法恢复 master 数据库中的表。

  • 跟踪标志开启

    • 全局启用跟踪标志 1118。

    • 全局启用跟踪标志 1222。

    • 全局启用跟踪标志 2371。

优先级 200:非默认服务器配置

  • Agent XPs - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

  • 备份校验和默认值 - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

  • 备份压缩默认值 - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

  • 并行成本阈值 - 此 sp_configure 选项已更改。其默认值为 5,已设置为 48。

  • 最大并行度 - 此 sp_configure 选项已更改。其默认值为 0,已设置为 12。

  • 最大服务器内存 (MB) - 此 sp_configure 选项已更改。其默认值为 2147483647,已设置为 128000。

  • 优化临时工作负载 - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

  • 显示高级选项 - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

  • xp_cmdshell - 此 sp_configure 选项已更改。它的默认值为 0,并且已设置为 1。

优先级 200:可靠性

  • Master中的扩展存储过程

  • master - [sqbdata] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbdir] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbmemory] ​​扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbstatus] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbtest] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbtestcancel] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbteststatus] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqbility] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

    • master - [sqlbackup] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,现在需要将 master 数据库作为备份/恢复计划的一部分。

优先级 210:非默认数据库配置

  • Read Committed Snapshot Isolation Enabled - 此数据库设置不是默认设置。

    • 红门

    • 红门监视器

  • 启用快照隔离 - 此数据库设置不是默认设置。

    • 红门

    • 红门监视器

优先级 240:等待统计

  • 1 - SOS_SCHEDULER_YIELD - 1770.8 小时的等待,115.9 分钟平均每小时等待时间,100.0% 信号等待,1419212079 个等待任务,4.5 毫秒平均等待时间。

优先级 250:信息性

  • SQL Server 在 NT 服务帐户下运行 - 我作为 NT Service\MSSQLSERVER 运行。我希望我有一个 Active Directory 服务帐户。

优先级 250:服务器信息

  • 默认跟踪内容 - 默认跟踪保存 2018 年 4 月 14 日晚上 11:21 到 2018 年 4 月 16 日上午 11:13 之间 36 小时的数据。默认跟踪文件位于:C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log

  • 驱动器 C 空间 - C 驱动器上有 196816.00MB 可用空间

  • 驱动器 D 空间 - E 驱动器上有 894823.00MB 可用空间

  • 驱动器 L 空间 - F 驱动器上有 1361367.00MB 可用空间

  • 驱动器 T 空间 - G 驱动器上有 114441.00MB 可用空间

  • 硬件 - 逻辑处理器:12。物理内存:144GB。

  • 硬件 - NUMA 配置

    • 节点:0 状态:ONLINE 在线调度器:4 离线调度器:2 处理器组:0 内存节点:0 内存 VAS 保留 GB:186

    • 节点:1 状态:OFFLINE 在线调度器:0 离线调度器:6 处理器组:0 内存节点:0 内存 VAS 保留 GB:186

  • 启用即时文件初始化 - 服务帐户具有执行卷维护任务权限。

  • 电源计划 - 您的服务器有 2.60GHz CPU,并且处于平衡电源模式 - 呃...您希望您的 CPU 全速运行,对吗?

  • 服务器上次重启 - 2018 年 3 月 9 日上午 7:27

  • 服务器名称 - [已编辑]

  • 服务

    • 服务:SQL Server (MSSQLSERVER) 在服务帐户 NT Service\MSSQLSERVER 下运行。上次启动时间:2018 年 3 月 9 日上午 7:27。启动类型:自动,当前正在运行。

    • 服务:SQL Server 代理 (MSSQLSERVER) 在服务帐户 LocalSystem 下运行。上次启动时间:未显示。启动类型:自动,当前正在运行。

  • SQL Server 上次重启 - 2018 年 3 月 9 日上午 6:27

  • SQL Server 服务 - 版本:13.0.4466.4。补丁级别:SP1。累积更新:CU7。版本:标准版(64 位)。已启用的可用性组:0。可用性组管理器状态:2

  • 虚拟服务器 - 类型:(HYPERVISOR)

  • Windows 版本 - 您正在运行一个非常现代的 Windows 版本:Server 2012R2 时代,版本 6.3

优先级 254:运行日期

  • 船长的日志:确定某事某事...

Bre*_*zar 51

我敢打赌,您已经以某些 CPU 节点和/或内存节点处于离线状态的方式配置了虚拟 CPU。

下载sp_Blitz(免责声明:我是该免费开源脚本的作者之一)并运行它:

sp_Blitz @CheckServerInfo = 1;
Run Code Online (Sandbox Code Playgroud)

查找有关 CPU 和/或内存节点脱机的警告。SQL Server Standard Edition 只能看到前 4 个 CPU 插槽,并且您可能已将 VM 配置为类似于 6 个双核 CPU。它最终会遇到类似于企业版的 20 核限制如何限制您可以看到的内存量的问题

如果你想在这里分享 sp_Blitz 的输出,你可以像这样运行它以输出到 Markdown,然后你可以复制/粘贴到你的问题中:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1;

更新 2018/04/16 - 确认。您附加了 sp_Blitz 输出(感谢您!),它确实表明您的 CPU 和内存节点处于脱机状态。构建 VM 的人将其配置为 12 个单核 CPU,因此 SQL Server 标准版只能看到前 4 个插槽(核心)以及连接到它们的内存。

要修复它,请关闭 VM,将其配置为 2 插槽、6 核 VM,然后 SQL Server 标准版将看到所有内核和内存。这也将减少您的 SOS_SCHEDULER_YIELD 等待时间 - 现在,您的 SQL Server 正在冲击前 4 个核心,但仅此而已。在此修复之后,它将能够在所有 12 个内核上运行。

  • 不同的 [页面](https://www.youtube.com/watch?v=AnVeu1XLhwA),我想是同一个视频 (3认同)

Pic*_*llo 8

作为Brent Ozar 行动计划的附录,我想分享结果。正如 Brent 所指出的,在 VMware 中,我们错误地配置了具有 12 个单核 CPU 的虚拟机。这导致 SQL Server 无法访问剩余的 8 个内核,因此导致了我的原始问题中描述的内存问题。我们昨晚将我们的服务置于维护模式,以便适当地重新配置 VM。我们不仅看到内存以正常方式增长,而且正如 Brent 所暗示的那样,等待次数呈指数下降,我们的整体 SQL Server 性能猛增。vNUMA 配置现在是快乐的小组件,可以分割我们的工作负载。

对于可能正在使用 VMware vSphere 6.5 的用户,完成 Brent 描述的操作项的简要步骤如下。

  1. 登录到 VMware 群集的 vSphere Web Client,然后浏览到托管 SQL Server 的虚拟机。您的 VM 必须处于脱机状态才能调整 CPU 和内存配置。
  2. 在主窗格中,转到Configure > VM hardware,单击右上角的Edit按钮。您将打开一个上下文菜单,其中包含Edit Settings. 作为参考,下图是不正确的配置。请注意,我已Cores per Socket设置为1. 鉴于 SQL Server 标准版的限制,这是一个糟糕的配置。

    配置不正确

  3. 修复就像调整Cores per Socket值一样简单。在我们的例子中,我们将它设置为6这样我们就有2 Sockets. 这允许 SQL Server 使用所有 12 个处理器。

    正确配置

重要说明:不要将值设置为 theNumber of Cores或 theSockets将是奇数的地方。NUMA 喜欢平衡,根据经验,需要被 2 整除。例如,4 核 3 插槽的配置将是不平衡的。事实上,如果你sp_Blitz使用这种类型的配置运行,它会抛出一个警告。

在 VMware vSphere 上构建 Microsoft SQL Server(PDF 警告)中的第 3.3 节详细概述了这一点。白皮书中概述的做法适用于 SQL Server 的大多数本地虚拟化。

以下是我在布伦特的帖子后通过研究汇编的更多资源:

我将以过去 24 小时内从 RedGate SQL Monitor 的捕获结束。主要的注意点是 CPU 利用率和等待次数 - 在昨天的高峰时段,我们遇到了大量 CPU 使用和等待争用。在这个简单的修复之后,我们的性能提高了十倍。甚至我们的磁盘 I/O 也显着减少。这是一个看似容易被忽视的设置,可以将虚拟性能提高一个数量级。至少,它是由我们的工程师和一个完整的忽视D'哦时刻。

红门性能