由DRM引起的ORA-00481错误

在开始向大家分享之前,先说说 Oracle 的错误的标示体系,大家都知道在 Oracle 数据库中有大量的错误,比如以 ora-开头、tns-开头、crs-开头,当然还有其他工具类的错误开头比如 exp 和 imp 等。


当然都是大家熟悉的错误开头,其中 ora-类错误大家接触的最多,这是和 Oracle 数据库相关的错误类别,今天就和大家分享的是 ora-00481错误。

 

我们先来看看 ora-00481 的含义及可能的原因。

Ora-00481 错误意思是 lmon 进程 abort。


Ora-00481 错误的可能原因有以下几种:

1. 由 DRM 引起,当 DRM 开始后但是并未完成所致。

2. ASM 或者 database 启动失败造成 RAC 重构时报 ora-00481错误

3. Lmon 与 OCSSD 通信失败出现 ora-00481 错误

4. 实例被驱逐时伴随 ora-00481 错误。


以上4条引起481错误的原因。


下面就这几个可能原因简单在日志中反馈的结果做下分析:


1.    由 DRM 引起的481错误。

由 DRM 引起的 ora-00481错误,是由于 DRM 开始但是并未完成导致,在 lmon 的 trace 文件中会显示 DRM 并未完成的提示:


由DRM引起的ORA-00481错误_第1张图片


在上述 trace 中,没有 End DRM(107) 的信息。意思就是 DRM 期间,LMON 进程没有工作导致 DRM 并没有完成,以至于实例被驱逐。在这种情况下需要更多日志信息来确定是由于 DRM 未完成导致的,我们可以按照下述的步骤进行一步步的确定:


A. LMSx trace 文件给出如下类似的信息:

由DRM引起的ORA-00481错误_第2张图片


上述显示需要更多的 LOCK ELEMENTS (简称 LE) , 但是没有有效的。


LMS 进程在 DRM 重构的过程中由于 LE 短缺导致失速,然后导致 DRM 超时并造成实例的crash.


这种问题需要打补丁 bug:11875294,bug:12537479,根据补丁内容设置参数_gc_read_mostly_locking。


B. 还有一种情况如下;

在 lmon trace文件中体现如下:

由DRM引起的ORA-00481错误_第3张图片


LMON 进程等待 LMD 接收 ftdones。


进一步查看 LMD0 的 trace 文件,来确定为什么 LMD 不工作了,这个需要查看所有节点上的 LMD0 的 trace 文件。如下:


由DRM引起的ORA-00481错误_第4张图片

 

在 trace 文件中 “avl 0”意味着目前该节点可用的 ticket 数量为0;所以 LMS 进程跑出了 flow control tickets 的范围,在该种情况下,Oracle 推荐更新相应补丁来解决此类问题,比如:bug16819962.17452841,17801017,17847764,16088176;或者通过调整初始化参数_lm_tickets 来增加 tickets 的数量;根据我们的实际经验,对于高并发系统来讲,建议调整为5000。

  

这里很可能人可能并不理解什么是 ticket,这里我再为大家简单介绍一下 Oracle ticket 消息机制,这是 Oracle 为了保证在实例之间传输的消息的平衡和对传输的消息的几率,控制彼此之间的合理流量而引入的一个消息机制,RAC 通过 ticket 对彼此之间传输的流量和几率进行控制。


一个节点发送一则消息队列的同时会带着一个 ticket 到对端,对端的 ticket 会增加。本地的 ticket 会减少,本地节点会根据可用的 buffer 和已经收到的信息以及发送的请求 ticket 的信息(null-req)计算本地可用的 tickets。当本地没有 ticket 可用,本地的 LMS/LMD 就会进入消息等待队列,并持续的检查 ticket latch 里的信息,判断是否有可用的 ticket 的信息可用。直到对端发送回 message,并带回可用的 tickets 后,本地才能再继续发送消息到对端。上述的例子就是由于实例间 ticket 短缺,引发 LMS/LMD 之间消息传输超时出现的故障。


这个可以通过视图 GV$GES_TRAFFIC_CONTROLLER 来获取每个节点上的 avalible 的 ticket 的数量,或者可以通过隐含参数_lm_tickets 来进行控制,该参数默认值是1000,通过该参数可以避免上述出现的错误。


