最近在工作忙碌之余也帮几位网友查看了几个问题,有一个问题让我印象挺深,其实也可以分享出来作为一些参考,问题之外还是有一些值得借鉴的地方。
首先是在周末的一个晚上,白天已经比较累了,大概在晚上11点左右,就准备收拾收拾睡觉了,但是突然qq闪动起来,有一个网友发消息给我,在反复问我,在不在不?看起来还挺着急。
于是我就带着试探的口吻来问他,他说刚刚做了一个操作,系统现在的负载很高,想让我帮忙看看。
然后他就在qq那头给我焦急的解释,当时听了的大体感觉是他创建了一个索引,但是执行了19分钟还没有反应,现在的系统负载很高,希望我能够给点意见。
当我问系统负载有多高的时候,看到的截图如下:
通过这个看不到系统负载很高,所以我就想他要了最新的ash,awr报告,因为他手头刚好收集了ash报告,所以就直接发给我了。
top等待事件为:
Event | % Event | P1 Value, P2 Value, P3 Value | % Activity | Parameter 1 | Parameter 2 | Parameter 3 |
resmgr:cpu quantum | 67.19 | "3","0","0" | 53.69 | location | | |
| | "2","0","0" | 13.33 | | | |
direct path read | 13.54 | "15","115072","128" | 0.02 | file number | first dba | block cnt |
read by other session | 2.06 | "15","481314","1" | 0.06 | file# | block# | class# |
db file sequential read | 1.11 | "2","114340","1" | 0.00 | file# | block# | blocks |
对于第一个等待事件还真比较陌生,不过ash报告的好处是这些信息得来都不费功夫。top1的sql已经很清楚的说明了这些等待事件的归属。
SQL ID | Planhash | Sampled # of Executions | % Activity | Event | % Event | Top Row Source | % RwSrc | SQL Text |
fjyagwts516j8 | 1886057869 | 204 | 75.71 | resmgr:cpu quantum | 55.01 | TABLE ACCESS - FULL | 55.01 | select o.TRX_AMT as tradeAmoun... |
| | | | direct path read | 12.03 | TABLE ACCESS - FULL | 12.03 | |
| | | | CPU + Wait for CPU | 8.64 | TABLE ACCESS - FULL | 8.64 | |
所以这个问题看起来是由于全表扫描导致的。查看了执行计划,我问他对于这个表的全表扫描,其实可以考虑添加索引来缓解。
他说刚试过了,就是重建了索引,等了19分钟没反应,所以就取消了。
等等,他说的是重建,而不是新建,经过确认,他说是重建索引,相关的一个表是分区表,之前是存在全局索引,后来想改用本地索引,但是删除快,要添加就难了。
而他在等待了19分钟之后还没有任何反应就有些慌了,不知道该怎么办,这是一个线上环境,情况还是比较紧急的。
这个时候我已经不打算早点休息了,于是就准备远程协助,看看更多的问题信息,方便诊断。
这是一套11gR2的rac环境,简单查看了一些系统情况,发现CPU使用率到到了90%以上,iowait都在30%以上,已经是一个比较严重的情况了,而且查看session的使用情况,发现里面竟然有400多个active的session,而大部分的session都在同一条语句上卡住了,就是刚刚看到的sql(sql_id fjyagwts516j8),队友这种情况,一种比较省事的办法就是停掉前端应用,马上创建索引来缓解,查看有些sql语句,执行时间竟然已经达到了1个半小时,而后面还有一大堆的session被阻塞,这个时候来看,情况确实也比较危急,而且rac环境中,两个阶段的iowait都极高,如此下去,很可能导致严重的IO问题,后果不堪设想。
我让他提供了准备的脚本,把需要执行的创建语句发给我,简单评估一下,然后就是尝试重建索引了。
当然这类操作,其实还是有一些技巧可循,本来想尝试index的online,但是发现里面都是大量的读请求,本身使用online还是有一些限制,在正常的情况下创建,发现持续时间要高很多,而这些信息都可以完全通过v$session中绑定对应的sql_id来得到一些信息,如果不加并行,整体的索引创建时间预估是1个小时40分钟,这个效率显然是不可接受的,现在每耽误一些时间,系统的负载和出现故障的概率就会高一些。所以看到了相关的执行计划,还是不能接受,于是简单整理一下思绪,强制开启了会话级的并行ddl,配合查到的执行计划,根据预估需要14分钟,但是我明显感觉会晚一些,因为目前的系统资源还是比较紧俏,所以预估时间可能要长一些,比如20分钟到30分钟的样子。
在得到了这类信息之后,就开始密切关注v$session中的数据变化情况,并行进程确实得到了启用,而且查看执行的情况还是在计划之中,到了14分钟,我安慰他说,目前系统的资源使用率较高,会有适当的延迟,应该会很快完成,需要等待一下。
又过了近10分钟,这个操作才终于顺利的完成了,我心里终于松了一口气,看看表,已经用了近半个小时的时间看问题,看来还是有一些收获。
马上查看v$session中的信息,发现那些持久运行的会话依然存在,对于这种情况和这位网友确认,他还不敢去强制停应用,或者杀掉那些会话,不过从新进入的sql情况可以看出,性能确实是得到了改善,所以我也就安慰他,这个问题已经告一段落,剩下的事情就是等待哪些被卡住的语句顺利执行完了,因为系统负载降低了不少,所以这个过程相对要快一些了。
在简单交代之后就去休息了,在第二天早上向他确认问题情况,他说现在一切都正常了,哪些活跃的会话连接都得到了释放。
对于这个问题,其实如果明白了其中的原委,可以看出其实处理方式还是很肯定的,需要借助索引来大幅度改善性能,但是创建索引还是最好评估一下,如果没有任何的参考,那种大海里捞针的感觉着实不好受,无法评估这个操作的时长和影响范围,在具体实施操作的时候就会心虚很多。但是一旦你明白了问题的边界,就可以很快调整自己的焦躁状态,哪些事情是紧急的需要马上处理,哪些是可能的问题原因需要重点关注,这些准备工作和操作都会一目了然。而对于这个问题的更多启示,就是不要低估任何风险,这位网友说当时看后台也没有多少的session于是就想修正一些索引的情况,没想到画蛇添足了。