暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一个案例看Oracle的历史故障回放功能是如何碾压其他数据库的… --技术人生系列第三十七期-我和数据中心的故事

中亦安图 2017-09-21
968

如果你的交易在过去的某个时间,突然有几笔交易出现超时了,这种历史故障,要想在其他数据库中查明原因,几乎是不可能的,而原因却是惊人的一致,“已经没有当时出问题瞬间的信息,没办法查呀”。但是在Oracle中,ASH功能可以做到按秒/10秒为单位的故障过程回放,只要掌握适当技巧,核查历史类故障在Oracle数据库中就变得很简单了。这样实用、强大的功能让人欲罢不能,可以说是直接碾压其他数据库。

----中亦科技小y(黄远邦)


猜谜赠书

近期,将有一位高手中的高手加入中亦科技,大家可以猜猜看,会是哪位神秘人物呢?可在留言区留言,点赞数量最多的,获赠一本高质量的Oracle数据库书籍。欢迎踊跃留言哦。另外,北京寻找中级Oracle DBA培养,服务超大型客户,有兴趣的朋友可以发简历到小y的邮箱51994106@qq.com哦。


案例分享前的小广告


不知不觉,技术人生系列(每周四首发)到了三十七期。

期间,很多读者咨询关于Oracle数据库实战培训的事情,于是,我们开始了第一期培训,帮助大家极致地使用数据库,而不是浅尝辄止,同时提升大家的职业价值(money)…

下面是第一期的培训内容和报名方二维码,多多支持哦。

不喜勿喷,不想看广告的可以直接跳到案例章节,“问题来了”



问题来了!

 

11月25日,周五晚上,正在家里看电视,电话响了,是一位银行客户资深DBA的来电,也是我的好朋友、好兄弟,看来,他遇到麻烦了…

远邦,11月20号晚上例行跑批的时候,在1分钟内出现了多笔联机交易超时!当时的CPU不高,内存很富余,没有换页。异常的SQL_ID是15vru8xqgdkjf,就是我们的联机交易会插入的交易报文表,这个表和批量没有关系。最严重的一笔,就是2016-11-20 20:44:04 ~ 20:44:34,时间达到了30秒。这些交易做的事情很简单,就是INSERT INTO VALUES,插入交易报文表。我已经把ASH dump的相关信息发到你邮箱了,尽快帮忙分析下原因吧。需要说明信息可以再找我…”


细心的同学,可能已经从这段话中发现了很多信息:

Ø  举例故障发生已经过去五天了,还可以查么?

Ø  故障只出现了不到1分钟,还可以查么?

Ø  简单的一笔INSERT INTO VALUES 怎么可能需要30秒呢?


在Oracle中,答案是YES!

而帮助我们完成这项核查任务的正是客户提到的ASH dump.

接下来这个case的根因分析,可能会颠覆很多人的运维“经验”,“没想到,这么做,对高并发的系统的影响这么大啊…”,还可能会有很多人生收获哦,我们不妨一起往下看吧。


开启分析之旅


1

ASH科普


打开邮件,不仅只有awr报告、ash报告,

还有一个表ash_1120_2040的dump,即ASH DUMP,真是贴心极了!

 

这个表实际上是dba_hist_active_session_history的备份,该表按照10秒为粒度,记录数据库中活动的会话在执行的SQL和发生的等待,且不会随着重启而丢失。而gv$active_session_history则是按秒采样存储,但因为是存放在内存中,因此会随着重启而丢失,且保存的数量有限.

 

这就是ASH功能,即活动会话历史功能。

举个例子:

假设一个会话正在运行一条SQL语句,从4秒到34秒,总计30

因为ASH功能是按照10秒间隔进行采样,因此,可能在4142434秒总计采集到4次,也可能在51525秒采集到3次(34秒的时候运行结束,因此下一次35秒的采集将没有该会话)


2

ASH初探—活动会话趋势


ash_1120_2040的dump导入电脑后,

立刻发出下列查询,获得按时间分布的活动会话个数的趋势


结果绘制为下图所示



可以看到:

Ø  两个红色竖线之间的30秒左右,正是出现部分联机交易超时的时候。

Ø  但是在出问题前的几分钟,即红色加框部分,活动进程数已经上来了,这个和客户确认了一下,是批量调起来的时间,批量是多个进程并发处理的


3

交易超时期间进程都在等什么

 

接下来,我们发出下列查询,获得交易超时期间的等待事件



结果如下所示:

可以看到,都是和RAC global cache相关的等待,需要说明的是,不懂RAC也不影响对这个case的阅读和理解,小y主要是通过这个case传授给大家核查疑难历史问题的方法和思路,以及不断颠覆自己常识的勇气,才能不断进步。



