今天我分享下简单总结导致oracle数据库主机CPU sys%高的一些原因。

在日常的数据库运维中,操作系统CPU 使用率一直是我们衡量系统负载的一个比较贴切的指标,例如USER%可以更好的反馈数据库对CPU的使用情况,进而我们再次去数据库中找出导致CPU消耗高的源头,wa%可以反馈IO等待消耗的CPU时间百分比,当wa的值高时,可以说明IO等待比较严重。

然而,当CPU SYS%异常增高的时候,我们都知道是系统内核消耗了大量的cpu,但常常是束手无措。在NGBOSS的数据库运维中,我们把CPU SYS%高的问题抛给了主机侧,而主机工程师的回复便是CPU sys%高是因为ORACLE用户进程导致,这往往使问题排查无法继续进行,因此我稍微总结下目前所遇到几点sys cpu突然增高原因。

从time 命令说起:

有时,我们使用time 命令去测试执行某一个命令或某个脚本所消耗的时间,例如,time ps:

可以看到其中的时间,分为real,user和sys,其中的user和sys 便是指的是CPU 时间,从IBM的Performance and System Tuning文档中看到了关于time解释,其中对于user和sys的解释如下:

CPU时间分为user和sys组成。 User值是程序本身以及任何其调用的库的子程序所使用的时间。 sys值是系统调用使用的时间由程序调用(直接或间接)。

那么SYS部分的CPU主要会由哪些操作或是系统调用产生呢?以下列出了日常运维中相对典型的案例现象以及借鉴他人文章的几点总结。

1> 大量的登录连接

例如短时间的连接风暴的情况,大量的登录需要新启动进程导致CPU SYS 飙高,

监听创建新会话要分配进程的,这部分由CPU sys 承担。

实验:以下是在虚拟机测试的使用脚本模拟多次登录,随着PROCESS的增加,cpu sys%出现较大波动。

从上面实验可以看到,随着登陆会话的持续增多,sys的上涨幅度较大,在我们的日常运维中假如遇到短时间内sys cpu 飙高的现象,建议尽快排查是否存在大量的连接涌进。

2> 大量并发的I/O操作。

一般I/O操作不会消耗太多的CPU,因为主要的时间消耗会在I/O操作的设备上。比如从磁盘读文件时,主要的时间在磁盘内部的操作上,而消耗的CPU时间只占I/O操作响应时间的一少部分。但在大量的并发的I/O时才可能会使得SYS CPU 有所增加。

案例:RMDB1出现sys cpu持续增长到50%以上

10月20日下午16点左右发现RMDB1主机cpu 异常,其中sys 增长到50%以上。

查看当时的磁盘情况发现DISK28、27、20、21四块盘异常繁忙,磁盘读特别高,每块盘的每秒平均达350M左右。

从数据库中查其盘主要是MD库,这是个业务量较小的库,与crm同在一台主机上。

查询MD库等待事件发现主要存在direct path read 等待,这也正是磁盘繁忙的原因。

后来确定主要是以下sql 引起,杀除掉正在执行的sql会话,固定走错的执行计划之后数据库direct path read 等待消失,繁忙的4块磁盘也回归正常,cpu sys 也下降到正常范围。

3> GC 引起的 sys cpu 高

 GC是rac中节点的缓存共享,对CPU的要求貌似非常高,在日常的运维中,总是发现RAC中一旦某个节点出现性能问题,很容易引起另一节点出现大量的GC等待,GC主要是对内存中的操作。例如gc cr multiblock request,一般情况下都是全表扫描或全索引扫描导致, gc cr multiblock request 会造成CPU 对内存的调度和管理,会消耗CPU 时间。

案例:节点1因高消耗SQL引起gc buffer busy acquire 导致CPU sys 高

9月29日11点左右的CPU sys异常增高,分析当时的等待,log file sysnc,gc buffer busy acquire和latch free的等待都很高,但是其中log file sysnc和latch free怀疑是因cpu资源紧张引起。

而gc buffer busy acquire很明显指向了异常的语句:

查询语句当时执行情况,其一次执行时间在60到120秒不等,其中CPU时间在10到20秒不等,这说明语句在执行时,有80%的时间用于等待上,但是语句没有产生物理读取,结合会话的等待事件,我们可以知道80%的时间都消耗在了GC的相关等待上(GC相关等待会导致CPU sys使用偏高)。

从awr中Segments by Global Cache Buffer Busy可以看到,表CS_REC_RECEPTION上Global Cache Buffer Busy占数据库总的86%。这再次证明了系统的GC等待事件确实是有表xxxxx上的业务语句导致。

最终发现业务表在两个都有运行,包括查询和和DML语句,因此引起了较多的gc buffer busy acquire等待。以上分析过程是ORACLE原厂工程师给出,并推断CPU sys 飙高的原因就是因为GC等待。在9月29日当天开发商规避掉该sql之后情况确实好转,但关于GC等待造成CPU sys 异常增高的案例很难找到进一步佐证,并且在平时遇到gc等待高时cpu sys并不也一定异常高,并且在之后同一节点仍出现过CPU sys异常的问题,每次伴随着大量的I/O操作,怀疑导致高数据库CPU sys异常的原因有多种。

除了以上原因还有以下操作系统本身的管理机制导致的原因:

4>进程调度。

这部分CPU的使用,在于操作系统中运行队列的长短,越长的运行队列(run queue),表明越多的进程需要调度,那么内核的负担就越高,但是很多时候往往我们看到的运行队列高很可能是由于CPU利用率高导致的结果。

5> 内存管理。

比如应用程序向操作系统申请内存,操作系统维护系统可用内存等。与ORACLE类似,越大的内存,越频繁的内存管理操作,CPU的消耗会越高。

6> 其他,包括进程间通信、信号量处理、设备驱动程序内部的一些活动等等。

总结来说,CPU利用率中的SYS部分,指的是操作系统内核(Kernel)使用的CPU部分,也就是运行在内核态的代码所消耗的CPU,最常见的就是系统调用(SYS CALL)时消耗的CPU,这部分是有可能来自用户进程的申请而发起的。

本次列举的案例主要还是仅表述了日常的问题现象,而具体的原理仍需学习深究。