2. 在 alert 中发现如下信息:

由DRM引起的ORA-00481错误_第5张图片


并且这条信息是在实例被驱逐或者实例由于 ora-00481abort。


在这种情况下,有三种思路,如下;

① 心跳网络连接问题,

② HAIP 的问题,在这种情况下,先需要确定 HAIP 是否可以正常使用。

③ 服务器负载压力过大。可以通过 oswatcher 来收集系统资源使用情况。


3. 在 alert 中发现如下信息:

由DRM引起的ORA-00481错误_第6张图片


Ora-29701 错误,意思 lmon 与 OCSSD of CRS/GridInfrastructure. 丢失连接。


在这种情况有两种思路:

① 确定是否有 job 或者用户误删除了 /tmp/.oracle 和 /var/tmp/.oracle

② 更新补丁 bug 14096821.

  

Ora-00481 错误可能出现的原因以及日志中的反馈我们已经大概了解了,下面我们就看看用户 crm 库的具体情况。

 

客户这的 crm 数据库在8月1日早上2节点突然业务连接中断,查看2节点 alert 日志发现日志中报了 ora-00481 错误,并且后续导致2节点实例 abort,在2分钟之内又重新启动,恢复正常。


由DRM引起的ORA-00481错误_第7张图片

 

先介绍下客户这边的环境 HP-Unix + RAC, Oracle 版本10.2.0.4 使用的是裸设备。所以需要收集的日志文件有,database alert 日志,trace 文件(lmon, lmd, lms, diag, lmhb, dia0),按照顺序先收集 database alert 日志,如下:


由DRM引起的ORA-00481错误_第8张图片


上述信息中,只是表明了由于481错误终止了实例,所以需要更多的信息来确定问题来源。


在分析 LMON 的 trace 文件之前,简单的描述下 LMON 进程,LMON 进程,主要是监控 RAC 的 GES 信息以及负责检查集群中各个节点的健康情况,当有节点出现故障时,负责进行 reconfig 以及 GRD (globalresource Directory) 的恢复等。


RAC 的脑裂机制,Lmon 进程检查到实例级别出现脑裂时,会通知 clusterware 来进行脑裂操作,当等待超过一定时间,那么 LMON 进程会自动触发 IMR (instancemembership recovery),这实际上也就是我们所说的 Instancemembership reconfig。


其次,lmon 进程主要通过2种心跳机制来检查判断集群节点的健康状态:

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

② 控制文件磁盘心跳,其实就是每个节点的 ckpt 进程每3s更新一次 controlfile 的机制。

 

现在查看上述中给出的 lmon 的 trace 日志文件:


由DRM引起的ORA-00481错误_第9张图片


我们可以看出在 LMON 进程的 trace 文件中最近的记录为4月24日,并没有发现故障时间点8月1日的相关信息。由于是 Oracle LMON 检测到异常后并终止了实例,那么我们进一步分析 LMON 进程;


因此我们这里进一步检查确认是否有相关的有价值的线索。


通过 ls -rtl | greplmon 命令得到最近的 LMON 的 trace 日志。


由DRM引起的ORA-00481错误_第10张图片


查看最近的 LMON 的 trace 日志,ngcrm2_lmon_11361.trc


由DRM引起的ORA-00481错误_第11张图片


结合 alert 和 LMON trace 查看,时间点顺序是这样的:

时间 1  08:29:43,实例终止,

时间 2  08:30:11.107  在 LMON trace 中 reconfigure 开始,

在结合 alert 日志中

时间 1 08:30:00 实例进程启动

时间 2 08:30:06,实例启动完成,启动后台进程包括 LMON 进程,

时间 3 08:30:18 进程 CRS 重构,

时间 4 08:30:35 database open。


也就是说上述的 LMON 进程的 trace 文件是在实例恢复后的 trace 文件,在之前的就没有,而且在实例恢复后的 LMONtrace 文件中看到 DRM Reconfiguration 都是正常的。所以在这没办法判定是否是由于 DRM 造成的481错误。


需要进一步来查看 lmd 日志和 diag 日志,以及 lms 日志:

Lms 日志(more ngcrm2_lms0_11365.trc)


由DRM引起的ORA-00481错误_第12张图片


LMD 日志(ngcrm2_lmd0_11363.trc)