可以看到:

排在第一位的是gc buffer busy acquire表示数据库集群中的某个节点,如节点1向节点2请求一个BLOCK的时候,节点1已经先有人在我前面申请了同样一个BLOCK,所以连申请都是繁忙的,busy acquire


这个等待说明什么呢?

两个或者两个以上的会话同时申请同一个BLOCK,撞上了。

 

常见原因:

通常和SQL的效率有关,如果SQL效率够高,则无需申请那么多BLOCK,就不会和其他会话撞在一起同时申请一个BLOCK去了。

但在这里,显然不是SQL效率的问题,因为他就是一条简单的INSERT INTO VALUES的语句而已,不存在执行计划不好的问题。

 

显然,在我之前的申请的那个进程,向节点2请求BLOCK的过程中遇到了异常,导致了问题的发生。

 

如果是你,接下来该怎么往下分析呢?


4

根因分析之分析阻塞源头

 

我们做根因分析,常用的手段就是梳理进程之间的关系。找到阻塞的源头后分析他在做什么,为什么比平时要慢很多,导致了问题的发生。

 

分析到了这里,也许有同学会问道,那“我可以查到本节点是哪个会话在我之前申请了BLOCK么?我想去看看排在我前面的会话在经历什么

 

答案是YES!!!

  

ASH中的 blocking_session字段标识了“哪个会话在我之前先行申请了该BLOCK

接下来,我们发出下列查询,找到某一瞬间,正在等gc buffer busy acquire的上百个会话,分别在申请哪些BLOCK(p1/p2),被谁阻塞了(blocking_session)


可以看到,在开始出现问题的时刻,即20:44:04

节点182个会话申请同一个BLOCK在等gc bufferbusy acquire,被节点1 SID3200的会话阻塞了,即节点1 SID3200的会话先于82个进程向节点2请求。



5

很多人倒在了去挖宝藏的路上…


乘胜追击,我们看看节点1SID3200的会话在等什么,被谁阻塞了呢?

如此递归下去,直到我们找到源头,到底是谁在“一夫当关,万夫莫开呢”



结果如下:


可以看到:

异常出现了!节点1 SID3200的会话在请求收到文件号47 BLOCK1540116的时候,无法快速获取,等待事件是gc current blockbusy,并且这次申请从20:44:0420:44:24,持续了20秒以上,但是崩溃的是,没有办法知道谁是我的阻塞者了

 

是的,ash是一座宝藏,但是很多人却倒在了去挖宝藏的路上。

接下来,该怎么往下查呢?到底去往宝藏的路在哪里呢?

 

很抱歉,小y带着大家走了一遍这条死路,现实中,确实有很多朋友在不断重复这条死路,不想继续重复这条死路,想找一个带路人的,来参加我们的通向高手系列培训吧。



6

跟随小y重新出发


其实,作为IT技术人员,我们有时往往在处理问题的时候把问题想的复杂了,太注重技巧了,太注重官方文档的描述,不知不觉中让自己走进了死胡同。最简单的查问题的方法,像说话一样顺着思路往下查就好了,很多问题从官方文档中无法得到答案的时候,其实,生活可以给我们答案。无招胜有招。

----中亦科技小y(黄远邦)


y喜欢化繁为简,既然客户已经提到,有一笔插入报文表的联机交易2016-11-20 20:44:04 ~ 20:44:34,时间达到了30秒。那么我们就从这里开始好了…



结果如下所示

可以看到:

SQL_ID'15vru8xqgdkjf'在ASH中被连续采样到了4次,说明执行时间大于30秒.与客户描述完全一致。然后呢?如果是你,怎么接着往下查,不妨思考几十秒…



7

再一次倒下?



接下来,我们通过sql_exec_idSQL的唯一执行标记,来看看这笔超长交易的情况


结果如下所示:


确实,最长的一笔交易,在04秒到24秒期间,一直在等”gc current retry”

“完了,这个等待事件我没遇到过啊”,好吧,我也没遇到过,如果是你,你会怎么往下查,此处建议停下来几分钟,度娘和googleMOS一下,看看是否可以获得继续往前走的思路呢最后,您是否又倒在了这里呢?请留言告诉小y…

答案就在后面,什么时候往后翻,由你决定。



8

向生活问路,要答案


其实小y也不知道长交易的会话在等的那个人 ”gc current retry”到底是谁,因为“gc current retry”这个人,无论在度娘还是GOOGLE还是METALINK上都找不到任何解释。

这个时候,小y习惯于向生活要答案。

