缓冲池外的SQL Server 2012内存消耗


10

我有一个SQL Server 2012 SP2 Enterprise Edition实例,比最大内存消耗约20GB的内存。内存限制。该实例限制为65GB,但以下查询显示的正在使用的物理内存为86GB

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

该服务器是物理服务器,具有2个NUMA节点。有没有一种方法可以找出正在消耗缓冲池之外的内存的原因(我假设这是正在发生的事情)?

这是DBCC MEMORYSTATUS的输出:

DBCC MEMORYSTATUS的输出

这是设置的内存限制:

内存限制的屏幕截图

提前致谢。

更新:-我已经运行了亚伦建议的查询

SELECT TOP (20) * FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC

这是输出:-

MemoryClerkOutput

pages_kb的总和约为60GB

更新2:-DBCC MEMORYSTATUS的完整输出在这里:-http: //pastebin.com/nGn6kXEc

更新3: - Shanky在这里的Excel文件的脚本输出: - http://jmp.sh/LKRlH4K

更新4:-输出的屏幕截图:-

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

PhysMemInUse屏幕截图

因此,这似乎表明SQL Server使用的内存大于65GB。


这会产生什么?SELECT TOP (20) * FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC;
亚伦·伯特兰

嗨,亚伦,谢谢您的回复。我现在将使用输出更新问题
dbafromthecold 2015年

Answers:


11

最大服务器内存控制着缓冲池和所有页面大小的分配,但是仍然不能控制诸如直接Windows分配(链接的服务器,sp_OA,XPs),线程/线程栈所需的内存等

您可能会期望在NUMA上更高(尽管我不确定20 GB是否正常);关键是,您不能期望最大的服务器内存能够完全控制SQL Server实例使用的内存。如果您希望整个实例(不只是缓冲池,计划缓存和CLR)使用不超过64GB,则应将最大服务器内存设置为较低。

一些潜在的想法可以追踪到这一点(我将所有内容标准化为MB):

  • 性能计数器

    看看是否有任何东西跳得太大了:

    SELECT counter_name, instance_name, mb = cntr_value/1024.0
      FROM sys.dm_os_performance_counters 
      WHERE (counter_name = N'Cursor memory usage' and instance_name <> N'_Total')
      OR (instance_name = N'' AND counter_name IN 
           (N'Connection Memory (KB)', N'Granted Workspace Memory (KB)', 
            N'Lock Memory (KB)', N'Optimizer Memory (KB)', N'Stolen Server Memory (KB)', 
            N'Log Pool Memory (KB)', N'Free Memory (KB)')
      ) ORDER BY mb DESC;
    
  • 前20名文员

    您已经完成了此操作,但出于完整性考虑:

    SELECT TOP (21) [type] = COALESCE([type],'Total'), 
      mb = SUM(pages_kb/1024.0)
    FROM sys.dm_os_memory_clerks
    GROUP BY GROUPING SETS((type),())
    ORDER BY mb DESC;
    
  • 线程堆栈大小

    首先,请确保它是零,而不是一些自定义数字(如果它不是0,请找出原因并修复):

    SELECT value_in_use
      FROM sys.configurations 
      WHERE name = N'max worker threads';
    

    但是您还可以使用以下命令查看线程堆栈占用了多少内存:

    SELECT stack_size_in_bytes/1024.0/1024 
      FROM sys.dm_os_sys_info;
    
  • 加载了第三方模块

    SELECT base_address, description, name
      FROM sys.dm_os_loaded_modules 
      WHERE company NOT LIKE N'Microsoft%';
    
    -- you can probably trace down memory usage using the base_address
    
  • 记忆相关的DMV

    您可能还可以发现这些DMV异常之处:

    SELECT * FROM sys.dm_os_sys_memory;
    SELECT * FROM sys.dm_os_memory_nodes WHERE memory_node_id <> 64;
    

本文是在SQL Server 2012之前编写的,因此可能需要调整某些列名和计算,但也可以尝试使用其他方法:

该网站上另一篇文章也有一些良好的背景:

有关在外部使用内存的事物类型的一些很好的信息max server memory(但没有有关如何收集实际使用情况的好的数据):