由DRM引起的ORA-00481错误_第13张图片


Diag 日志信息(ngcrm2_diag_11357.trc)


由DRM引起的ORA-00481错误_第14张图片


在这三个日志中由于设置了 dump_file_size 的大小为 5M,之前的日志都没法查看。


但是在 alert 日志中和 LMON 日志,LMD 日志中多次出现与 DRM 相关的内容,而且在 LMD 日志中,出现的如下两条内容:


由DRM引起的ORA-00481错误_第15张图片


以及 LMON 日志中的:


由DRM引起的ORA-00481错误_第16张图片


等信息,在结合我们之前分析的 ora-00481 错误出现的几个因素,是由于 DRM 开始后未完成,在实例启动起来后,重新进行未完成的 reconfiguer. 并且在之后的 LMON trace 文件中,还可以看到一些 DRM 开始以及结束的信息,且非常频繁。


总结:基于我们对 Oracle lmon 等进程的原理以及结合前面的种种日志分析,我们认为此次故障跟 Oracle DRM 有极大关系(实际上我们在其他客户案例中遇到了很多类似情况,尤其是 Oracle 10g rac 环境中,DRM 稳定性较差)。


DRM(Dynamic Resourcemanagement)动态资源管理。真正实现是在10.1.0.2之后的版本之后,10g 之前也有。


该特性的设计初衷是为了通过更改所访问资源的 master node 降低跨节点频繁访问需求,通过更改 master node 的节点属性,让访问资源的频繁的节点成为 master node ,把节点之间的块交换放在节点本地以降低节点之间访问块的低价。在 10gR2 之后,file affinity 演化为细粒度更高的 object affinity,并且同时引入了 undoaffinity,只要是满足隐含参数要求,DRM 就会被启用,可以通过 LMON 和 lms 的 trace 文件就可以发现有很多的 remastering. 在11g之后 Oracle 引入了两个重要的指标。Read-mostly locking 以及 reader bypass.。read-mostly locking: 简单的说就是,对于某个对象,比如读非常多,预先给它加一层共享访问锁,所有结点都持有,因而减少了共享锁的申请操作。而当需要写操作时,需申请排它锁时,在每个结点上都申请一个”anti-lock”锁,可以理解为”反锁”,然后再 cache fusion。


reader bypass:与 read-mostly locking 是互斥的,主要是为读少写多的业务进行的优化。reader bypass 同样引入了一种新的锁模式 weakX lock(又称 xw 锁)。可以在S锁没有释放以前,为一个 block 加上一个xw锁,对这个 block 进行修改,但是不允许立刻 commit,直到所有的的S锁都关闭或者降级到N锁,LMS 就会向 xw 锁的持有者发送一条信息可以进行 commit.


该案例中,最终建议用户关闭 DRM,关闭 DRM 可以设置如下两个参数。


由DRM引起的ORA-00481错误_第17张图片


但是有一点,客户的环境都是生产系统,而且在1号中午12点之前是出账时间,不允许重启数据库,所以只能临时的增大上述两个参数的值,减少 DRM 被触发的机率,变相的关闭 DRM。在屏蔽 DRM 后,目前数据库至今允许稳定。


更改参数如下:


由DRM引起的ORA-00481错误_第18张图片


在11gR2 之后可以通过_lm_drm_disable 可以在线动态禁用 DRM,对于该参数的描述如下:


由DRM引起的ORA-00481错误_第19张图片


设置_lm_drm_disable 在不同的 level 有不同的含义。

 Level4 disable read mostly

 Level 5 disable DRM for all but undo

 Level 7 disable DRM for all including undo.


一般情况下建议 level 设置为5。命令如下:

Altersystem set “_lm_drm_disable”=5;

 

最后总结下,伴随481错误的出现往往就是实例的重启,而且我们也看到了,481错误出现的场景都是在 RAC 环境下,在 RAC 稳定的情况下,唯一考虑的也就是心跳问题和 DRM 问题,这两个问题其实都还是跟各个节点的业务运行情况有关系,为了降低心跳压力和 DRM 重构,最好的手段还是对业务进行分离,如果不然,检查各自的数据库环境的参数,确保不会出现上述相关隐含参数未改的情况,在两节点压力过大的情况下会导致节点实例重启。

你可能感兴趣的:(Oracle,Database)