手把手教你解决系统CPU 100%使用率

简介:
客户是一个世界上很有名的公司,他们最近新上了一套系统,为SUNSolaris 8 +  DB2  V8 FP15 ,平时跑起来好好的一点问题没有。可是,他们每周都会或多或少地遇上一两次 100%CPU 使用率,然后造成系统 down ,不得不重新启动操作系统。

上面就是这次问题的现象,假设这个问题出在诸位读者的系统里面,大家应当如何入手分析?为什么要那样入手分析?

=================================================

首先自然是抓数据,没有数据的话所有的猜测也就只能称为“猜测”,而不能称为分析……

在什么情况下抓什么数据,这是作为系统管理 DBA 的问题诊断的第一门课,也是必须要自学的一门课。每个人面对同样问题时需要的数据可能都是不同的,因为每个人分析问题的思路和切入点都不同,所以没有人能够写出本书来说在 hang 的时候抓这些这些,在 crash 的时候抓这些这些……

对于这个问题,诸位都认为应该抓什么数据呢?

=================================================


首先问题的现象就是操作系统 CPU 高,那么 nmon 是必须的,换句话说至少要有 vmstat ps-elf
另一方面是数据库,因为这个系统是完全的数据库系统,那么出问题基本可以认为是数据库问题了,那么从 DB2 角度来讲,我们需要检测整体情况,还要检测每个连接。所以也就是至少要有 snapshotfor database/applications db2pd–everything 的信息。

那么这些信息该怎么抓?什么时候抓?系统死了以后肯定不能抓了,系统好好跑的时候抓了没用,只能在系统将死的那一段时间的数据才有用,对不?

而且就算只有了当时的一个 vmstat 又能看出什么? CPU 高……高了……高了……然后呢?正常情况下 CPU 怎么样, CPU 增高的速率怎么样?抓信息不能只抓一个时间点,而是要从一段时间出发去理解问题。

那么也就是说,我们不能只抓一次这些数据,而是要不停地抓啊抓啊……那么问题就是,以什么样的速率去抓?

====================================================

这个就是仁者见仁智者见智的问题了,没有标准答案,只要是适合自己的就好……根据这个问题的现象,平时一个小时抓一组数据,当 CPU 超过某一个正常标准时,应该有一个后台监测程序去一分钟抓一组数据,才能够比较准确地反映出问题。

因此我们可以写一个 cronjob 平时一个小时抓一组数据,然后还要写一个后台守护进程几秒钟检测一下 CPU ,如果超出了某一个使用率则调用另一个程序来一分钟抓一次数据……相信这些对诸位能够读到这里还没有睡着的读者来说都不困难。
:)

也许你要问:那你怎么知道超过某个使用率的 CPU 一定会产生问题呢?说不定就是 workload 高了,过一会就好了呢……

没错,如果这样的话我们就把这些数据忽略掉不看就好了……反正系统 down 的时候我们肯定知道,而且我们肯定会在那之前就开始抓数据了,所以我们肯定会抓到问题发生时的数据阿……

======================================================

我们抓了这些信息都要看什么?很多情况下人们抓了无数的信息,然后就不知道该怎么办了。尽管大家都知道问题肯定是能够被这些信息反映出来的,但是面对几百兆甚至几个 G 的文本文件有点狗咬刺猬无从下口的感觉。

在这个问题中,我们首先要知道,是不是 DB2 引起的问题。

当我们能够确认是 DB2 的问题,下一个要问的就是什么东西造成高 CPU ,如果是 DB2 进程,那么是某一个进程吃掉了所有的 CPU ,还是很多小的进程一起吃掉了所有的 CPU

每次问的问题不要太多,让我们先来回答这两个。

从捕捉到的数据来看,问题发生的时候 CPU 的增长率非常非常快,基本上可以认为是几分钟之内就冲到了 100% ,而不是像一些其他的 case 里面,可能用了 3 5 天的时间才渐渐增高到 100%

这个现象可以说明什么?问题是短时间内产生的,而不是像内存泻露那种需要几个小时到几天才能够有明显症状的问题。

那么下一个问题,我们有没有什么进程消耗了过高的 CPU ?这个问题怎么看?很多人喜欢看 ps aux ,实际上在对于 warehouse 这种系统来说,里面的那个百分比是完全没有用的。

想一想它的运算规则,是 CPU 运行总时间除以进程运行总时间……

%CPU