“gc currentretry”,从字面上,看是请求当前BLOCK,但是无法获取,在retry.既然是向节点2请求一个BLOCK,无法获取,需要retry,那么我们有必要查下节点2是谁负责供应这个BLOCK 呢?没错!就是节点2LMS进程!

接下来,我们于情于理,都应该去查下问题期间,LMS进程在做什么

发出下列查询即可


结果如下图所示


可以看到,这些LMS进程在等gcs log flush sync,LMS进程在把一个BLOCK传给其他节点前,需要把这个BLOCKlog buffer中的改变,刷到磁盘中的在线日志文件,但是很可惜,刷了很长时间都没有完成。所以没有办法快速将BLOCK传输给节点1,因此节点1在不断retry.这里” gcs log flush sync”的阻塞者2_2633显然就是我们所熟悉的LGWR进程,即log buffer 的写进程。



9

一马平川


跨过了这道坎,显然,我们就可以一路南下,一马平川了!

接下来,看看节点2LGWR进程是不是在忙其他事,无暇顾及LMS进程的刷日志请求呢?发出下列查询


结果如下所示:


可以看到:

节点2LGWR进程,在等enq: CF-contention,即想要去写控制文件(例如切换日志时需要写控制文件),但是被其他人领先一步,这个人是节点11369会话。期间,LGWR进程傻傻的继续等控制文件的队列锁,但等了几十秒都无法获取。


乘胜追击,发出下列查询,看看节点11369会话为什么长时间持有控制文件的队列锁。


结果如下:


可以看到,sid=1369是节点1ckpt检查点进程

ckpt正在进行控制文件的读写,因此持有控制文件的锁。

期间等待事件是控制文件的顺序度和并行写,并且没有阻塞,而是一直在变化。正常来说,如果IO比较快的话,那么持有控制文件的锁的时间是非常快的


10

根因分析--查IO的来源



进一步检查IO的性能


oswatcher数据可以看到,在问题时段,很多磁盘busy 100%,平均响应时间200多毫秒,IO基本上主要是写,但不是所有盘都100%,例如hdiskpower 11依然是有少量读写的



检查大量写IO的来源


检查ASH中的等待事件



结果如下所示:


可以看到是问题时刻,在等db file parallel write的进程有24个,显然是DBWR进程在等该数据库总计24DBWR进程,全部处于活动状态,说明有什么动作触发了大量刷脏块的操作。


11

真相大白,谁触发了大量脏块的写操作



检查alert日志,可以看到alter system archive log allcurrent)的命令,该命令必然会触发DBWR大量刷脏块,导致磁盘在短时间内极忙,导致HBA卡带宽也可能被占满。

到这里,大家不妨停下思考下,导致是谁执行了这个触发全量检查点的archivelog all(current)命令呢?

不妨思考几十秒…


答案就是我们大家所熟悉的RMAN备份脚本!

要说明的是,真相和你想的不一样!不是备份产生的IO影响了磁盘繁忙!

因为之前我们看到了,磁盘繁忙100%来自于写,而不是来自于读!RMAN主要是读!而且如果是RMAN的读IO影响磁盘繁忙,那么不可能只影响了30秒左右!

因为RMAN脚本开始执行时的alter system archive log allcurrent)的命令触发了DBWR大量刷脏块,导致磁盘很忙,而控制文件和数据文件在一起,导致ckpt进程在拿到控制文件队列锁后,操作很慢,继而阻塞了LGWR进程,LGWR进程于是不响应LMS进程,最后导致了GC等待数十秒,也就是联机交易大量超时。全量检查点完成后,交易恢复正常!

 

怎么再次验证呢alter system archivelog ..的影响呢?

接下来发出下面这条命令来验证下



可以看到, RMAN就是在最初的04秒发起,之后的4334秒往后RMAN进程都还在,但交易已经恢复正常,也就是说RMAN脚本里触发的全量检查点和批量并行写操作产生大量脏块叠加在一起,是问题的原因


为什么以前没事??

经确认,当天备份提前了,和批量重叠了,但不是因为RMAN备份的读IO导致问题,而是因为RMAN备份脚本在最开始执行的alter system archivelog ..命令触发的这次全量检查点和批量并行写操作产生大量脏块叠加在一起,导致30秒左右,检查的INSERT联机交易也出现了超时,这才是问题的真相和问题的根本原因!



12

还没完,你确认这就是问题的真相么?


你确认这就是问题的真相?

欢迎大家踊跃留言,说说你的想法,同时可以加小y微信 shadow-huang-bj,一起加入学习探讨群.我将在下期(技术人生系列)揭晓答案。


问题原因与经验总结


故障原因总结:

l  故障的原因在于批量期间,产生大量脏块

