【新书连载】DRM引发RAC的故障分析

编辑说明:《Oracle性能优化与诊断案例精选》出版以来,收到很多读者的来信和评论,我们会通过连载的形式将书中内容公布出来,希望书中内容能够帮助到更多的读者朋友们。

在2015年1月13日凌晨3:44左右,某客户的一套集群数据库的节点1出现crash。检查该节点的告警日志,我们发现了如下内容。

从上述的告警日志来看,在凌晨3:44:43时间点,节点1的LMON进程出现异常被终止,抛出ORA-00481错误。接着节点1的数据库实例被强行终止。

对于Oracle RAC 数据库故障,我们在进行分析时,首先要对OracleRAC的一些核心进程原理有所了解才行,这样才能深入本质

深入原理

这里我们简单描述Oracle RAC的几个核心进程的基本原理,例如LMON、LMS和LMD等。

Oracle 的LMON进程,其作用主要是监控RAC的GES(Global Enqueue Service)信息。当然其作用不仅仅局限于此,还负责检查集群中各个Node的健康情况。当有节点出现故障的时候,LMON进程负责进行reconfig以及GRD(globalresource Directory)的恢复等。

我们知道RAC的脑裂机制,如果IO fencing是Oracle本身来完成,也就是说由Clusterware来完成。那么当LMON进程检查到实例级别出现脑裂时,会通知Clusterware来进行脑裂操作,当然LMON进程其并不会等待Clusterware的处理结果。当等待超过一定时间,LMON进程会自动触发IMR(instance membership recovery),这实际上也就是我们所说的Instance membership reconfig

既然提到LMON进程的检测机制,那么LMON如何去检查集群中每个节点的健康状态呢?其中主要分为如下几种。

(1)网络心跳(主要是通过ping进行检测)。

(2)控制文件磁盘心跳,其实就是每个节点的CKPT进程每三秒更新一次控制文件的机制。

Oracle RAC核心进程LMD主要负责处理全局缓存服务(保持块缓冲区在实例间一致)处理锁管理器服务请求。它向一个队列发出资源请求,这个队列由LMS进程处理。同时LMD 还负责处理全局死锁的检测、解析,并监视全局环境中的锁超时(这就是为什么我们经常看到数据库alert log中LMD进程发现全局死锁的原因)。

如果是Oracle11gR2 rac环境,那么还存在一个新的核心进程,即LMBH进程。该进程是Oracle 11R2版本引入的一个进程,该进程的主要作用是负责监控LMD、LMON、LCK和LMS等核心进程,防止这些Oracle核心后台进程spin(stuck)或被阻塞。该进程会定时地将监控的信息打印输出在相应的trace文件中,便于我们进行诊断。这也是11gR2一个亮点。

当LMBH进程发现其他核心进程出现异常时,会尝试发起一些kill动作。如果一定时间内仍然无法解决,那么将触发保护,将实例强行终止掉,当然这是为了保证RAC节点数据的完整性和一致性。

结合案例分析

从上述的日志分析,我们可以看出,节点1实例是被LMON进程强行终止的,而LMON进程由于本身出现异常才采取了这样的措施。那么节点1的LMON进程为什么会出现异常呢?

通过分析节点1数据库实例LMON进程的trace 内容,我们可以看到如下内容。

从上面LMON进程的trace信息来看,LMON进程检测到了DRM在进行sync同步时出现了timeout,最后LMON强制退出了。

既然如此,那么我们应该继续分析为什么DRM会出现timeout。另外根据前面讲述的原理,Oracle DRM的操作主要进程是LMD进程来完成,那么我们来分析节点1实例的LMD进程的trace内容,是否能看出蛛丝马迹。

我们可以看到,当LMON进程遭遇ORA-00481错误之后,LMD进程也被强制abort终止掉了。从LMD 进程的trace文件来看,出现了tickets 等待超时的情况,而且日志中Oracle也告诉我们,在该故障时间点,系统负载并不高。