感谢Aaron,该服务器有足够的可用内存,我只是想看看我是否能找到使用那20GB的内存。有没有一种方法可以确定直接Windows分配或线程堆栈的内存消耗?
dbafromthecold 2015年

我有运行脚本,“被盗服务器内存(KB)”计数器为14GB。进行挖掘以查看是否可以获得更多信息
dbafromthecold 2015年

服务器内存被盗似乎不是问题。仍在寻找
dbafromthecold

尽管这里不是问题,但值得一提的是,列存储对象池(CACHESTORE_COLUMNSTOREOBJECTPOOL内存文员类型)也位于缓冲池之外。见从尼科纽格鲍尔这个博客帖子
BlažDakskobler

@BlažDakskobler是的,谢谢,内存中也是如此。如果有机会,我会更新帖子
Aaron Bertrand

3

我从鲍勃·多尔(Bob Dorr)那里得到了关于SQL Server 2012中最大服务器内存控制的定义。您也可以阅读联机丛书以获取更多详细信息

服务器的最大内存控制SQL Server的内存分配,包括缓冲池,编译内存,所有缓存,qe内存授予,锁管理器内存和CLR内存(基本上是dm_os_memory_clerks中的任何“职员”)。线程堆栈,内存堆,除SQL Server之外的链接服务器提供程序的内存,或由“非SQL Server” DLL分配的任何内存均不受最大服务器内存的控制。

分配给线程堆栈的内存,第三方DLL,除Microsoft以外的链接服务器提供程序(如MySQL.PostgreSQL等)或在SQL Server地址空间中加载的非SQL Server的任何DLL被分配在最大服务器内存之外。SQL Server 2012中的IIRC备份操作仍在缓冲池之外分配了内存。

您是否正在使用链接服务器查询其他RDBMS?同一Windows机器上安装的任何其他软件。您能否在某些共享位置发布以下查询的输出

select type,
sum(pages_kb)/1024 as [Memory utilized in MB],
sum(awe_allocated_kb)/1024 as [Memory allocated though Windows API]
 from sys.dm_os_memory_clerks
 group by type
 order by [Memory utilized in MB] desc
 Go
-------

 select (virtual_address_space_committed_kb/1024) as virtual_address_space_committed_MB,
 (locked_page_allocations_kb/1024) locked_page_allocations_MB,
 (pages_kb/1024) [memory allocated MB]
  from sys.dm_os_memory_nodes
  Go
-------
SELECT SUM (pages_in_bytes)/1024 as 'KB Used', type 
FROM sys.dm_os_memory_objects
GROUP BY type 
ORDER BY 'KB Used' DESC;
GO
--------
select name,
type,
sum(pages_kb)/1024 as [Mem MB],
sum(entries_count) as [Total Entry count] from sys.dm_os_memory_cache_counters
group by
type, name
order by [Mem MB] desc
Go
-----
select * from sys.dm_os_loaded_modules where company <> 'Microsoft Corporation'
go

您还可以将完整的DBCC MMEMORYSTATUS输出上传到某个共享位置并在此处发布链接吗?这将有助于了解哪些组件正在占用内存

编辑:根据dbcc memorystatus输出,我可以看到2个NUMA节点,每个节点使用的内存约为

Node 1 : VM Committed 33554380

Node 2: VM Committed  33554420

Total is approx 64 G. 

再次,如果您在memorystatus中看到Memory Manager输出

Memory Manager                           KB
---------------------------------------- -----------
VM Reserved                              260726964
VM Committed                             **67108820**

提交的VM实际上是SQL Server提交的虚拟内存,并且由于已提交了此内存physical memory backing it。再次使我觉得SQL Server使用的最大服务器内存设置为65 G

这是最大的服务器内存。因此,内存可以在两个节点之间很好地分配,也可以添加以下查询语句的输出进行检查。请添加屏幕截图

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

@DBAFromTheCold:已经晚了,但是您是否还在寻找答案,如果是的话,我想再尝试select * from sys.dm_so_process_memory
一遍

嗨Shanky,感谢您的答复,但问题已解决。对我而言,SQL本身并没有释放内存。我正在监视服务器,如果再次发生,我将发布更新。真的想深入了解这一点。
dbafromthecold 2015年
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.