当前位置: 首页 > 科技观察

SQLServer内存被操作系统进程压榨案例

时间:2023-03-19 14:03:00 科技观察

场景:最近某DB服务器偶尔出现CPU告警。我的电子邮件警报阈值(请阅读yù)设置为15%。一开始没当回事,以为是有一些统计查询,越来越频繁了。探索:我决定检查导致问题的原因。我排查的顺序是这样的:1、首先打开Cacti监控,发现某天后平均CPU值突然上升,可以看到System\ProcessorQueueLength和sqlservr\%ProcessorTime也有明显的变化。2、从最易访问的低效SQL入手,考虑业务最近是否有修改?连接SQL实例,打开ActivityMonitor,展开“RecentQueriesConsumingalotofresources”,将CPU时间倒转,并没有立即消耗资源的查询。根据个人经验,如果这里的值为4位数,则一分钟内执行次数为3位数,一般服务器CPU占用10%左右或更多。如果cpu时间是5位数,而且分钟内的执行次数也很高,几百次以上,CPU一般会变得焦躁不安。图片仅作演示:3.没有耗资源的SQL,这是DBA们最不想看到的结果,因为可能是SQLServer在内部或外部的压力下,导致处理时间过长,操作系统通信消失。SQLServer常见的非查询低效性能问题,大部分来自内存或硬盘,有时需要同时研究和比较两个基线,以确定谁是因谁是果。这里,我们首先查看SQLServer的内存使用情况。打开性能计数器,我和小伙伴都惊呆了……装了一个64G内存的数据库,而SQLServer的TargetMemory只有500多兆!其中StolenPage也占用了200多兆,而数据库DataPage只有200多兆内存可用,Oh,Shit!虽然我真的不想用“它去哪儿了”这个词,但是“我的记忆去哪儿了”?同时我们也注意到PageLifeExpectancy的值只有26(内存充足的服务器,这个值至少应该在W以上),而我们很久以前讲的“CacheHitRation”仍然保持着相对98的高水平!这个案例告诉我们,缓存命中率的性能计数器往往不能说明什么问题。4、OK,这样的话,谁占用了本该属于我亲爱的SQLServer的内存呢?继续,打开Wiindows任务管理,选择进程选项卡,点击显示所有用户进程,发现svchost.exe占用了60G内存的大部分!5.什么是svchost.exe?我们将在下面使用ProcessMonitor工具。打开后会自动加载所有的Wiindows进程。按内存排序后,将鼠标移到svchost.exe进程,会显示为RemoteRegistry服务。6、查到这里,事情有了一定的线索。这可能是Windows内存泄漏的bug,所以我搜索了关键字:windowsserver2008r2remoteregistrymemoryleak,找到了以下链接:http://support.microsoft.com/kb/2699780/en-us果然:Assumeth使用运行Windows7或WindowsServer2008R2的计算机上的应用程序查询远程计算机上的性能计数器。在这种情况下,本地计算机上的Remote    Registry服务的内存使用量会增加,直到可用内存耗尽。解决方法:1.重启服务器,安装hotfix2。因为重启服务器会影响业务,所以想到重启RemoteRegistry服务,应该也能暂时解决问题。这个错误应该在某些情况下发生。然后适时重启服务,SQLServer的TargetMemory恢复到60多G,CPU也正常了。到目前为止,问题没有再次出现。追问:DBA的工作,说起来既难又容易。仅仅发现问题并解决问题是不够的。我们也需要意识到自己的不足。监控,所以没有第一时间发现病情的严重性。幸好服务器没有承接重要业务,否则后果不堪设想,说不定早就崩溃了。怕的是要是挂了,自然要重启Server,那时候我们连***站点都没有。领导一问,我又使劲挠头。事件发生后,我设置了SQLServer内存监控。一天后,从新的监控数据中,发现另一台服务器出现了同样的问题!我很高兴,不是服务器没有宕机,而是我做对了。附上内存监控图。可以看到,服务重启后,SQLServer的TotalPages一直在上升,并逐渐趋于稳定。Page的寿命也越来越大。CPU还可以指示症状已消除。我很高兴。总结:服务器在出现性能问题之前,大多都是提前有一些症状,尤其是内存泄漏,因为内存被一点点挤出来了。当***达到一个极限,SQLServer就会突然崩溃,然后就只剩下一个dump给你了,微软笑死了。有经验的医生应该从每天的背痛中看出一些蛛丝马迹,然后进一步分析,提前预知重大疾病的发生。这就是DBA的价值所在。这个案例告诉我,只有关注服务器异常的细节,才能防患于未然。