首页 > 数据库 > Oracle > DRM特性引起的RAC节点宕机
某银行客户集群1 节点出现异常重启的问题,希望我们能够找出问题所在。开始本次故障排查之前,我们先来了解下DRM (动态资源管理)的原理。
假设某集群数据库包含3 个节点,根据RAC 内存融合的原理,每个实例会保存数据库1/3 的主节点信息,同时也意味着,每个节点访问数据时会有2/3 的概率需要从远程节点获取数据块的锁信息,从而造成更多节点间的消息通信。在实际应用中更有可能出现的情况是,一些数据块在非主节点上被访问了很多次,而主节点却很少访问。这种情况就意味着会产生大量的资源访问节点和资源主节点的消息,从而增加了私网的工作负载,甚至可能还会影响到数据库的性能。所以,Oracle 从10g 开始,推出了DRM 特性,使资源的主节点信息可以被动态修改。当然,决定这种修改的依据是每个节点对资源的访问频率。DRM 的移动过程主要可分为如下几个步骤。
1) 静默节点(Quiesce )。
2) 冻结阶段(Freeze )。
3) 清除阶段(Cleanup )。
4) 重建节点(Rebuild )。
5) 解冻节点(Unfreeze )。
下面先来看看数据库的告警日志,如图2-47 所示。
图2- 47 告警日志
不难看出,2018 年10 月9 日23:41:14 ,由于数据库的后台进程LMON 和LMS 节点间存在通信异常,LMS0 进程终止了数据库实例。因此,我们继续检查数据库LMON 和LMS 日志,以便查看是否因为进程出现了问题,才导致数据库宕机。接下来查看LMON 跟踪日志,输出如下:
*** 2018-10-09 23:34:18.405
* DRM RCFG called (swin 0)
CGS recovery timeout = 85 sec
Begin DRM(139949) (swin 0)
* drm quiesce
*** 2018-10-09 23:34:18.759
2018-10-09 23:34:18.759522 : DRM(139949) resources quiesced [0-65535], rescount 588987
2018-10-09 23:34:18.759882 : DRM(139949) local converts quiesced [0-65535], lockcount 0, bucket 0
* drm sync 1
* drm freeze
* drm cleanup
* drm sync 2
* drm replay
* drm sync 3
* drm fix writes
* drm sync 4
* drm end
* DRM RCFG called (swin 0)
CGS recovery timeout = 85 sec
* drm quiesce
<!--…… 省略部分-->
*** 2018-10-09 23:34:20.780
2018-10-09 23:34:20.780063 : DRM(139949) resources quiesced [131072-196607], rescount 589078
2018-10-09 23:34:20.780437 : DRM(139949) local converts quiesced [131072-196607], lockcount 1, bucket 228
* drm sync 1
* drm freeze
kjxgm_Notify_Eviction: Received an instance eviction notification from instance 2
*** 2018-10-09 23:41:14.147
kjxgm_Notify_Eviction: eviction member count 1 reason 0x2
kjxgm_Notify_Eviction: eviction map 1
2018 年10 月9 日 23:34:18.405 ,LMON 进程就已经接收到了来自2 节点的驱逐信息。此时数据库正在发生DRM ,但直到实例宕机(23:41 ),DRM 也没有结束的迹象。也就是说一个DRM 竟持续了7 分钟都没结束。
下面进一步查看LMD trace 日志DRM 的启动信息,内容如下:
*** 2018-10-09 23:34:18.359
* received DRM start msg from 2 (cnt 1, last 1, rmno 139949)
Rcvd DRM(139949) AFFINITY Transfer pkey 5999817.0 from 1 to 2 oscan 1.1
ftd (30) received from node 2 (76 0.30/0.0)
all ftds received
* kjxftdn: break from kjxftdn, post lmon later
*** 2018-10-09 23:34:18.812
ftd (33) received from node 2 (76 0.33/0.0)
all ftds received
* kjxftdn: break from kjxftdn, post lmon later
ftd (35) received from node 2 (76 0.36/0.0)
all ftds received
ftd (37) received from node 2 (76 0.38/0.0)
all ftds received
ftd (30) received from node 2 (76 0.30/0.0)
all ftds received
* kjxftdn: break from kjxftdn, post lmon later
*** 2018-10-09 23:34:20.830
ftd (33) received from node 2 (76 0.32/0.0)
all ftds received
* kjxftdn: break from kjxftdn, post lmon later
*** 2018-10-09 23:34:34.002
kjddt2vb: valblk [0.4e693] > local ts [0.4e692]
*** 2018-10-09 23:34:35.173
kjddt2vb: valblk [0.4e699] > local ts [0.4e698]
<!--…… 省略大量kjddt2vb: valblk 信息-->
*** 2018-10-09 23:41:12.133
kjddt2vb: valblk [0.504e9] > local ts [0.504e8]
2018 年10 月9 日 23:34:18 ,LMS 进程开始启动DRM ,直到实例宕机都没有结束,结合LMON 的信息,我们可以猜测到当时节点间通信的私网流量较大。
客户端zabbix 监控故障时间段系统的心跳网络流量,也印证了上面的判断。此时基本上可以判定是DRM 引起了此次宕机。为了进一步明确宕机的原因,我们再来查看23 点34 分左右数据库的会话信息,如图2-48 所示。

