CPU飙升!故障分析解决过程详解

记一次CPU飙升的分析处理过程,聊聊我的思路。技术人人都可以磨炼,但处理问题的思路和角度各有不同,希望这篇文章可以抛砖引玉。

以一个例子为切入点


一、问题背景

一大早接到告警,核心数据库RAC两主机CPU使用很高,90%以上,系统操作缓慢,业务卡顿。需要马上紧急处理,排查一下具体原因,消除潜在隐患。

基础环境:

  • 主机类型:x3850 X6
  • 操作系统:DB:CentOS Linux release 7.4.1708、APP:CentOS Linux release 7.2.1511 (Core)
  • 存储:IBM存储,2TB,MULTIPATH
  • 内存:64 G
  • CPU型号:E7-4830 v3 @ 2.10GHz ( 4 U * 12 core)
  • CPU核数:32CORE
  • 数据库环境:11.2.0.4(RAC)

问题现象:

服务器CPU使用率90%以上,业务卡顿。

简单说明:

CPU使用高一般有以下几种原因?

  • 排序、SQL解析、执行计划突变、全表扫描、会话阻塞等都会导致CPU飙升,可能的原因较多,需要层层递进,逐步定位根因;

分析方法包括哪些:

  • 主要由主机top/topas占CPU高的进程查询相应SQL、会话增长趋势、阻塞分析、ASH/AWR报告分析、SQL执行时间/执行计划变化等;
  • 了解业务场景,业务上有没有变更,例如开发功能变更、业务使用量增加等。

在很多应用场景中,数据库的稳定性直接决定了系统的稳定性。本文介绍一些通用的数据库问题处理技巧,健壮的数据库不能解决所有的问题,但是却能增加数据库运行的稳定性。

二、分析说明

  • 通过分析日志定位、分析故障原因;
  • 追溯历史数据,分析关键指标的历史波动,这些关键指标可以用来做为数据库健康度参考指标。
  • 用实际数据来验证推断,排除掉其它干扰因素,定位数据库问题的根本原因,帮助快速修复。


三、疑问点排查及分析思路

1、主机top信息

可以通过top命令看一下单一进程使用CPU的情况,有CPU使用高的可以通过pid定位sid最终定位sql_id。
本次通过主机top信息看到进程使用CPU都很平均,无法直接定位是某个进程某个SQL引起的CPU使用过高的问题。

2、查询CPU top10的语句

结合AWR信息:


可以看到,故障时段,853by1q5drtc2语句占用最大的CPU时间和逻辑读,接下去就是怎么优化这个SQL的问题。

2、sql信息

执行计划:


历史执行计划:


可以看到执行计划产生了不合理的变化,执行时间差异很大,这是CPU占用过大的根本原因。

3、执行计划为什么会改变?

表统计信息失效了?

表统计信息确实失效了。

ORACLE是根据数据改变量大于10%才进行统计信息的收集,且对静态表并不收集统计信息。至此,CPU使用率高的问题得到了最终解决,最终是由于统计信息没有正确收集导致的,

定位了问题,解决就很容易了,更新表统计信息后执行sql看一下效率及执行计划都恢复正常。本次是表统计失效导致的执行计划改变,如果不是因为统计信息失效导致的,可以采用的优化方案包括不限于修改SQL、指定HINT的方式修正执行计划,实在无法修改SQL的再使用SPM或SQLPROFILE进行绑定等。

4、关于统计信息收集

1)当系统有很大的分区表时,如果总是全部收集则会比较慢,11g之后可以设置INCREMENTAL只对数据有变动的分区做收集,如下示:

exec dbms_stats.set_table_prefs('JD','IMS_RES_MONITOR_2','INCREMENTAL','TRUE');exec dbms_stats.set_table_prefs(user,'table_name','INCREMENTAL','TRUE'); --只收集数据变动的分区select dbms_stats.get_prefs('INCREMENTAL',null,'table_name') from dual;  --查看分区表INCREMENTAL的值

2)延长自动统计信息收集时间

自动收集统计信息的时间是周一到周五每晚22:00:00到第二天2:00结束,周六周日两天全天收集。可进一步考虑工作日时段延长2小时,即周一到周五时段统计信息收集到第二天4:00结束。

四、结论总结

本次故障就是一次统计信息失真导致SQL执行计划走错的简单案例,但有时往往入手的思路错了,导致中间分析的道路过于曲折,在实践中,针对故障和问题需要充分考虑多个可能性,以求一击中的。

– END –
更多精彩内容,关注我们▼▼

为您推荐

发表评论

您的电子邮箱地址不会被公开。