从上述内容来看,我们似乎并没有得到十分有价值信息。由于LMON进程被强制终止掉之前,触发了一个process dump,因此我们进一步来分析进程dump,继续寻找蛛丝马迹。

LMD进程的processstate dmp 似乎也没有太多有价值的内容。不过我们至少可以肯定的是,系统的资源使用很正常

通过上述的分析,我们可以看到ORA-00481错误的产生是关键,而这个错误是LMON进程产生的。ORA-00481错误在Oracle MOS文档(1950963.1)中有非常详细的描述,针对本文DRM操作没有结束的情况,一般有如下2种原因。

(1)实例无法获得LE(Lock Elements)锁。 (2)tickets不足。

根据文档描述,我们从数据库两个节点的LMS进程trace中没有发现如下的类似关键信息。

Start affinity expansion for pkey 81885.0 Expand failed: pkey 81885.0, 229 shadows traversed,153 replayed 1 retries

因此,我们可以排除第一种可能性。我们从LMD进程的trace文件中可以看到如下类似信息。

这里的tkt total 表示目前数据库实例总的tickets数据为1000,当前可用的tickets为743. 因此我们可以排除ticket不足的导致DRM没有完成的情况。

换句话讲,上述ORA-00481错误的产生,本身并不是Oracle RAC的配置问题导致。对于LMON进程检查到DRM操作出现超时,最后导致实例崩溃。超时的原因通常有如下几种。

  1. 操作系统Load极高,例如CPU极度繁忙,导致进程无法获得CPU资源。
  2. 进程本身处理异常,比如进程挂起。
  3. 网络问题,比如数据库节点之间通信出现异常。
  4. Oracle DRM Bug。

从上面的信息来看,系统在出现异常时,操作系统的Load是很低的,因此第一点我们可以直接排除。

我们现在的目的是需要分析出LMON进程检查到了什么异常,以及为什么会出现异常。

LMON进程在abort之前进行了dump,那么是否能够从相关dump 中找到一些有价值的线索呢?

...省略部分内容...

从上面LMON进程本身的dump来看,节点1实例的LMON进程状态是正常的,最后发送消息给LMON进程的是SO: 700001405330198,SO即为state obejct。搜索该SO,我们可以发现为LMD进程。

...省略部分内容...

从LMON和LMD进程的process dump来看,进程本身状态是正常的。因此我们可以排除进程挂起导致出现Timeout的可能性。同时我们可以看到LMD进程一直在等待ges remote message,很明显这是和另外一个数据库节点进行通信

因此我们要分析问题的根本原因,还需要分析节点2数据库实例的一些信息。

首先我们来分析节点2实例的数据库告警日志。

从节点2的数据库告警日志来看,在3:44:48时间点,实例开始进行reconfig操作,这与整个故障的时间点是符合的。

告警日志中本身并无太多信息,我们接着分析节点2数据库实例的LMON进程trace信息。

从上述LMON进程的日志来看,在故障时间点之前,数据库一直存在大量的DRM操作。并且注意到节点进行reconfiguration时,reason 代码值为1。关于reason值,Oracle Metalink文档有如下描述。

从reason =1 来看,数据库实例被强行终止重启也不是通信故障的问题。如果是通信的问题,那么reason值通常应该等于3。reason=1表明这是数据库节点自身监控时触发的reconfig操作。这也与我们前面分析节点1的日志的结论是符合的。

我们从* kjfcln:DRM aborted due to CGS rcfg. 这段关键信息也可以确认,CGS reconfig的原因也正是由于DRM操作失败导致。同时也可以看到,在3:29开始的Begin DRM(82935)操作,一直到3:44出现故障时,这个DRM操作都没有结束(如果结束,会出现EndDRM(82935) 类似关键字)。

由此也不难看出,实际上,该集群数据库可能在3:29之后就已经出现问题了。这里简单补充一下Oracle DRM的原理:

在Oracle RAC环境中,当某个节点对某个资源访问频率较高时,而该资源的master节点不是local节点时,那么可能会触发DRM(Dynamic Resource Management)操作。

在Oracle10gR1引入该特性之前,如果数据库需要更改某个资源的master节点,那么必须将数据库实例重启来完成。很显然,这一特性的引入无疑改变了一切。同时,从Oracle 10gR2开始,又引入了基于object/undo 级别的affinity。这里所谓的affinity,本质上是引入操作系统的概念,即用来表示某个对象的亲和力程度。在数据库来看,即为对某个对象的访问频率程度。

在Oracle 10gR2版本中,默认情况下,当某个对象的被访问频率超过50时,而同时该对象的master又是其他节点时,那么Oracle则会触发DRM操作来修改master节点,这样的好处是可以大幅降低gc grant之类的等待事件。在进程DRM操作的过程中,Oracle会将该资源的相关信息进行临时frozen,然后将该资源在其他节点进行unfrozen,然后更改资源的master节点。

这里我们需要注意的是,这里frozen的资源其实是GRD(Global Resource Directory)中的资源。在整个DRM的过程之中,访问该资源的进程都将被临时挂起。正因为如此,当系统出现DRM操作时,很可能导致系统或进程出现异常的。

实际上关于OracleDRM的Bug也非常多,尤其是Oracle 10gR2版本中。针对本次故障,我们基本上可以认定是如下的Bug导致。

最后建议客户屏蔽Oracle DRM功能之后,经过监控发现运行了相当长一段时间后都没有出现类似问题。

通过这个RAC的案例分析,大家可能注意到,相关的集群日志非常多。在分析过程中,需要保持非常清晰的思路,才能基于问题将这些信息串联起来,最终成为定位和解决问题的重要信息。而事后基于问题的总结和研究,更加是巩固知识、带动我们成长的关键。希望大家能够从中学到故障分析、学习提升的思路和方法。

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

原文发表时间:2017-03-23

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯移动品质中心TMQ的专栏

win32应用程序性能测试-内存篇

本文主要讲述windows平台下应用程序性能测试的内存相关的知识,通过本文了解内存基本原理和分析内存占用问题。 一、内存是什么? 1内存分为物理内存和虚拟内存 ...

2048
来自专栏java一日一条

Java I/O底层是如何工作的?

缓冲与缓冲的处理方式,是所有I/O操作的基础。术语“输入、输出”只对数据移入和移出缓存有意义。任何时候都要把它记在心中。通常,进程执行操作系统的I/O请求包括数...

162
来自专栏java一日一条

Java I/O底层是如何工作的?

本博文主要讨论I/O在底层是如何工作的。本文服务的读者,迫切希望了解Java I/O操作是在机器层面如何进行映射,以及应用运行时硬件都做了什么。假定你熟悉基本的...

274
来自专栏腾讯数据库技术

只读实例与RO组--助力MySQL实现读写分离,提升扩展性

2854
来自专栏搜云库

操作系统和数据库基础

进程与线程的差别 进程是程序的一次执行。线程可以理解为进程中执行的一段程序片段。在一个多任务环境下中下面的概念可以帮助我们理解两者的区别。 进程间是独立的...

17410
来自专栏Elasticsearch实验室

Elasticsearch性能、稳定性调优实践

本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概...

4924
来自专栏IT笔记

Nginx学习之负载均衡

负载均衡 负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性...

3456
来自专栏技术博文

Memcached 及 Redis 架构分析和比较

Memcached和Redis作为两种Inmemory的key-value数据库,在设计和思想方面有着很多共通的地方,功能和应用方面在很多场合下(作为分布式缓存...

2703
来自专栏JAVA高级架构

大型网站技术架构

1093
来自专栏JAVA高级架构

一个分布式服务器集群架构方案

732

扫描关注云+社区