从一个故障案例看强大到令人发紫的Oracle数据库--我和数据中心的故事

作为一名混迹数据库江湖十几年的老DBA,当你对关系型数据库的了解越来越深入时,你会发现,Oracle数据库真的是强大到令人发紫!

Oracle数据库的强大,不仅体现在其对ACID的巧妙实现,其对高并发的完美支持,更重要的是他的可管理性,包括可度量、可回溯,以及出现问题后的问题核查接口和问题检查方法论,真是强大到令人发紫,这是其他关系型数据库短期内还无法超越的。

中亦科技小y(黄远邦)

问题引入

电话响了,是某银行一位熟悉的资深DBA的来电。

“小y,现在应用连接数据库会hang住,sysdba登陆也会hang住,无报错,该如何处理?”

没有往日的寒暄和客套,直入主题!

人的声音是有表情的,从电话那头急促的语气,不难判断,客户很着急。可能有些朋友不清楚数据库登录hang住是怎样的一种现象,下图可以脑补一下:

也就是说,正常的登录是可以快速看到“SQL>”这样的提示符的,但出现异常时,就会长时间等不到“SQL>”这样的提示符,这就是所谓的登录数据库会hang住。

看到这里,有些朋友开始激动了,要猜一下原因,试一下身手!

1)是不是数据库归档满了?

答:这…归档满了,sysdba登录会报ORA-归档错误相关的提示!而且注意细节,小y之前提到了,客户是资深的DBA,显然这种可能性早就被排除掉了,注意细节啊

2)查一下等待事件,看看在等什么呢?

答:这…数据库都连不进去了,怎么发出SQL来查询呢…

3)alert日志有什么明显报错么?

答:在这个case中alert日志没有报错,也没有明显问题…

三板斧用完后,接下来不妨思考个两三分钟,如果是你,接下来你要怎么指挥这场战斗…

……

此处留白…

什么时候往下翻,由你决定…

……

一切都是套路

“别着急,你收两个SSD保存现场,然后杀掉pmon,先恢复业务,然后把SSD的trace发我,我来做下RCA!”

客户杀完pmon进程,数据库自动重启后,业务恢复正常。随后将SSD发了过来。

这里有些同学听到这些术语,有些摸不着头脑了:

什么是SSD?固态盘(不会吧)?还有什么是RCA呢?

小y给大家科普一下:

SSD其实就是System State Dump,系统即时状态DUMP的首字母组合,RCA就是Root Cause Analyze,根因分析,是解决问题的难度要大许多,也有意思许多

为什么要收集SSD呢?

因为原因的不确定性,怎么能抓到蝴蝶效应中的那只蝴蝶呢?那就需要足够的信息!小y多年前未掌握SSD这个功能的时候,出现问题,喜欢收集v$session,v$session_wait,v$sqlarea,v$lock等动态性能的相关信息,然后重启,但是后来往下分析的时候,发现少收集了什么信息,导致分析不顺利,后悔莫及…

当时就在想,ORACLE是否有一个一键收集的功能:把想要的,不想要的,全都收集下来呢!答案就是SSD。

甚至是当sysdba无法登陆时,Oracle依然可以直接attach到共享内存,将内存中的即时状态全部抓取下来,包括系统当前各个进程正在执行什么、正在等什么、进城的堆栈等信息,真是强大大令人发紫的一个功能。

SSD的收集非常简单,照敲就是了,以下是SSD收集的命令

### sqlplus -prelim "/as sysdba"SQL>oradebug setmypidSQL>oradebug dump systamstate 266SQL>--等上30秒到1分钟SQL>oradebug dump systamstate 266SQL>oradebug tracefile_name

小y接下来就带领大家一起去分析SSD,做根因分析,你会发现工作是一件多么有趣的事情。

开启分析之旅

1.查看登陆进程在等什么

从xxdb_ora_33030248.trc中搜索"waiting for"可以看到:

可以看到:

1) 有N个进程都在等latch:librarycache,latch,并且latch是同一个即70000006b9d8008

2)1个进程在等cursor:pin X,即在等待cursor类型的mutex

3)latch等待的时间已经长达达到3723秒