(u and vflags) The percentage of time the process has used the CPU since the process started.The value is computed by dividing the time the process uses the CPU by theelapsed time

of theprocess. In a multi-processor environment, the value is further divided by thenumber of available CPUs because several threads in the same process can run ondifferent CPUs at

the sametime. (Because the time base over which this data is computed varies, the sumof all %CPU fields can exceed 100%.)

那么如果这个进程在刚开始的 10 个小时里面完全不做工,最后的 1 秒钟内消耗所有的 CPU ps aux 所得到的结果也是 0%
:)

所以 ps 里面的 %CPU 基本没用。

那么怎么看一个进程的 CPU 使用率? topas 是一个不错的选择,但是只能在问题发生的时候看……

嘿嘿,大家知道么?

=============================================

当然是 ps –elf |sort +5 –rn | grep –i “db2” | grep –i “<instance owner>” 咯, C 列可不是玩具:

C

(-f, l,and -l flags) CPU utilization of process or thread, incremented each time thesystem clock ticks and the process or thread is found to be running. The valueis decayed by the

schedulerby dividing it by 2 once per second. For the sched_other policy, CPUutilization is used in determining process scheduling priority. Large valuesindicate a CPU intensive

processand result in lower process priority whereas small values indicate an I/Ointensive process and result in a more favorable priority.

按照 C 列降序排列,最高的就是 CPU 消耗最高的 db2 进程。

在结果中,我们的确看到了几个进程有着高 C ,那么下一步就是要验证这些进程到底在干什么。

怎么看?




对比 snapshot 看咯。既然我们知道了哪几个 db2agent 消耗了高 CPU ,那么在 application snapshot 里面查找对应的
PID ,我们看到了大概 30 多个进程都在运行同样的一个查询语句。语句中包含 parametermarker ,也就是 ?

每个语句消耗的 CPU 时间都不大相同,短的只有几秒钟,长的则有几十秒了。这点是可以理解的,因为不同的 parametermarker 所包含的参数可能不一样,那么造成消耗不同 CPU 的结果也可以理解了。



看到这里,我们可以大致的认为这个查询语句是导致高 CPU 的直接原因(不一定是根本原因),那么下一个我们要问的就是,到底是先有鸡还是先有蛋?

是由于系统的某些问题导致这些查询都变慢了,然后一大堆一起执行造成系统更慢的恶性循环呢;还是说这些查询本来不应该这么多一起跑,但是现在由于什么原因他们一起执行造成了高 CPU 呢;或者说本来应该一大堆一起跑,但是每一个查询不应该消耗这么多 CPU 呢?

我们知道找到问题根源的思路肯定就在上面三种可能性的其中一种,那么让我们来一个一个地排除和推导吧……




首先让我们来想想怎样证明或者排除第一种可能性。

怎么看?

从现有的数据我想不出好办法……你们呢?有什么建议?

既然想不出来就不暂时不想,让我们看看第二种可能性。

第二种可能性就要看平时正常的数据了。通过检查平时的数据,我们发现该查询平时基本上不会同时出现 4 条以上。可是出现问题的时候却达到了 30 多条……为什么?

这个很有可能是切入的重点哦……因为这个间接地排除了第三种可能性,也就是平时不应该这么一大堆一起跑……

现在我们面前的是两种可能性,要不就是这些查询出于什么原因变慢了,原本单位时间内应该执行少量的查询,现在却需要执行一大堆……或者原本就不应该有那么多查询,但是某一段时间突然来了一堆……

下一步应该干什么?



不知道读者们都会怎么做,反正我是要客户重新抓数据,这一次加大正常时抓数据的密度,做到一分钟一次。

这次的数据发现了点有趣的冬冬。

在问题发生之前的几分钟内,从正常的数据中我们发现了很多该查询出于 LockWaiting 状态。

这个说明了什么?

估计有人看到这里就该明白了前因后果了……

这是由于某些东西让这个查询造成了
Lock Waiting ,然后这些查询都不能执行,然后越来越多的查询进来都被锁住。而后的某一时刻那个锁突然松了,这样所有的查询同时开始执行,造成了对系统十几倍的负担……

下一个问题就是,什么东西锁的呢?

applicationsnapshot 里面,我们发现所有的这些 lock 实际上都在等同样的一个 lock name ,然后检查这个 lock name 所对应的应用程序,发现它在等另外的一个锁……然后再去看那个锁,却发现在 applicationsnapshot 里面显示这个锁的拥有者是它自己!

一个应用程序等他自己……可能么?

