love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

Oracle instance hung due to gc buffer busy acquire/gc current request

一客户某系统反馈在上周深夜出现严重性能问题,整个系统出现了短暂hung,导致无法使用。通过用户提供的awr元数据,这里做了简单分析:

从上面的查询接过来有如下几个疑点:

1、节点1实例从23:27:59开始突然出现大量gc等待,以及enq: SQ – contention,包括buffer busy waits等。

2、23:23 — 23:27:59之间,节点1 无任何相关等待记录

3、用户反馈的日志切换无法完成即log file switch(checkpoint incomplete)在节点2的上是突然出现的,时间点是23:30:25

4、节点2在23:30之前到23:23分之间这7分钟,没有任何性能数据记录。

从上述等待的情况和规律,我们可以大致得到如下几个基本结论:

log file switch等待属于叠加现象,并非根本原因,因为在此之前系统已经运行极为缓慢了,其次节点1在27分突然出现大量gc等待,可排除SQL本身性能影响,如执行计划突然改变导致性能变差,进而产生大量gc,引发该问题。尽管如此,这里我仍然查了一下gc top SQL:

对于上述几个top SQL的 gc等待,让客户查询了相关执行计划,plan hash value并没有改变过,跟ash数据表现一致。

到这里就比较有意思了,既然并非SQL本身性能问题,为什么会突然出现400个gc 等待呢?(因为如果是SQL性能问题,通常是逐步叠加等待,并非突然一下就会涌现400个出来)。

分析到这里,我们认为有几个可能性:

1、在23:27分这个时间点,集群心跳有问题,导致gc 操作受到较大影响

2、数据库实例节点1,或者节点2 在23:27:59之前出现了异常,比如核心进程hung,实例hung,挂起等状态,进而影响数据库gc

3、数据库实例1,或者实例2 在23:27:59之前cpu资源异常,如系统cpu 100%等情况,导致lgwr,lms等进程无法获取cpu资源,进而导致该问题。

对于第一个可能性,让客户检查了zabbix监控,并没有发现异常,只是从监控来看,心跳流量较高,高峰期维持在60-70Mb/s,对于比较老旧的小型机环境来讲,相对有一些偏高,但还不不足以产生这么大的影响。

同样监控也发现cpu 资源相对是正常的,因此我们可以排除第1,3 两种可能性原因。

带着这种疑问和猜测,远程了客户环境,检查了节点2 trace目录,发现在当天晚上确实产生了一个diag dump,找了如下内容:

可以看到在23:25:09分,显示节点2 的Session 4510 会话出于hang的状态。那么该会话是什么呢?

Blocking Sid (Inst) % Activity Event Caused % Event User Program # Samples Active XIDs
4510, 1( 2) 57.91 log file switch (checkpoint incomplete) 54.11 SYS oracle@fdcdb2 (LGWR) 41/120 [ 34%] 0
log file sync 3.77
6953, 707( 2) 2.19 enq: SQ – contention 2.19 FDCMGR JDBC Thin Client 7/120 [ 6%] 0
3771,39737( 2) 1.71 buffer busy waits 1.71 FDCMGR JDBC Thin Client 7/120 [ 6%] 0

从ASH 报告我们可以得知4510 session 就是我们的LGWR 进程。可见在23:25:09  节点2 lgwr进程就出现了异常。

那么这就能解释通了。。。

我们继续带着疑问分析这个问题,因为过一段时间就自动恢复了,我始终怀疑是应用可能有些不正常,因此让客户检查了之前提到的2个TOP gc 等待的SQL,发现该sql在最近一周的执行计划,分别是13号,16号,18号。 其中这3个时间点都是业务出问题的时间点。唯一不同的是:

13号sql执行次数是9w次,16号是15w次,18号是17w次。根据用户的反馈,13号和16号也出现了类似问题,但是影响要比18号要小,尤其是13号,影响比较短暂。

结合实际情况和现象来看,我认为问题本身还是出现了这个业务模块上,可能是非固定时间执行,当业务量过大时,进而产生了大量gc,最终出现了该问题;实际上从统计来看,随着执行次数增加,sql的单次平均执行时间逐渐拉长。

最后,不得不说,对于这个比较大型的业务系统来讲,单个节点Session在3800-4000左右,每秒redo 在30M/s(单节点).  这么古老的小型机改换了。。。。

本以为故事即将终结,今天客户反馈早上又出现了该问题,虽然影响不大,仍然需要再次分析,从用户提供的diag trace文件来看,跟之前的问题看上去有一些不同:

从hung 分析结果来看,所有会话几乎均被lgwr进程阻塞,被阻塞会话超过1200个。其中lgwr在等待control file sequential read。似乎有一些奇怪?

由于是同一个trace文件,可以看到上次问题也就18号故障时间点的情况:

可以看到lgwr进程(session 4510) 也是在等待control file sequential read或者就是not in wait。可见本质上这几次问题是一样的。

此时怀疑检查点方面可能出现了问题,导致长时间没有触发,进一步分析之前的awr发现部分数据确实有一些异常:

其中physical writes from cache  – physical writes not checkpoint 的部分就是Oracle 增量检查点触发的dbwr physical writes操作。由此可见,增量检查点触发的写比例非常低,也该也就15%。 换句话讲其他85%可能就是db cache自身写脏等操作触发的。

Oracle从 8i引入了增量检查点,10g 版本引入了自动调节增量检查点机制,主要有如下几个相关参数:

Oracle 10g版本开始,默认启用了增量检查点自动调节机制。除了上述跟dbwr写相关的参数之外,还有跟redo log size相关的参数:

该参数在11.2版本中默认值为81%,在10g版本中为90%。 该参数大致意思指最大限制情况下,当所有redo log大小写满到其81%的情况下才触发检查点。从mos上文章也看到了一些描述,某些特定情况下增量检查点机制是有待完善的,与cpu_count,log_buffer大小,redo log size,以及mttr有关。

对于用户这个问题,我们建议用户通过如下2个方式调整之后进行观察:

1、log_buffer 调整为300m

2、fast_start_mttr_target 设置为600秒

 

Leave a Reply

You must be logged in to post a comment.