SQL Server 2012 SP3的内存不足问题


8

我一直有周期性的SQL Server OOM错误,一次是SQL Server关闭自身,并总是在夜间发生,这时没人使用它,并且那时没有SQL Agent作业运行:

这是典型的错误:

08/17/2017 19:31:17,spid100,未知,资源池``内部''中没有足够的系统内存来运行此查询。

2017年8月17日19:31:17,spid100,未知,错误:701严重性:17状态:123。

2017年8月17日19:31:17,spid112,未知,错误:18056严重性:20状态:29.(Params :)。由于格式化期间出错,因此以简洁模式打印错误。跟踪ETW通知等已跳过。

这是服务器信息:

  • 最小10 GB的SQL Server内存
  • 最大21GB SQL Server内存
  • 服务器上只有4个DB
  • 它们的大小每个只有1到2 GB
  • Tempdb的大小从未增长到超过1GB(设置为自动增长到10GB)
  • 索引均为低碎片指数,统计信息已更新
  • 版:

    Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64) 
        Oct 20 2015 15:36:27 
        Copyright (c) Microsoft Corporation
        Standard Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
    

我检查了多个项目:

  • DBCC内存状态
  • 快速统计:

    SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
    FROM sys.dm_os_process_memory;
    GO
    
    Output:
    20 GB
    Page Life Expectancy                     155932
    
  • 没有启用资源调控器:

    select pool_id, cache_memory_kb, used_memory_kb,
           out_of_memory_count,used_memgrant_kb
      from sys.dm_resource_governor_resource_pools
    
    Output:
    
    pool_id | cache_memory_kb | used_memory_kb | out_of_memory_count | used_memgrant_kb
    --------+-----------------+----------------+---------------------+-----------------
          1 |          295368 |         641416 |                   0 |                0
    
    
    select (physical_memory_in_use_kb/1024) Memory_usedby_Sqlserver_MB,
           (locked_page_allocations_kb/1024) Locked_pages_used_Sqlserver_MB,
           (total_virtual_address_space_kb/1024 )Total_VAS_in_MB,
           process_physical_memory_low,
           process_virtual_memory_low
      from sys. dm_os_process_memory
    
    Output:
    
    Memory_usedby_Sqlserver_MB | Locked_pages_used_Sqlserver_MB | Total_VAS_in_MB | process_physical_memory_low | process_virtual_memory_low
    ----------------------------------------------------------------------------------------------------------------------------------------
                         20553 |                          20393 |       134217727 |                           0 |                          0
    

服务器位于SP3上,我知道SP1中存在内存泄漏问题,因此请排除它。

有人注意到我应该关注的DBCC结果中的任何内容吗?


1
此服务器上还托管其他任何服务/应用程序吗?SQL Server服务帐户是否属于“内存本地安全策略”中“锁定页面”的一部分?Windows事件日志在您遇到SQL Server崩溃时是否还指示其他任何问题?
约翰·埃斯布雷纳

-该服务器上没有托管其他应用程序,而是专用的SQL服务器。-SQL Server服务帐户是Windows管理员组的一部分。-我只看到一堆VSS错误:卷影复制服务错误:查询IVssWriterCallback接口的意外错误。hr = 0x80070005,访问被拒绝。。这通常是由编写者或请求者过程中不正确的安全设置引起的。操作:收集Writer数据上下文:Writer类ID:{35e81631-13e1-48db-97fc-d5bc721bb18a} Writer名称:NPS VSS Writer Instance ID:{...}
user132852 '17

1
服务器是VM吗?如果是这样,它是否具有“专用”内存资源,或者是否与其他VM共享?而且,如果它共享内存,是否过度分配了内存资源?我已经看到这种情况(无论版本如何)在内存被过度分配的VM服务器上发生。
SQL_Hacker

3
谢谢Shanky。为了进行更新,上周五我在将其添加到监视中后发现了该问题,它似乎未正确配置应用程序(第三方)中的一个应用程序监视会话,直到OOM数小时后,连接会话才关闭杀死它。
user132852

1
@ user132852,您可以将解决方案放入答案中并将其标记为已回答。
Thomas Kronawitter '18

Answers:


2

由于SQL Server在VM中运行(如(hypervisor)版本语句中的指示所示),因此您应确保SQL Server 在主机服务器上的VMWare(或Hyper-V等)中具有内存保留。

内存预留通常应为生产环境中使用的SQL Server虚拟机分配给VM的内存的100%。如果没有内存预留,则主机服务器可能会通过使用“气球驱动程序”从虚拟机“窃取”内存以供其他VM使用,这很可能是导致内存不足的原因。

在VMWare vCenter中,要在虚拟机上设置内存预留,请执行以下操作:

  1. 在配置内存设置之前,请关闭虚拟机电源。

  2. 在vSphere Client中,右键单击清单中的虚拟机,然后选择“编辑设置”。

  3. 在“虚拟机属性”窗口中,选择“资源”选项卡,然后选择“内存”。

  4. 在“资源分配”面板中,选中“保留所有来宾内存(所有已锁定)”复选框。

  5. 单击确定。

如果您使用的是Microsoft Hyper-V,请在Hyper-V Manager中使用以下过程为VM禁用动态内存:

  1. 确保虚拟机已关闭。
  2. 右键单击虚拟机,选择“设置”
  3. 从左侧窗格中选择“内存”。
  4. 确保选中“启用动态内存” 。
  5. 启动虚拟机。

1

我将进行几个配置更改:

  1. 删除最低内存设置,实际上不需要这样做
    • 您要更改此设置的原因是,如果设置了此设置,SQL Server将永远不会释放标记下方的内存。如果页面被锁定在内存中,则无法再对页面进行分页。
  2. 对于总<32gb,将最大服务器内存调整为总服务器内存的75%,对于总> 32gb,将其最大服务器内存调整为87.5%。
    • 假设SQL Server是计算机上唯一运行的计算机,则在授予OS足够的内存以使其正常运行之后,让它消耗剩余的内存。

您可以使用以下脚本来完成此操作:

use master;
go

-- MIN Server Memory
exec sys.sp_configure
    'min server memory (MB)'
    ,0;

-- MAX Server Memory
declare
  @systemMemory int
  ,@maxServerMemory int;

select
  @systemMemory = total_physical_memory_kb / 1024
from
  sys.dm_os_sys_memory;

set @maxServerMemory = floor(@systemMemory * .75);

if @systemMemory >= 32768
  begin
    set @maxServerMemory = floor(@systemMemory * .875);
  end;

exec sys.sp_configure
  'max server memory (MB)'
  ,@maxServerMemory;

reconfigure;
go

3
我知道这些是相当标准的最佳做法,但是您能否解释一下如何更改它们将如何解决所遇到的错误?
Erik Darling
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.