这里不难看出:由于登陆的时候,要执行包括验证用户、获取权限等内部的SQL(递归SQL),但是在发出SQL后,由于长时间无法获取latch:library cache这样的资源,因此登陆看上去就像hang住了一样…接下来,我们只需要找到无法latch:library cache的原因,就可以解开数据库hang住的真相了!

2.第一次头脑风暴

看到这里,也许有同学迫不及待地又想再试试身手:

是不是硬解析的问题?

可以看到:

当客户端发出的SQL到达数据库的服务进程后,要先在shared pool中去找内存中是否存在该SQL和执行计划,如果存在则拿到执行计划直接执行即可。

那么oracle是如何查找的呢?就是对SQL文本计算hash值后,获取latch:library cache(11g中则采用mutex代替),对对应的链表进行扫描即可。

因此,软解析也会申请该latch。

所以,不能说是简单的硬解析的问题,一切都有可能!

BTW, 小y面试过很多人,其实更像看到的是分析问题的方法论,而不是使劲的猜…

为什么呢?我们总会遇到很多经验范围之外的事情,怎么可能猜出自己不知道的事情呢?

3.找原因,Orale就是这么简单!

既然长时间无法获取latch,那么是谁在持有latch呢?

需要说明的是,当无法获取latch:library cache的时候,Oracle在实现上,会将自己放到latch的等待着列表waiter list当中,那么自然也就有一个对应的持有者列表,这么做的原因在于,当持有者使用完该latch后,到等待者列表中唤醒等待的进程即可。同时,Oracle在做SSD的时候,就已经把持有者给打印到trace里了。

搜索 "waiting for 70000006b9d8008 Childlibrary"

可以看到“possible holder pid = 19ospid=10027060”,即持有者是pid = 19 ospid=10027060

接下来,我们需要去看看latch持有者即pid = 19 ospid=10027060的进程在做什么

4.持有latch的人去哪了?

搜索“ospid:10027060”,就可以看到LATCH持有者的进程的详细信息了

包括进程名,在执行什么SQL,进程状态是什么,在等什么资源…

可以看到:

Pid=19,spid=10027060的进程,是ORACLE的一个JOB SLVAE进程j001,

由于他在持有latch,导致了很多进程需要等待,

holding (efd=5) 70000006b9d8008 Child library cache

乘胜追击,进一步查看该进程在等什么资源:

可以看到:

该进程对应的SID是534,当前实际上并没有在等待任何资源,因为last wait表示的是上一次的等待了。长时间持有latch:library cache,导致N个进程登陆执行内部SQL的时候无法获取latch,继而无法登陆,但是,进程持有者PID=19,SID=534,又没有在等待任何资源,SQL:0表示当前没有在执行任何SQL。

生无可恋了,那我怎么知道进程持有者在做什么呢,这还怎么往下查呢…

提示:这里请记住latch的持有者,SID是534,534!

5.【陷入僵局】

还记得么,Oracle有一套方法论,那么方法论就是查看call stack,通过查看进程调用的函数轨迹,就可以判断出来,当前进入了哪一种场景。

但是由于客户一着急,收集的SSD的level不够,因为没有打印每个进程的call stack!

这可如何是好啊,难道问题要陷入僵局..

如果是你,接下来,会怎么往下打这一场仗

……

此处留白…

什么时候往下翻,由你决定…

……

6.心都给你了【细节决定成败】

如图所示:

红色加框部分显示,该进程的状态处于DEAD状态!即持有latch的那个进程已经死掉了!

看到这里:

有些朋友又要蒙圈了,“这是什么情况?”

有些朋友可能已经开始有点想法了,心里在嘿嘿乐…

没错,实际上,这已经设计到道和术的问题。

技术层面上,一路找到最终的阻塞者后,已经进行不下去了!

接下来,大家不妨停下来,思考一下:

原理层面呢?

学了那么多体系架构的东西,怎么用到生产问题中呢?

是否可以运用原理帮助解开这个数据库挂起的问题呢?

我面试候选DBA的时候,喜欢问原理。

很多候选DBA答不上来的时候,总喜欢解释道,而且是很坦然的解释到:

不好意思,过去从来不关注原理,熟练操作就可以了!