图2- 48 故障时间点会话信息
“gcs drm freeze in enter server mode ” 正是DRM 期间用户需要操作相同数据块时数据库发生的等待事件,如图2-49 所示。

图2- 49 等待事件信息
从会话等待及锁信息也能看出,故障发生前正在进行DRM 操作,但最终锁的源头LMS0 却处于空闲等待的状态。进一步查看LMS0 及2 节点的跟踪文件信息(ges2 LMON to wake up LMD - mrcvr ,2018-10-09 23:41:13.048015 : * kjfcdrmrcfg: waited 413 secs for lmd to receive all ftdones, requesting memberkill of instances w/o ftdones: ),内容与BUG 13399435/BUG13732226 匹配,MOS Oracle 官方参考文档LMON received an instance eviction notification from instance n (Doc ID 1440892.1) 。
最终,我们可以确认此次宕机是由于节点间产生了大量的DRM 触发了Bug ,从而导致1 节点数据库宕机。
分析到这里,宕机的原因已经很明确了,但是为什么会产生大量的DRM ,使得节点间通信加剧,这也是我们需要进一步排查的。由于数据库故障时间段丢失了部分快照点及自重启,我们尽可能地对现有日志进行分析,下面就来介绍排查的过程。首先,查看宕机前数据库的会话信息,如图2-50 所示。

图2- 50 宕机前数据库的会话信息
2018 年10 月9 日23 :34 ,节点间有大量的GC 类等待。堵塞的会话几乎都是来自2480 和2353 的会话,下面分别看下2480 和2353 会话,如图2-51 所示。

图2- 51 2480 会话信息
可以看出,2480 会话也被2353 会话堵塞,以相同的方式查看别的blocking_session ,可以发现它们都是来自同一个2353 会话,如图2-52 所示。

图2- 52 2353 会话信息
从以上会话信息中我们可以看出,最终锁的源头来自2353 号会话,它没有被任何会话堵塞,经排查,此会话是OGG (Oracle GoldenGate )挖掘进程,在执行SQL 23j1ukc8sjv4v 时构建了大量的全局CR 块。分析到这里,触发的条件也已经很明确了,是OGG 抽取进程引起的。
OGG 是本次故障的导火索,OGG 抽取导致了大量节点间的GC 类等待,造成大量会话阻塞,引起节点间的DRM ,触发Oracle Bug ,最终导致宕机。
由于DRM 触发了Oracle Bug ,因此建议关闭DRM 。
在Oracle 11G 中,可以使用如下方式禁用DRM :
SQL> alter system set "_gc_policy_time"=0 scope=spfile;
然后,同时重启所有实例生效。如果不想完全禁用DRM ,但是需要禁用read-mostly locking 或reader bypass 的机制。可以使用如下命令:
SQL> alter system set "_gc_read_mostly_locking"=false scope=spfile;
SQL> alter system set "_gc_bypass_readers"=false scope=spfile;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31547506/viewspace-2934454/ ,如需转载,请注明出处,否则将追究法律责任。