一些内存使用错误理解

 

开篇小感悟

  在实际的场景中会遇到各种奇怪的问题,为什么会感觉到奇怪,因为没有理论支撑的东西才感觉到奇怪,SQL Server自己管理内存,我们可以干预的方式也很少,所以日常很难遇到处理内存问题的案例。当遇到了原有的知识储备已经变得模糊,这是已经记不住第几遍阅读《SQL 2012实施与管理实战指南》内存管理章节,也分享给群友。sql server内存使用

一些内存使用错误理解

    本文来澄清一些用户经常对SQL Server内存使用的误解。对这些知识的理解可以帮助数据库管理员理解SQL Server的行为 
    1. Windows上还有很多物理内存没有被使用,就意味着SQL Server不缺内存
    这个观点是非常错误的,因为:
    (1)SQL Server很可能设置了Max Server Memory,约束了SQL Server继续申请内存的能力。(注:实际场景中就遇到过客户128GB内存的机器SQL Server 的Max Server Memory 被设置成2048MB 导致严重的问题
    (2)在32位的机器上 ,由于虚拟地址空间的限制,SQL Server可能已经无法继续申请内存。
    例如,在一台4 GB或更大的32位服务器上,SQL Server最多只能使用2 GB物理内存。一般Windows会使用500 MB左右的物理内存,这台机器可能就有1 GB多的空闲物理内存。这部分内存是SQL Server不开AWE就用不到的。 所以,服务器上有很多空闲物理内存,只能说明Windows不缺内存,不能说明SQL Server自己不缺内存。(这也是为什么建议更换老一代服务器,使用64位的操作系统和SQL Server的原因
 
    2.  SQL Server进程的Private Bytes(或Working Set)在不停地向上涨,说明SQL Server有内存泄漏的问题
    恰恰相反,对于申请内存,SQL Server有严格的限制。在32位的服务器上,不管是Buffer Pool还是MemToLeave,都有一个使用最大上限。当Windows感觉到有内存压力的时候,SQL Server又会主动地释放内存所以作为一个进程,SQL Serve发生内存泄漏的机会是非常小的。
    之所以会有这样的疑惑,是因为SQL Server启动的时候,仅会Commit它启动所需要的那部分内存。随着用户的使用,SQL Server会不断地申请内存,直到Windows感觉到内存压力,或者SQL到了自己的上限为止,在这之前,SQL Server的内存使用量的确会不断地增加。对SQL Server来讲,缓存越多的数据,它的性能会越好这种增长是正常的,不用焦虑如果不希望SQL Server使用那么多内存,只需设置Max Server Memory这个上限即可。
  (注:实际情况中很多人提到过,SQL Server竟然吃掉了所有服务器的内存,是不是内存泄露了?或问内存是不是这就是我系统的瓶颈呀?) 
 
    3.  Max Server Memory的值,就是SQL Server内存使用量的最大值。超过这个值就不正常
  Max Server Memory这个值应该是Buffer Pool的上限(此点针对SQL Server 2005/2008而言,对于SQL Server 2012内存管理发生了非常大的变化),而不是SQL Server所有内存使用的上限。由于SQL Server 内存的使用包括Buffer Pool和MemToLeave,所以SQL Server实际内存使用量一定会比Max Server Memory要大但是在正常情况下SQL Server MemToLeave的使用会远小于Buffer Pool的使用,控制好Buffer Pool,就基木控制住了SQL Server的整体内存使用量
   (注:建议无论内存是否存在压力都要合理的设置最大内存,PS:我也曾经被使用的内存超过设置的Max Server Memory吓了一跳
  
    4. SQL Server的内存使用总量,就是性能监视器里面的SQL Server:Memory Manager一Total Server Memory的值
    性能监视器里面与SQL Server相关的counter,都是SQL Server自己负责收集的。从SQL Server 2005以后,SQL整合了所有的内存申请,让它们使用同一的接口。所以SQL Server对自己申请的内存数量,是了如指掌的,但问题是,在SQL Server进程里运行的代码不都是SQL Server自己的代码。对第三方的代码,SQL Server是不知道它们申请了多少内存的。
    SQLServer:Memory Manager - Total Server Memory的值,是SQL Server自己的代码申请的内存空间大小。真正SQL Server进程申请的空间值,会比这个值大一些。(具体大多少和MemToLeave的大小有关系)
    如果SQL Server没有开启AWE,SQL Server进程申请的逻辑内存数和物理内存数可以由Process下的Private Bytes和Working Set看出。这两个值会包含所有的内存支出,包括SQL自己的代码和第三方的代码。
    如果SQL Server开启了AWE,问题就比较尴尬了。因为Windows没有办法正确判断出一个使用了AWE 内存的进程,究竟总共用了多少内存。我们只能借助SQLServer:Memory Manager一Total Server Memory来判断SQL Server的Buffer Pool使用量。至于SQL Server自己申请的内存总数(Buffer Pool + MemToLeave ),可以通过查询和内存相关的DMV计算出来,但第三方的代码申请的内存,就很难做精确计算了
   
  
    5.当系统有内存压力的时候,SQL Server总是会自动释放内存
    默认情况下,SQL Server的确会在系统有内存压力的时候自动释放内存但是有个例外:SQL Server启动时会试图做“Lock Page In Memory”的动作。如果启动账号有这个权限,动作就会成功。那么当同一台服务器上的其他应用程序需要内存的时候,SQL Server很可能不会释放内存。所以在这种情况下,建议SQL Server设置Max Server Memory上限。
  (注:Lock Page In Memory很多资料上写到SQL的内存不会被释放了,但实际情况中,当操作系统感觉到压力一样会把SQL的内存释放掉,也是错误理解6的由来) 
 
    6.  SQL Server有办法将自己的内存绑定在物理内存里
    SQL Server的确想通过Lock Page In Memory的方法达到这个目的。但是,作为一个用户态为主的应用程序,它还是会受限于核心态。如果核心态里发出内存要求,SQL Server就会被迫把自己的内存释放出来。
 
    7.增加MemToLeave的大小可以提高SQL Server的性能
    在32位的SQL Server上,默认MemToLeave是256 MB+0.5 MB x ( Max Thread数目)。如果MemToLeave 用完了,SQL Server的一些重要功能就不能进行,甚至新的连接都建立不起来所以一些对MemToLeave需求比较大的SQL Server,例如,一些经常运行Linked Server分布式查询的SQL Server,或者是一些运行CLR,Extended Stored Procedur的SQL Server,可能不得不再加一些MemToLeave空间。这可以使用SQL Server的

一个启动参数一g完成。例如,如果想把MemToLeave设成512 MB+0.5 MB x ( Max Thread数目),可以加启动参数一g512。
    但是需要想清楚的是,SQL Server的虚拟地址空间只有2 GB,给MemToLeave越多,Buffer Pool能拿到的就越少。Data Cache的内存还可以从AWE扩展的内存补,Buffer Pool里的Stolen内存就没办法了。所以其实这是拆东墙补西墙,关键要看哪一块内存对SQL Server的性能和稳定运行最重要。不必要多给,这会浪费资源,影响Buffer Pool里面的性能。只有确定了SQL Server的MemToLeave的确不够,才应该去增大它

  
 8.增加物理内存一定会提高SQL Server的性能
    既然SQL Server这么喜欢内存,那管理员多给服务器配备一些内存,是不是就一定能够提高性能呢?很多时候这个想法是对的,但是并不是总是正确。这是因为增加的内存SQL Server不一定用得到。
    (1)首先要检查是哪一部分的内存有瓶颈,是Database Cache,还是Stolen,是Buffer Pool,还是MemToLeave。
    (2)要检查缺的那部分内存是不是已经到了理论上的上限,新加内存SQL Server用不用得上例如,在32位+AWE的服务器上,Buffer Pool里的Stolen Memory最多也不过1.6 GB。如果是这一部分内存不够,再加内存也没有用。只有将系统升级到64位,才能突破这些限制。
    (3)加人的内存,一般大部分都会被Buffer Pool使用,这样SQL Server就会缓存更多的数据页面和执行计划,大多数时候这会对性能有帮助。如果Database Pages没有压力,SQL Server会缓存太多的动态T-SQL执行计划,对性能没什么好处,反而会增加SQL Server的维护成本。只有在SQL Server的Database Page缺内存的时候,增加内存才会对性能有明显帮助。如果数据库比较小,常用数据页面已经缓存在了内存里,增加内存对性能不会有太大帮助。
  (注:内存这个东西对于一些初级DBA分析起来还是有些难度,而很多情况下只要看到内存压力就要添加内存这样也是不对的,很多时候内存的消耗很自己程序的语句优化程度也有着非常大的关系) 
 
 9. Stolen的内存真的是偷来的吗
   很多在描述Stolen的内存块的时候都说这块内存是不需要保留(Reserve)而直接提交(Commit )使用的,所以这块内存叫作Stolen。这么说错了吗?其实,从Windows的层面,对于任何内存的使用,都必须遵循先Reserve再Commit的过程。对于一块内存,如果不Reserve而直接使用会导致访问违例(Access Violation)因为SQL Server内部的内存管理机制,所有要使用的内存,Buffer Pool都已经帮我们保留(Reserve)好了如果SQL所要做的,是用Buffer Pool已经保留(Reserve)好了的那部分地址空间去直接提交(Commit ),而且,这一部分内存又不是用来存放Buffer的,就被称为Stolen

--------------博客地址---------------------------------------------------------------------------------------

博客园原文地址: http://www.cnblogs.com/double-K/

 

欢迎转载,请保留出处。

-----------------------------------------------------------------------------------------------------

(4.11)sql server内存使用的更多相关文章

  1. 人人都是 DBA(IV)SQL Server 内存管理

    SQL Server 的内存管理是一个庞大的主题,涉及特别多的概念和技术,例如常见的 Plan Cache.Buffer Pool.Memory Clerks 等.本文仅是管中窥豹,描述常见的内存管理 ...

  2. SQL Server 内存中OLTP内部机制概述(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  3. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  4. SQL Server内存遭遇操作系统进程压榨案例

    场景: 最近一台DB服务器偶尔出现CPU报警,我的邮件报警阈(请读yù)值设置的是15%,开始时没当回事,以为是有什么统计类的查询,后来越来越频繁. 探索: 我决定来查一下,究竟是什么在作怪,我排查的 ...

  5. Sql Server 内存相关计数器以及内存压力诊断

    在数据库服务器中,内存是数据库对外提供服务最重要的资源之一, 不仅仅是Sql Server,包括其他数据库,比如Oracle,MySQL等,都是一类非常喜欢内存的应用. 在Sql Server服务器中 ...

  6. SQL SERVER 内存学习系列(二)-DMV查看内存信息

    内存管理在SQL Server中有一个三级结构.底部是内存节点,这是最低级的分配器,用于SQL Server的内存.第二个层次是由内存Clerk组成,这是用来访问内存节点和缓存存储,缓存存储则用于缓存 ...

  7. SQL SERVER 内存学习系列(一)

    最近帮客户解决发布订阅的问题时,突然遇到这样一个问题发布订阅中报下面的错误,另外执行alter table 操作时也会报错 : 问题很奇怪发布订阅和CLR有什么关系?memtoleave内存是个啥?回 ...

  8. SQL Server内存理解的误区

    SQL Server内存理解 内存的读写速度要远远大于磁盘,对于数据库而言,会充分利用内存的这种优势,将数据尽可能多地从磁盘缓存到内存中,从而使数据库可以直接从内存中读写数据,减少对机械磁盘的IO请求 ...

  9. SQL SERVER 内存分配及常见内存问题 DMV查询

    内存动态管理视图(DMV): 从sys.dm_os_memory_clerks开始. SELECT  [type] , SUM(virtual_memory_reserved_kb) AS [VM R ...

随机推荐

  1. bullet, iOS真机编译错误error: identifier or immediate expression expected解决方法

    刚才发现c3dEngine2(http://git.oschina.net/wantnon2/c3dEngine2 或 https://github.com/wantnon2/c3dEngine2)的 ...

  2. Win7安装.Net framework 3.5时出错的某解决办法

    情况: Win7卸载了.Net Framework 3.5后, 做了些盘符的Symlink操作, 将一些大文件从C盘移到D盘. 再次安装.Net 3.5时, 怎么都装不上, 直接下载离线安装包, 一装 ...

  3. grub手动引导win7

    grub>rootnoverify (hd0,0)--->win7系统安装盘号 grub > chainloader +1 grub > makeactive     ---& ...

  4. ubuntu16安装docker

    首先确保curl已经安装! 然后执行: curl -sSL https://get.docker.com/|sudo sh 这个是通过脚本的方式安装docker. 运行命令测试 sudo docker ...

  5. 一键保存网页为PDF_V1.2

    福利来了,“一键保存网页为PDF”发布以来最给力的功能来了: 1.支持大部分浏览器了(添加书签方式),测试IE8\IE9.谷歌.火狐可用: 2.转换组件“ephtmltopdf”无水印了,不用注册账号 ...

  6. 自定义 Collection View 布局

    自定义 Collection View 布局 answer-huang 29 Mar 2014 分享文章 UICollectionView 在 iOS6 中第一次被引入,也是 UIKit 视图类中的一 ...

  7. DataUml Design 介绍8-DataUML 1.2版本正式发布(支持SQLite数据库、NetUML开发框架)

    DataUML 1.2版本在软件架构上有了很大的变化,目前DataUML支持Access.SQLite.MY SQL .ORACLE.MS SERVER2000.MS SERVER2005.MS SE ...

  8. 设备树API

    引子 首先看一个例子,也可参考linux设备树语法中的gpio示例.该示例选自openwrt的gpio-button-hotblug驱动. 设备树code: gpio-keys-polled { co ...

  9. makefile变量定义应用到c语言

    makefile是为组织程序工程的,其定义的宏怎样应用到c程序中呢? 我们知道Makefile中可定义变量或导出变量,make命令可定义变量:编译器(如gcc)可通过CFLAGS定义宏. 但如何才能使 ...

  10. PHP递归实现无限级分类

    在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性.那么PHP是如何实现无限级分类的呢?我们在本文中使用递归算法并结合mysql数据表实现无限级分类. 在一些复杂的系统中,要求对信 ...