听到这些回答,小y总会语重心长的让对方做一道故障题,不掌握原理是不可能解开的,结果很显然的,候选人自然答不上来,之后我会演示问题处理和分析过程,候选人往往都会重新定义对道和术的认知,孺子可教...

工程师熟练操作是基础,,但是从中级工程师到高级工程师,再到资深工程师,深入原理是一道坎,能将原理熟练应用到实际分析中又是一道坎。什么时候跨过坎了,层次也就不一样了。很多DBA因为没有人点拨,可能永远过不了那道坎…

……

此处留白…

什么时候往下翻,由你决定…

……

7.振聋发聩的一问!

为什么进程死掉了,但是进程还在持有latch资源不释放?PMON做什么去了?他是干什么吃的…

是的!这就是问题的关键!当听到这么一个振聋发聩的惊天一问时,恭喜你,跨过了一道坎!

如果已经提示到这个程度,依然无法发出这么一个疑问,可以找小y给培训一下了!

8.看看PMON在做什么

搜索(PMON),就可以找到SSD中PMON进程的相关信息。如下所示:

可以看到:

PMON正在等待cursor:pin x,即申请模式为独占,类型为cursor的mutex

waiting for 'cursor: pin X'

该mutux的IDN是 idn=ad39e34,即hash值

由于PMON被阻塞,卡住了,因此自然没有机会去清理死去进程所持有的LATCH了!

我们继续真相又进了一步!

只需要集中精力,需要继续到底是是哪个进程,持有了idn=ad39e34的mutex,导致PMON被长时间阻塞了,就可以解开问题的真相了!

接下来,大家不妨停下来,思考一下:

上图中,但是BLOCKING_SESS=0X0,这里无法直接查看是谁阻塞了PMON进程。

那么如果是你,你会怎么往下查呢

……

此处留白…

什么时候往下翻,由你决定…

……

9.谁阻塞了PMON【还是套路】

由于PMON进程以独占方式申请

类型为cursor的mutex被阻塞,显然该MUTEX正在被某个进程以独享或独占方式长时间持有。这显然是不正常的。毕竟MUTEX是一种轻量级的资源。

接下来,我们在TRACE中搜索"idn ad39e34 oper",结果如下所示

Mutex 70000003eec4be0(534, 0) idn ad39e34 oper GET_EXCL Mutex 70000003eec4be0(534, 0) idn ad39e34 oper EXCL

可以看到:

该MUTEX上有两个操作,OPER即Operation,操作。

一个进程正在以独占方式持有,即oper EXCL

另外一个进程正以独占方式申请,oper GET_EXCL,Get表示申请, 因此发生阻塞。该进程就是PMON进程。

红色底纹部分的534,就表示MUTEX的持有者,即SID=534!

没错!SID=534就是我们之前持有latch:library cache资源但已经死去的进程!

就是哪个等着被PMON清理的死去的进程!

10.没看错吧【毁三观】

综合上述分析,总结如下:

1) N个进程无法登陆,是因为无法获得latch:library cache资源,该资源被一个死去的SID=534的进程持有了, 还没释放!

2) 按照原理,PMON有义务去清理死去的SID=534的进程所持有的资源(latch等).

3) 但是PMON只有一个,PMON正在等'cursor:pin X',即以独占方式申请类型为cursor的mutex.所以腾不出手来清理死去的SID=534的进程.

4) 正是SID=534持有MUTEX,阻塞了PMON !

假设说步骤1,2还合理的话,但是步骤3和4就毁三观了!

总结起来就一句话,PMON要去给死去的进程收尸,但是要获得死去进程的同意!

这太不合理,太不科学了!为什么会这样呢…

很简单,命中BUG!

11. 轻松找BUG

分析到这里,掌握了问题的本质,那么找BUG起来就很简单了!

ORACLE有一个强大的知识库,记录了全球客户提交过的CASE,里面包含了BUG库!

怎么找到具体的BUG呢?

接下来不妨思考个1分钟,如果是你,接下来你要怎么定搜索关键字呢…

……

此处留白…

什么时候往下翻,由你决定…

……

这里,小y以“pmon cursor dead”做为关键字(其他关键字也可以),检索BUG。