l  ckpt进程持有控制文件的队列锁后,开始进行IO操作

l  但期间rman备份调用alter system archive log的命令,从而触发dbwr进程往数据文件大量的写,导致磁盘100% busy.导致控制文件的IO读写无法快速完成。

l  由于日志切换,因此lgwr进程需要获得控制文件的队列锁,而ckpt进程阻塞了lgwr进程,lgwr进程处于enq: CF contention状态,无法响应LMS进程的日志写情况。LMS进程负责节点间的GC。因此,GC出现问题,INSERT语句出现超时


数据中心运维建议:

Ø  将控制文件和数据文件从底层RAID组就分开,放到其他磁盘组,避免被DBWRIORMANIO影响。

Ø  Rman备份脚本中的alter system archive log all命令会导致数据库做全量检查点,触发DBWR的大量IO操作,期间拖慢整体性能

Ø  重新评估 alter system archive log all的替代方式

Ø  RMAN备份和批量时间错开


这个案例下来,小y希望您至少有如下收获:

Ø  Rman的备份脚本中的altersystem archivelog ..命令居然影响这么大

Ø  术很重要,这是基础!

Ø  道也很重要,他可以让你到达更远的地方

Ø  当技术里没有答案的时候,我们可以问生活,上天不会亏待认真、细心和爱思考的人


听说你很热爱ORACLE技术,听说你错过了首届Oracle欢乐颂技术大会北京站的分享,听说你离上海很近或就在上海,那你不用遗憾,首届Oracle欢乐颂技术大会上海站即将在10月开启,快快来报名吧

更多实战分享和风险提示,请关注“中亦安图”公众号!也可以加小y微信,进微信群探讨技术,shadow-huang-bj喜欢就转发吧,您的转发是我们持续分享的动力!

关注中亦安图公众号,阅读往期文章:

往期回顾

关注公众号,回复数字查看精彩往期!

回复“017”第十七期:技术人生系列·我和数据中心的故事(第十七期)-看中国最美女DBA的一次价值连城的系统优化!

回复“018”第十八期:技术人生系列·我和数据中心的故事(第十八期)-记一条500行执行计划的SQL问题分析-从应急处理到根因分析

回复“019”第十九期:技术人生系列·我和数据中心的故事(第十九期)-通过案例教你识别操作系统重启是否为CRS引起

回复“020”第二十期:技术人生系列·我和数据中心的故事(第二十期)-ORA-01555错误启示录

回复“021”第二十一期:技术人生系列·我和数据中心的故事(第二十一期)-一条错误结果SQL带来的警示

回复“022”第二十二期:技术人生系列·我和数据中心的故事(第二十二期)-通过trace定位oracle统计信息收集带来的问题

回复“023”第二十三期:技术人生系列·我和数据中心的故事(第二十三期)-致敬618-电子商城秒杀活动技术支持历险记

回复“024”第二十四期:技术人生系列·我和数据中心的故事(第二十四期)-一次一波三折的节点重启问题分析

回复“025”第二十五期:技术人生系列·我和数据中心的故事(第二十五期)-老司机遇到的ORACLE 12C安装问题

回复“026”第二十六期:技术人生系列·我和数据中心的故事(第二十六期)-一次数据库升级引发的惊天大案

回复“027”第二十七期:技术人生系列·我和数据中心的故事(第二十七期)-从一个故障案例看强大到令人发紫的Oracle数据库

回复“028”第二十八期:技术人生系列·我和数据中心的故事(第二十八期)-小CASE见大问题之足以摧毁整个应用的数据库设计

回复“029”第二十九期:技术人生系列·我和数据中心的故事(第二十九期)-如何解决程序时快时慢的业界性能难题

回复“030”第三十期:技术人生系列·我和数据中心的故事(第三十期)-一分钟查一个案例带你看看Oracle数据库到底有多牛逼

回复“031”第三十一期:技术人生系列·我和数据中心的故事(第三十一期)-【深度分析】一个你打死都想不到的死锁导致的应用异常

回复“032”第三十二期:技术人生系列·我和数据中心的故事(第三十二期)-看中国最美女DBA又一次奇葩问题的解决

回复“033”第三十三期:技术人生系列·我和数据中心的故事(第三十三期)-变更不重启,就是害自己!

回复“034”第三十四期:技术人生系列·我和数据中心的故事(第三十四期)-一个CASE看ORACLE新特性的本质

回复“035”第三十五期:技术人生系列·我和数据中心的故事(第三十五期)-从天而降的TRACE

回复“036”第三十六期:技术人生系列·我和数据中心的故事(第三十六期)-颠覆传统调优方法的案例分享



文章转载自中亦安图,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论