不可能……难道是
bug ?别忙着下结论……



第三次抓数据,这次我们包含进 locksnapshot

从抓到的 locksnapshot 里面发现了什么呢?这个锁的拥有者的 agentid 实际上是 0

怎么回事?

如果我们去 infocenter 查找 agent_id_holding_lock 就会发现:
If this element is 0 (zero) and the application is waitingfor a lock, this indicates that the lock is held by an indoubt transaction. Youcan use either appl_id_holding_lk or the command line processor LIST INDOUBTTRANSACTIONS command (which displays the application ID of the CICS agent thatwas processing the transaction when it became indoubt) to determine the indoubttransaction, and then either commit it or roll it back.

哈哈,明白发生了什么了么?

问题的根源压根就不再 DB2 里面,而是负责 2-phase commit 的应用程序服务器的错误(也不一定是它的错误,至少问题的根源不再 DB2 里面了)。

这个问题发生的因果关系可以被表达为
indoubt transaction 发生 - 〉锁不能被释放
〉一个应用程序在等这个锁
〉使用高 CPU 的查询在等待这个应用程序正在持有的锁
〉应用程序不停地发同样的查询
〉越来越多的查询都在锁等待
〉应用程序服务器在若干长的时间之后自动解决 indbouttransaction (比如回滚) - 〉锁释放
〉很多查询同时得到共享锁,同时执行
〉造成 CPU 使用率一下子冲高,系统性能严重下降
〉新的查询不停地进入
〉系统越来越慢,恶性循环
〉系统死掉……

那么怎么解决 indoubttransaction 呢?那就不是 db2 的问题咯,把这个问题交给应用程序小组去头疼好了。当然,如果业务允许,把那个查询改变成 UR isolation level 也可以,不过很遗憾对于这个客户的业务不能够使用 UR ,所以只能从应用程序层搞定了……

嘿嘿,看了这么多的推导如果你还没有睡着,我想应该能发现点东西吧
:)

首先,调优 / 调错并不是一种根据文档就可以简单完成的任务,而是需要很多的逻辑推导与证明 / 反证。

简单地说就是如下的循环:
自己提出问题 - 〉想到应该如何去证明 - 〉抓数据 - 〉分析数据 - 〉提出下一步的问题……

而这个循环也是适用于我自己的,也许其他人可能有不同的思路,不过所有的思路都可以被归纳为两个单词,就是: NarrowDown

只有不停地对问题进行细分,证明或者排除其他的可能性,才能一步一步到达问题的根源,而不是根据现象如同没头苍蝇一样到处乱撞,能不能解决问题全靠运气……


本文转自holy2009 51CTO博客,原文链接:http://blog.51cto.com/holy2010/311756


相关文章
|
2月前
|
缓存 运维 Linux
Linux系统调优详解(三)——CPU状态查看相关命令
Linux系统调优详解(三)——CPU状态查看相关命令
41 1
|
2月前
|
运维 Linux
Linux系统调优详解(二)——CPU负载查看相关命令
Linux系统调优详解(二)——CPU负载查看相关命令
47 10
|
3月前
|
Linux
|
1月前
|
监控 Java 索引
cpu使用率过高和jvm old占用过高排查过程
cpu使用率过高和jvm old占用过高排查过程
34 2
|
3月前
|
存储 Ruby 内存技术
【机组期末速成】CPU的结构与功能|CPU结构|指令周期概述|指令流水线|中断系统
【机组期末速成】CPU的结构与功能|CPU结构|指令周期概述|指令流水线|中断系统
78 1
|
2月前
|
运维 Linux 调度
Linux系统调优详解(十)——CPU调优
Linux系统调优详解(十)——CPU调优
66 3
|
2月前
|
网络协议 Linux
【系统DFX】如何诊断占用过多 CPU、内存、IO 等的神秘进程?
【系统DFX】如何诊断占用过多 CPU、内存、IO 等的神秘进程?
105 0
|
3月前
|
存储 JSON 运维
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
49 0
|
3月前
|
缓存 Linux
百度搜索:蓝易云【Linux系统中查看CPU信息的方法有哪些?】
这些是在Linux系统中查看CPU信息的常见方法。根据您的需求和具体环境,您可以选择适合您的方法来查看CPU信息。
58 0
|
3月前
|
监控 Java Linux
疯狂飙高!怎么排查CPU导致系统反应缓慢的问题?
疯狂飙高!怎么排查CPU导致系统反应缓慢的问题?