很快,一个BUG的标题引起了注意:

Bug 8426816 PMON may hang cleaning up a dead process (rare)

点开BUG,描述如下:

怎么样,看完了吧,这不就是我们这个问题么!

an instance hang may result due to PMON getting

blocked when attempting to clean up a failed process.

从现象到问题本质完全吻合!版本10.2.0.4也完全吻合!

当PMON要以X模式即独占模式申请MUTEX(cursor:pin X就是一种mutex)去清理一个死去进程的时候,该MUTEX被死去进程持有!从而导致了数据库HANG的情况!

问题原因与经验总结

故障过程总结:

1) SID=534的进程在持有latch:library cache和mutex等资源的时候进程死去

2) PMON有义务清理该进程所持有的资源,如mutex

3) 由于命中BUG 5377099 ,导致PMON无法获得MUTEX,被死去的进程534阻塞

4) 因此SID=534的死去进程长时间持有latch:library cache,导致其他用户执行递归SQL,无法被软解析,继而无法登陆,即数据库出现了HANG的故障!

经验总结:

1) 运维公式=快速收集系统即时状态信息+恢复业务

2) 快速收集系统即时状态信息的目的是做RCA,根因分析,以便在大规模数据库运维中可以预防其他数据库也出现类似问题。

3) 不定期做补丁分析,发现严重的BUG,提前预防。

4)技巧重要,原理更重要。

5) 要查问题或者培训,找小y私聊

通过这样一个案例,你不难发现,ORACLE的SSD功能,真是强大到令人发紫!

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2017-07-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏林冠宏的技术文章

浅析 <路印协议--Loopring> 及整体分析 Relay 源码

1123
来自专栏人人都是极客

开源飞控StarryPilot无人机的制作

近年来无人机应用市场日趋火热,无人机开始被应用在多个领域之中,比如航拍,植保,运输,安防等。随着应用场景的增加,对于无人机的大脑一飞控,的性能和功能要求也变得越...

551
来自专栏杨建荣的学习笔记

最近让我焦灼的四个问题(有解) (r7笔记第76天)

之前写了一篇 《最近让我焦灼的四个问题》,既是感慨,也是无奈,既是记录问题,也是鞭策自己,当然只是吐槽,抱怨是没有任何意义的,所以我更新第二篇,这些问题在近些天...

3506
来自专栏康怀帅的专栏

Mac OS X 背后的故事(下)

Mac OS X 背后的故事(九)半导体的丰收 半导体的丰收(上)   在美国宾夕法尼亚州的东部,有一个风景秀美的城市叫费城。在这个城市诞生了一系列改变世界的奇...

3807
来自专栏安富莱嵌入式技术分享

【RL-TCPnet网络教程】第29章 NTP网络时间协议基础知识

本章节为大家讲解NTP (Network Time Protocol,网络时间协议)和SNTP(简单网络时间协议,Simple Network Time Pro...

873
来自专栏Jerry的SAP技术分享

阿里云上到底能运行SAP哪些产品?

本文主要内容大部分来源于SAP已经发布的note:

1895
来自专栏杨建荣的学习笔记

我身边的一些数据库事故 (r5笔记第52天)

最近携程的数据事故闹得沸沸扬扬,不管是什么原因,问题终究发生了。在问题发生的时候,更关键的是解决方法和防范措施,一般在升级或者重大的生产演练中,我们都有一个le...

35810
来自专栏张善友的专栏

如何有效监控.NET 应用程序

     当你的.NET应用出现性能问题的时候能很快得找到问题的症结吗? 这是一个运营的企业应用所必需考虑的问题,最近工作中碰到很多这方面的问题,运行中的系统完...

1897
来自专栏酷玩时刻

支付宝支付-常用支付API详解(查询、退款、提现等)

Maven项目引用JAR包可以参考 支付宝Wap支付你了解多少? 里面有详细的介绍

1242
来自专栏SAP最佳业务实践

SAP S/4HANA最佳业务实践:Order-to-Cash订单到收款-2客户360度视图

Details of the Object Page Customer -360°View客户360度视图 –Header 概览 –Contacts 合同 –S...

25611

扫码关注云+社区