SQLServer Stolen内存优化案例
最近开始观察到 SQLServer.exe 进程占用内存过大,已达到了60GB,如图: 然而,SQLServer 限制的最大内存为 55GB: EXEC sp_configure'max server memory (MB)'
可以看到,竟然高出近5GB。 先说明当前数据库情况: 数据库总大小不到50GB,最大内存限制为55GB。 其实数据内存的使用绰绰有余了,什么原因呢?现在开始跟踪。 先打开性能监视器(cmd—>perfmon)监视系统及数据库内存情况: 监视可确定: 除了部分缓存计划,Stolen pages 占用最多!~而 Stolen 中的 MemToLeave 是不受’max server memory (MB)’ 限制的。可以使用系统DMV sys.dm_os_memory_clerks 查看主要哪些类型对象占用的 Stolen 或者 MemToLeave 最多。 SELECT [type],SUM(virtual_memory_reserved_kb) AS [vm reserved],SUM(virtual_memory_committed_kb) AS [vm commited],SUM(awe_allocated_kb) AS [awe allocated],SUM(shared_memory_reserved_kb) AS [sm reserved],SUM(shared_memory_committed_kb) AS [sm committed],SUM(single_pages_kb) AS [Stolen in Buffer Pool],SUM(multi_pages_kb) AS [MemToLeave],SUM(single_pages_kb)+SUM(multi_pages_kb) AS [Stolen],SUM(virtual_memory_committed_kb)+SUM(multi_pages_kb) AS [Buffer Pool] FROM sys.dm_os_memory_clerks GROUP BY [type] ORDER BY [MemToLeave] desc
可以看到,USERSTORE_TOKENPERM 和 CACHESTORE_SQLCP 占用最多。 使用 DBCC MEMORYSTATUS 查看时,也是这两个Stolen 占用最多。 CACHESTORE_SQLCP(node 0)KB
---------------------------------------- -----------
VMReserved 0
VMCommitted 0
LockedPagesAllocated 0
SMReserved 0
SMCommitted 0
SinglePageAllocator 6398656
MultiPageAllocator 231576
USERSTORE_TOKENPERM(node 0)KB
---------------------------------------- -----------
VMReserved 0
VMCommitted 0
LockedPagesAllocated 0
SMReserved 0
SMCommitted 0
SinglePageAllocator 859584
MultiPageAllocator 4236064
现在使用sys.dm_os_memory_cache_counters 查看具体是什么对象 SELECT top 10 * FROM sys.dm_os_memory_cache_counters(nolock) ORDER BY multi_pages_kb DESC;
TokenAndPermUserStore 占用最多,TokenAndPermUserStore 是什么? 字面意思可以理解,Token and Permission ,即用户登录和权限的认证信息。 该值的大小和数量一直都在增加: SELECT SUM(single_pages_kb+multi_pages_kb) AS "CurrentSizeOfTokenCache(kb)" FROM sys.dm_os_memory_clerks WHERE name='TokenAndPermUserStore' SELECT COUNT(*) FROM sys.dm_os_memory_cache_entries(nolock) WHERE [type]='USERSTORE_TOKENPERM' and name='TokenAndPermUserStore'
具体的缓存对象信息可以查看: SELECT TOP 10 OBJECT_NAME(est.objectid,EST.dbid) AS ObjectName,omce.name AS cacheName,omce.in_use_count,omce.is_dirty,omce.disk_ios_count,omce.context_switches_count,omce.original_cost,omce.current_cost FROM sys.dm_exec_cached_plans ecp CROSS APPLY sys.dm_exec_sql_text(ecp.plan_handle) est INNER JOIN sys.dm_os_memory_cache_entries omce ON ecp.memory_object_address = omce.memory_object_address WHERE omce.name = 'Object Plans' --WHERE omce.name = 'SQL Plans'
这个怎么释放?使用系统命令 DBCC FREESYSTEMCACHE DBCC FREESYSTEMCACHE('TokenAndPermUserStore')
--DBCC FREESYSTEMCACHE('SQL Plans')
--DBCC FREESYSTEMCACHE('Object Plans')
执行完成后,内存瞬间降了下来: 虽然是将了下来,但是也会渐渐增加回去。系统提供了几个设置选项,由于介绍这些参数的相关文章太少不详细,本人没太了解,没有使用,如下几个参数: exec sp_configure 'access check cache quota'
exec sp_configure 'access check cache bucket count'
DBCC TRACEON(4620,-1)
========================================================= select cacheobjtype as [Cached Type],COUNT(*) as [Number of Plans],SUM(CONVERT(BIGINT,size_in_bytes))/1024/1024 as [Plan Cache Size(MB)] from sys.dm_exec_cached_plans group by cacheobjtype order by [Plan Cache Size(MB)] desc
编译计划 (compiled plan)占用多达6GB,可以继续用 sys.dm_exec_cached_plans 查看是什么对象占用最多。 select objtype as [Cached Object Type],size_in_bytes))/1024/1024 as [Plan Cache Size(MB)],avg(usecounts) as [Avg Use Count] from sys.dm_exec_cached_plans group by objtype order by [Plan Cache Size(MB)] desc
Adhoc 和 Prepared 占用6GB多的缓存,即时查询和预编译在系统中占用较多,说明有较多SQL语句不能重新使用,每次都需要编译,这部分可以进行参数化或存储过程替代。当然即时查询也可使用系统设置是否进行缓存优化,查看是否开启即时查询优化: EXEC sp_configure'optimize for ad hoc workloads'
下面开启优化: EXEC sp_configure 'show advanced options',1 RECONFIGURE EXEC sp_configure 'optimize for ad hoc workloads',1 RECONFIGURE
这不会使即时查询的缓存计划立即降下来,过几天观察,发现少了1GB+。 本文出自“Hello.KK (SQL Server)”的博客,转载请务必保留此出处http://www.voidcn.com/article/p-bcncvsph-vg.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |