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

场景:

  最近一台DB服务器偶尔出现CPU报警,我的邮件报警阈(请读yù)值设置的是15%,开始时没当回事,以为是有什么统计类的查询,后来越来越频繁。

探索:

  我决定来查一下,究竟是什么在作怪,我排查的顺序如下:

  1、首先打开Cacti监控,发现最近CPU均值在某天之后骤然上升,并且可以看到System\Processor Queue Length 和 sqlservr\%ProcessorTime 也在显著的变化。

  

  2、从最容易入手的低效SQL开始,考虑是不是最近业务做了什么修改?连接到该SQL实例,打开活动监视器,展开“最近耗费大量资源的查询”,并CPU时间倒序,在这里并未发现有即时的耗费资源的查询。据个人经验,这里的值如果是4位数,分钟内执行次数3位数,一般的服务器CPU大概就10%以上,如果cpu时间那里是5位数,且分钟内执行次数也很高,几百次以上,那CPU一般就会不淡定了。图片仅为演示

  

  3、没有耗资源的SQL,这是DBA最不愿意看到的结果,因为也许,SQL Server受到了来自内部或者外部的压力,使得自己花费了过多的时间去处理与操作系统的沟通去了。SQL Server常见的非查询低效类的性能问题,绝大多数都来自于内存或者硬盘,而这两者有的时候需要同时研究对比基线,才能确定谁是因,谁是果。在这里,我们首先查看SQL Server内存使用情况,当打开性能计数器时,我和我的小伙伴们都惊呆了……安装了64G内存的数据库,SQL Server的TargetMemory仅有500多兆!这其中StolenPage还占用了200多兆,数据库DataPage仅有200多兆的内存可供使用,Oh,Shit!虽然我很不想用“去哪了”这三个字,但是“我的内存去哪了“?同时我们也注意到PageLifeExpectancy值只有26(一个内存充足的服务器,这个值至少应该是上W的),而很早之前我们津津乐道的"Cache Hit Ration"却仍然保持一个比较高的水准98! 这个案例告诉我们,缓存命中率这个性能计数器很多时候说明不了什么问题。

  

  4、OK,既然这样,是谁占用了本该属于我亲爱的SQL Server的内存呢?我们继续,打开Wiindows任务管理,选定进程选项卡,点击显示所有用户进程,发现svchost.exe占用了绝大多数的60G内存!

  

  5、那svchost.exe又是个什么东西呢?我们下面就用到ProcessMonitor这个工具了,打开后自动加载所有Wiindows进程,按内存排序后,鼠标移至svchost.exe进程上,显示为Remote Registry服务。

  

  6、查到这里,事情已经有了一定的眉目,这个多半是windows内存泄露Bug,遂google关键词: windows server 2008 r2 remote registry memory leak

  找到如下链接:http://support.microsoft.com/kb/2699780/en-us

  果然:Assume that you query performance counters on a remote computer by using an application on a computer that is running Windows 7 or Windows Server 2008 R2. In this situation, the memory usage of the Remote     Registry service on the local computer increases until the available memory is exhausted.

解决方法:

  1、重启服务器,安装hotfix

  2、因为重启服务器会影响到业务,所以我在想重启RemoteRegistry服务,应该也能暂时解决问题,这个bug应该是在某种固定情景下发生的。

  随后,在合适的时间,我重启了这个服务,SQL Server的TargetMemory重新恢复到60多G,CPU也正常了,目前为止该问题未再发生。

后续跟进:

  DBA的工作,说难也难,说容易也容易,发现问题,解决问题还不够,我们还要意识到自己的欠缺,在本案例中,我之前并没有建立起SQL Server内存的监控,所以没有在第一时间就发现病情的严重性,好在该服务器并未承担重要业务,否则后果不堪设想,说不定早就崩溃过了,后怕之处在于,如果崩溃了,自然要重启服务器,到那个时候,我们连第一现场都没有,当leader问起来,我又该使劲挠头了。

  该事件之后,我建立起了SQL Server内存的监控,1天后,我从新的监控数据中,又发现了一台服务器出现相同的问题!我很庆幸,不是庆幸服务器没宕机,而是庆幸我做对了。

  附一张内存监控图,可以看到服务重启之后,SQL Server的Total Pages一直在上升,并逐渐稳定,Page life expectancy也在变得越来越大,CPU也能指示病症已消除,我很欣慰。

  

  

总结:

  服务器在出现性能问题前,大部分是提前有一些征兆的,尤其是内存泄露,因为内存是一点点被压榨掉的,最后到达一个极限时,SQL Server就会突然Crash掉,然后只留给你一个dump,微软就笑了。有经验的大夫应该从日常的腰酸背痛中看出一些端倪,然后进一步分析,提前预知重大疾病的发生,这就是DBA的价值。这个案例,告诉我,重视服务器异常的细节变化,才能做到防患于未然。

(0)

相关推荐

  • SQLserver2000 企业版 出现"进程51发生了严重的异常"错误的处理方法

    情景:一直用到比较好,突然不行 处理步骤:关了360等防火墙:(影响不大,但是有可能是因为杀毒软件处理时把某个关键文件heal了) 装了微软补丁http://www.microsoft.com/downloads/details.aspx?FamilyID=9552d43b-04eb-4af9-9e24-6cde4d933600&displaylang=zh-cn#filelist 重新启动就ok了. 这个工具是微软SQL Server 2000 安全工具,描述为"SQL Server

  • sql server 2000阻塞和死锁问题的查看与解决方法

    数据库发生阻塞和死锁的现象: 一.数据库阻塞的现象:第一个连接占有资源没有释放,而第二个连接需要获取这个资源.如果第一个连接没有提交或者回滚,第二个连接会一直等待下去,直到第一个连接释放该资源为止.对于阻塞,数据库无法处理,所以对数据库操作要及时地提交或者回滚.二.数据库死锁的现象:第一个连接占有资源没有释放,准备获取第二个连接所占用的资源,而第二个连接占有资源没有释放,准备获取第一个连接所占用的资源.这种互相占有对方需要获取的资源的现象叫做死锁.对于死锁,数据库处理方法:牺牲一个连接,保证另外

  • 查找sqlserver查询死锁源头的方法 sqlserver死锁监控

    查找出SQLServer的死锁和阻塞的源头 --查找出SQLServer死锁和阻塞的源头 复制代码 代码如下: use mastergodeclare @spid int,@bl intDECLARE s_cur CURSOR FORselect  0 ,blockedfrom (select * from sysprocesses where  blocked>0 ) awhere not exists(select * from (select * from sysprocesses whe

  • sqlserver进程死锁关闭的方法

    1.首先我们需要判断是哪个用户锁住了哪张表. --查询被锁表 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resource_type='OBJECT' 查询后会返回一个包含spid和tableName列的表. 其中spid是进程名,tableName是表名. 2.了解到了究竟是哪个进程锁了哪张表后,需要通过进程找到锁

  • SqlServer表死锁的解决方法分享

    其实不光是上面描述的情况会锁住表,还有很多种场景会使表放生死锁,解锁其实很简单,下面用一个示例来讲解: 1 首先创建一个测试用的表: 复制代码 代码如下: CREATE TABLE Test ( TID INT IDENTITY(1,1) ) 2 执行下面的SQL语句将此表锁住: 复制代码 代码如下: SELECT * FROM Test WITH (TABLOCKX) 3 通过下面的语句可以查看当前库中有哪些表是发生死锁的: 复制代码 代码如下: SELECT request_session_

  • SQLServer 中的死锁说明

    两个进程发生死锁的典型例子是:进程T1中获取锁A,申请锁B:进程T2中获取锁B,申请锁A,我们下面动手来演示一下这种情况: 1. 创建一个Database,名为InvDB. 2. 执行下面脚本创建person表并填充两条数据: 3. 在SQL Server Management Studio的两个窗口中同时执行下面的查询: 这段代码在默认的READ COMMITTED隔离级别下运行,两个进程分别在获取一个排它锁的情况下,申请对方的共享锁从而造成死锁. 可见一个进程可以正常更新并显示结果,而另一个

  • 利用sys.sysprocesses检查SqlServer的阻塞和死锁

    MSDN:包含正在 SQL Server 实例上运行的进程的相关信息.这些进程可以是客户端进程或系统进程. 视图中主要的字段: 1. Spid:Sql Servr 会话ID 2. Kpid:Windows 线程ID 3. Blocked:正在阻塞求情的会话 ID.如果此列为 Null,则标识请求未被阻塞 4. Waittype:当前连接的等待资源编号,标示是否等待资源,0 或 Null表示不需要等待任何资源 5. Waittime:当前等待时间,单位为毫秒,0 表示没有等待 6. DBID:当前

  • SQL Server内存遭遇操作系统进程压榨案例分析

    场景: 最近一台DB服务器偶尔出现CPU报警,我的邮件报警阈(请读yù)值设置的是15%,开始时没当回事,以为是有什么统计类的查询,后来越来越频繁. 探索: 我决定来查一下,究竟是什么在作怪,我排查的顺序如下: 1.首先打开Cacti监控,发现最近CPU均值在某天之后骤然上升,并且可以看到System\Processor Queue Length 和 sqlservr\%ProcessorTime 也在显著的变化. 2.从最容易入手的低效SQL开始,考虑是不是最近业务做了什么修改?连接到该SQL

  • SQL Server内存机制详解

    1.前言 对于数据库引擎来说,内存是一个性能提升的重要解决手段.把数据缓存起来,可以避免在查询或更新数据时花费多余的时间,而这时间通常是从磁盘获取数据时用来等待磁盘寻址的.把执行计划缓存起来,可以避免重复分析执行计划时带来额外的CPU及各种资源的开销.通过在内存中开辟查询内存空间,可以迅速地完成排序.哈希等计算,达到快速返回运算结果的目的.若没有足够的内存空间,数据库引擎将无法快速地响应用户的请求. 2.SQL Server如何从操作系统层面分配内存 SQL Server存储引擎本身是一个Win

  • Sql Server 和 Access 操作数据库结构Sql语句小结

    下面是Sql Server 和 Access 操作数据库结构的常用Sql,希望对你有所帮助.内容由海娃整理,不正确与不完整之处还请提出,谢谢. 新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default '默认值' null ,[字段2] ntext null ,[字段3] datetime,[字段4] money null ,[字段5] int default 0,[字段6]

  • ASP语言实现对SQL SERVER数据库的操作

    目前管理信息系统已从传统的客户机/服务器(C/S)模式转向了浏览器/服务器(B/S)模式,特别是微软公司推出它的新产品ASP语言之后,这种转变更加迅猛.管理信息系统的核心是对数据库进行包括添加.修改和查询等等操作,ASP提供的ADO数据库接口控件,使得程序员再也勿需编写复杂的CGI程序了,而只要用几句简单的语句即可实现以上操作.1.系统环境 PII 350,Ram 64M,WINNT Server 4.0, Service Pack4, IIS 4.0, SQL Server7.0. 2.系统功

  • Go pprof内存指标含义备忘录及案例分析

    最近组内一些Go服务碰到内存相关的问题,所以今天抽时间看了下Go pprof内存指标的含义,为后续查问题做准备. 内容主要来自于Go代码中对这些字段的注释,加自己的理解.理解不对的地方欢迎指正. // https://github.com/golang/go/blob/master/src/runtime/mstats.go#L150 // 总共从OS申请的字节数 // 是下面各种XxxSys指标的总和.包含运行时的heap.stack和其他内部数据结构的总和. // 它是虚拟内存空间.不一定全

  • SQL Server的事务操作隔离模式介绍

    一般而言,最好让SQL Server以默认形式在隔离事务操作;毕竟,隔离是ACID模型的基本原则之一.但是,有时候因为业务需求的原因,数据库管理员不得不违背默认行为,而 是采取更灵活一点的方法来进行事务操作隔离.针对数据库管理员遇到的这类情况,SQL Serve提供了五种不同的事务操作隔离模式.在详细介绍这些事务操作隔离模式之前,必需先了管理员会遇到的数据库问题: 1.脏数据读写,这种情况发生在当一个事务读写由另一个事务修改而未提交的数据的时候.如果另一个事物永远都不提交其修改数据,那么第一个事

  • PowerShell连接SQL SERVER数据库进行操作的实现代码

    核心代码 #配置信息 $Database = 'DemoDB' $Server = '"WIN-AHAU9NO5R6U\DOG"' $UserName = 'kk' $Password = '123456' #创建连接对象 $SqlConn = New-Object System.Data.SqlClient.SqlConnection #使用账号连接MSSQL $SqlConn.ConnectionString = "Data Source=$Server;Initial

  • Sql Server事务语法及使用方法实例分析

    本文实例讲述了Sql Server事务语法及使用方法.分享给大家供大家参考,具体如下: 事务是关于原子性的.原子性的概念是指可以把一些事情当做一个不可分割的单元来看待.从数据库的角度看,它是指应全部执行或全部不执行的一条或多条语句的最小组合. 为了理解事务的概念,需要能够定义非常明确的边界.事务要有非常明确的开始和结束点.SqlServer中的每一条select.insert.update.delete语句都是隐式事务的一部分.即使只发出一条语句,也会把这条语句当做一个事务-或执行语句的所有内容

  • SQL Server 2005 创建简单的存储过程--总结分析

    最近由于工作需要,简单了解了下SQL Server 2005 数据库创建简单的在存储过程.一.首先说明如何创建存储过程: CREATE PROCEDUER my_pro @inputDate varchar ,//声明输入变量 @Result varchar(255) output //声明输出变量 AS declare @variable1 varchar(255)//声明varchar变量 declare @variable2 int //声明整形变量 BEGIN IF ...(条件) BE

  • 浅谈SQL Server中统计对于查询的影响分析

    而每次查询分析器寻找路径时,并不会每一次都去统计索引中包含的行数,值的范围等,而是根据一定条件创建和更新这些信息后保存到数据库中,这也就是所谓的统计信息. 如何查看统计信息 查看SQL Server的统计信息非常简单,使用如下指令: DBCC SHOW_STATISTICS('表名','索引名') 所得到的结果如图1所示. 图1.统计信息 统计信息如何影响查询 下面我们通过一个简单的例子来看统计信息是如何影响查询分析器.我建立一个测试表,有两个INT值的列,其中id为自增,ref上建立非聚集索引

随机推荐