总结导致oracle数据库主机CPU sys%高的一些原因
今天我分享下简单总结导致 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 ,这部分是有可能来自用户进程的申请而发起的。
本次列举的案例主要还是仅表述了日常的问题现象,而具体的原理仍需学习深究。