百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

技术培训 | RAC 宕机罪犯案情探析之子游标

mhr18 2025-02-03 14:08 19 浏览 0 评论

大家好,我是云和恩墨的李轶楠,不过网上的朋友更习惯叫我600,所以我也慢慢熟悉了这个称呼,其实这个称呼来自于ITPUB论坛上当时我注册的论坛ID“ORA-600”,因为这个ID跟Oracle的著名错误号一样,很容易给大家留下深刻印象,所以被我借用了过来,呵呵。这些年通过论坛上认识了很多朋友,也结识了现在与我一起奋战的恩墨小伙伴们。

闲话不多说,我们来看看我们今天要分享的主题吧,这些年我们积累了大量的客户群体,也意味着我们面对着各种复杂的环境与事件,后续我会把我们小伙伴们所遭遇到的各种或者经典、或者灵异、或者有趣的case,逐一做成案件分析来分享给大家,希望大家喜欢。今天就以去年我们所遇到的一次RAC节点宕机的故障作为开场吧。

1. 案情描述

2015年6月的一个傍晚,大雨滂沱,正坐在家里发呆中,突然被一阵铃声惊醒。拿起电话,发现是客户来电,于是赶紧接听:

”我们的核心系统在晚上9点多突然有一个节点挂了,实例自动重启。虽然没有影响业务,但这种无缘无故的重启发生在核心系统上,直接威胁我们的业务运行,领导很重视,所以今天必须把原因找到,多晚都要给出结果,拜托了!“

2. 案情分析

听到客户的描述,心里第一个反应是:还好,只是单节点重启,问题本身应该不严重,至少对业务影响并不大,看来这大雨天是不用淋雨去客户现场了。。。呵呵,小心思而已。

客户目前急需的是快速给出问题的原因,以便根据情况作出后续的规避措施,所以需要尽快拿到现场的一些数据来做分析,毕竟分析所需要的信息数据距离故障时间越近,精准度就越高,越有利分析

经过进一步的沟通,得到了一些案发时的基本信息:

  1. 重启的是整个数据库架构的2节点,这个库是核心系统,晚上也有业务;

  2. 重启实例的情况其实以前也发生过,只不过发生的不多;(潜台词是也许这不是个案,以前的重启意味着可能这个问题一直存在)

  3. 当前数据库版本为11.2.0.1。(看到每个大版本的第一个小版本,总是觉得这种系统会BUG缠身。。。虽然夸大了点,但我们确实遇到了不少这种小版本的BUG)

当然,很明显只听客户描述是不够的。于是,我远程登录了客户的服务器,开始做进一步检查。

在开始分析之前,先跟大家及一下故障分析的常规思路,也便于初学者在遇到问题的时候知道从何处入手。

  • 在遇到故障时,首先要辨识一下当前的场景主要是性能问题的还是真的故障;

  • 如果是性能问题,那就需要收集当时的系统性能信息与数据库性能信息,awr、ash,或者系统的nmon、top之类都可以;

  • 如果是故障,那就要检查数据库的告警日志与跟踪文件了,非常典型的就是alertSID.log,这里面往往给了我们进一步追踪痕迹的指引。除此之外,各个进程的trace文件,asm的trace文件以及RAC的各种log、trace文件都会给出一些故障的原因或者印记,具体的这些文件所在目录大家都应该熟悉,最典型的就是通过background_dump_dest、user_dump_dest参数去查找(注意,rac的log和trace文件与数据库的目录并不在一起,可以检查$GRID_HOME/log/的各个子目录),更详细的在这里就不再展开了。

  • 另外,当遭遇这些问题的时候,如果有MOS账号的话,建议首先去MOS中查看是否有故障相关的BUG或者技术文章,这既是快速诊断问题、解决问题的途径,也是DBA快速成长的重要手段。关于MOS的使用,大家可以加公众号“oracle”,在其中可以看到5月5日发的一篇“Oracle初学者入门指南-什么是Metalink或MOS?”

好吧,回到我们的案例中:

1、下面是节点2的alert log部分内容:

Fri Jun 26 20:24:52 2015

Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_p001_13581.trc (incident=204565):

ORA-00600: 内部错误代码, 参数: [kksfbc-wrong-kkscsflgs], [39913467504], [33], [], [], [], [], [], [], [], [], []

Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_204565/orcl2_p001_13581_i204565.trc

Fri Jun 26 20:25:06 2015

Trace dumping is performing id=[cdmp_20150626202506]

Fri Jun 26 20:25:06 2015

Sweep [inc][204565]: completed

Sweep [inc2][204565]: completed

Fri Jun 26 20:25:18 2015

Trace dumping is performing id=[cdmp_20150626202517]

。。。。。

Fri Jun 26 21:21:08 2015

Archived Log entry 164580 added for thread 2 sequence 48360 ID 0xa822d65a dest 1:

Fri Jun 26 21:41:09 2015

Thread 2 advanced to log sequence 48362 (LGWR switch)

Current log# 2 seq# 48362 mem# 0: +DATA/orcl/onlinelog/redo21.log

Current log# 2 seq# 48362 mem# 1: +DATA/orcl/onlinelog/redo22.log

Fri Jun 26 21:41:09 2015

Archived Log entry 164584 added for thread 2 sequence 48361 ID 0xa822d65a dest 1:

Fri Jun 26 21:50:26 2015

LCK0 (ospid: 29987) waits for latch 'object queue header operation' for 77 secs.

Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_lmhb_29939.trc (incident=204141):

ORA-29771: process MMON (OSID 29967) blocks LCK0 (OSID 29987) for more than 70 seconds

Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_204141/orcl2_lmhb_29939_i204141.trc

MMON (ospid: 29967) is blocking LCK0 (ospid: 29987) in a wait

LMHB (ospid: 29939) kills MMON (ospid: 29967).

Please check LMHB trace file for more detail.

Fri Jun 26 21:51:06 2015

Restarting dead background process MMON

Fri Jun 26 21:51:06 2015

MMON started with pid=213, OS id=16612

Fri Jun 26 21:51:09 2015

Sweep [inc][204141]: completed

Sweep [inc2][204141]: completed

Fri Jun 26 21:54:10 2015

LMS1 (ospid: 29929) waits for latch 'object queue header operation' for 81 secs.

LCK0 (ospid: 29987) has not called a wait for 85 secs. Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_lmhb_29939.trc (incident=204142):

ORA-29770: global enqueue process LMS1 (OSID 29929) is hung for more than 70 seconds

Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_204142/orcl2_lmhb_29939_i204142.trc

Fri Jun 26 21:54:20 2015

Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_lmhb_29939.trc (incident=204143):

ORA-29770: global enqueue process LCK0 (OSID 29987) is hung for more than 70 seconds

Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_204143/orcl2_lmhb_29939_i204143.trc

ERROR: Some process(s) is not making progress.

LMHB (ospid: 29939) is terminating the instance.

Please check LMHB trace file for more details.

Please also check the CPU load, I/O load and other system properties for anomalous behavior

ERROR: Some process(s) is not making progress.

LMHB (ospid: 29939): terminating the instance due to error 29770

Fri Jun 26 21:54:21 2015

opiodr aborting process unknown ospid (26414) as a result of ORA-1092

Fri Jun 26 21:54:21 2015

ORA-1092 : opitsk aborting process

Fri Jun 26 21:54:21 2015

System state dump is made for local instance

System State dumped to trace file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_diag_29889.trc

Instance terminated by LMHB, pid = 29939

Sat Jun 27 12:52:23 2015

Starting ORACLE instance (normal)

LICENSE_MAX_SESSION = 0

LICENSE_SESSIONS_WARNING = 0

Interface type 1 eth1 172.16.0.0 configured from GPnP Profile for use as a cluster interconnect

Interface type 1 eth0 192.168.0.128 configured from GPnP Profile for use as a public interface

Picked latch-free SCN scheme 3

Autotune of undo retention is turned on.

LICENSE_MAX_USERS = 0

SYS auditing is disabled

在告警日志中我们发现一个很明显的ORA-600错误,同时也发现一些其他的ORA报错,见上面标红部分。于是我们对这些错误分别进行了分析,发现:

1)ORA-600 [kksfbc-wrong-kkscsflgs] (Doc ID 970885.1) 确实是一个bug,在MOS上有说明:

NBBugFixedDescription
906728211.2.0.1.2, 11.2.0.1.BP01, 11.2.0.3, 12.1.0.1ORA-600 [kksfbc-wrong-kkscsflgs] can occur
906613010.2.0.5, 11.1.0.7.2, 11.2.0.2, 12.1.0.1OERI [kksfbc-wrong-kkscsflgs] / spin with multiple children
882832811.2.0.1.1, 11.2.0.1.BP04, 11.2.0.2, 12.1.0.1OERI [kksfbc-wrong-kkscsflgs]
866116811.2.0.1.1, 11.2.0.1.BP01, 11.2.0.2, 12.1.0.1OERI[kksfbc-wrong-kkscsflgs] can occur

但MOS上并未说明该BUG会导致实例宕机,这个600错误看来应该与此次重启关系不大,好吧,作为一个问题记下来就是了。

2) 在故障时间点,LMHB 进程check发现mmon进程阻塞了LCK0进程,超过70s,因此尝试kill MMON进程,该进程被kill之后将会自动重启。

可以看到在Jun 26 21:51:06 时间点,MMON进程重启完成。

这里在插播一件事,正好就在前几天,我们的客户也遇到了MMON进程的相关问题,在这也顺便分享给大家:客户的MMON进程被Kill之后并未自动启动,导致AWR等性能信息无法自动收集,因此客户希望能够在不启动数据库的情况下启动MMON,再想了各种办法之后,最终找到了方法:

Restart the database instance

或者

Set the instance to "restricted session" mode and then bring it back to normal mode using following commands as SYSDBA:alter system enable restricted session;alter system disable restricted session;

大家也可以搜寻一下MOS上的文章,看到相关的信息:文档 ID 2023652.1

接下来,在Jun 26 21:54:10,LMS1进程报错无法获得latch(object queue header operation) 超过85秒。

注: LMHB是11gR2中引入的后台进程,官方文档介绍是Global Cache/Enqueue Service Heartbeat Monitor,Monitor the heartbeat of LMON, LMD, and LMSn processes,LMHB monitors LMON, LMD, and LMSn processes to ensure they are running normally without blocking or spinning。 该进程负责监控LMON、LMD、LMSn等RAC关键的后台进程,保证这些background process不被阻塞或spin。 LMHB是Lock Manager Heartbeat的缩写。

2、为了更清楚的理清线索,我们根据节点2的alert log信息,整理出如下的时间线点:

Jun 26 20:24:52 ORA-00600 [kksfbc-wrong-kkscsflgs]

Jun 26 21:50:26 LCK0 (ospid: 29987) waits for latch 'object queue header operation' for 77 secs MMON (OSID 29967) blocks LCK0 (OSID 29987) for more than 70 seconds MMON (ospid: 29967) is blocking LCK0 (ospid: 29987) in a wait LMHB (ospid: 29939) kills MMON (ospid: 29967)

Jun 26 21:51:06 MMON started with pid=213, OS id=16612 Jun 26 21:54:10 LMS1 (ospid: 29929) waits for latch 'object queue header operation' for 81 secs LCK0 (ospid: 29987) has not called a wait for 85 secs

ORA-29770: global enqueue process LMS1 (OSID 29929) is hung for more than 70 seconds

Jun 26 21:54:20 ORA-29770: global enqueue process LCK0 (OSID 29987) is hung for more than 70 seconds

ERROR: Some process(s) is not making progress. LMHB (ospid: 29939) is terminating the instance

LMHB (ospid: 29939): terminating the instance due to error 29770

从最后的信息可以看出,在21:54:20时间点,LMHB进程强行终止了数据库实例. 而终止实例的原因是LMHB进程发现LCK0进行hung住了,而且超过了70s。在从前面的信息也可以看出,实际上在21:54:10时间点,LCK0进程就已经没有活动了了,而且在该时间点LMS1进程也一直在等待latch。很明显,如果LMS1进程无法正常工作,Oracle为了保证集群数据的一致性,为了避免脑裂,必然将问题节点强行驱逐重启。

那么LMS1在等什么呢?LCK0为什么被Hung住了?

3、lms1进程的情况

让我们来看看LMS1到底在干什么?

检查
orcl2_lmhb_29939_i204142.trc,而该trace 文件产生的时间点是:Jun 26 21:54:10:

SO: 0x9a1175160, type: 2, owner: (nil), flag: INIT/-/-/0x00 if: 0x3 c: 0x3

proc=0x9a1175160, name=process, file=ksu.h LINE:11459, pg=0

(process) Oracle pid:14, ser:1, calls cur/top: 0x9b17e5330/0x9b17e0e60

flags : (0x6) SYSTEM

flags2: (0x100), flags3: (0x0)

intr error: 0, call error: 0, sess error: 0, txn error 0

intr queue: empty

ksudlp FALSE at location: 0

(post info) last post received: 0 0 116

last post received-location: kjc.h LINE:1810 ID:KJCS Post snd proxy to flush msg last process to post me: 991126330 1 6

last post sent: 41134582880 162 1

last post sent-location: ksl2.h LINE:2160 ID:kslges last process posted by me: 9811032c8 1 14

(latch info) wait_event=0 bits=a

Location from where call was made: kcbo.h LINE:890 ID:kcbo_unlink_q_bg:

waiting for 993cfec60 Child object queue header operation level=5 child#=117

Location from where latch is held: kcl2.h LINE:3966 ID:kclbufs:

Context saved from call: 0

state=busy(shared) [value=0x4000000000000001] wlstate=free [value=0]

waiters [orapid (seconds since: put on list, posted, alive check)]: 14 (95, 1435326858, 4) 21 (94, 1435326858, 7)

waiter count=2

gotten 73961423 times wait, failed first 4752 sleeps 1927

gotten 33986 times nowait, failed: 4

possible holder pid = 36 ospid=29987

on wait list for 993cfec60

holding (efd=5) 9b59be480 Child gc element level=3 child#=20

Location from where latch is held: kcl2.h LINE:3535 ID:kclbla:

Context saved from call: 0

state=busy(exclusive) [value=0x200000000000000e, holder orapid=14] wlstate=free [value=0]

holding (efd=5) 9b45cac50 Child cache buffers chains level=1 child#=61221

Location from where latch is held: kcl2.h LINE:3140 ID:kclbla:

Context saved from call: 0

state=busy(exclusive) [value=0x200000000000000e, holder orapid=14] wlstate=free [value=0]

Process Group: DEFAULT, pseudo proc: 0x9b11ca008

O/S info: user: oracle, term: UNKNOWN, ospid: 29929

OSD pid info: Unix process pid: 29929, image: oracle@ebtadbsvr2 (LMS1)

从LMS1进程的信息来看,LMS1 进程所等待的资源(object queue header operation)正被ospid=29987 持有,那么29987又是什么呢?

4、进一步分析下ospid=29987 是什么?

让我们接着往下看:

SO: 0x9911283b0, type: 2, owner: (nil), flag: INIT/-/-/0x00 if: 0x3 c: 0x3

proc=0x9911283b0, name=process, file=ksu.h LINE:11459, pg=0

(process) Oracle pid:36, ser:2, calls cur/top: 0x9b17e58e0/0x9b17e58e0

flags : (0x6) SYSTEM

flags2: (0x0), flags3: (0x0)

intr error: 0, call error: 0, sess error: 0, txn error 0

intr queue: empty

ksudlp FALSE at location: 0

(post info) last post received: 0 0 35

last post received-location: ksr2.h LINE:603 ID:ksrpublish last process to post me: 981110608 118 0

last post sent: 0 0 36

last post sent-location: ksr2.h LINE:607 ID:ksrmdone last process posted by me: 9911283b0 2 6

(latch info) wait_event=0 bits=20

holding (efd=3) 993cfec60 Child object queue header operation level=5 child#=117

Location from where latch is held: kcl2.h LINE:3966 ID:kclbufs:

Context saved from call: 0

state=busy(shared) [value=0x4000000000000001] wlstate=free [value=0]

waiters [orapid (seconds since: put on list, posted, alive check)]: 14 (95, 1435326858, 4) 21 (94, 1435326858, 7)

waiter count=2

Process Group: DEFAULT, pseudo proc: 0x9b11ca008

O/S info: user: oracle, term: UNKNOWN, ospid: 29987

OSD pid info: Unix process pid: 29987, image: oracle@ebtadbsvr2 (LCK0)

最后一句很明显的告诉我们,29987原来就是LCK0进程。这意味着lms1 进程所等待的资源正被LCK0 进程所持有。而同时还有另外一个进程orapid=21 也在等待该进程。通过分析我们分析发现:

orapid=21,是dbw2进程,即数据库写进程。

注:这里解释一下,orapid是oracle中的进程id,而pid则是os上的进程id。所以orapid=21从v$process中可以查到是dbw2,而orapid=14是lms1.

5、从数据库alert log来看,在Jun 26 21:54:10 有提示lck0 进程已经超过85秒没有响应

LCK0 (ospid: 29987) has not called a wait for 85 secs

根据时间点来计算,大概在Jun 26 21:52:45点左右开始,LCK0进程即没有响应了。

那么很明显,我们只要知道LCK0进程为什么会hung,就知道了此次故障的原因。

那么我们来看看LCK0的trace文件,看能不能看到一些线索。

6、LCK0进程的trace信息

*** 2015-06-26 21:50:29.329 Process diagnostic dump for oracle@ebtadbsvr2 (LCK0), OS id=29987,

pid: 36, proc_ser: 2, sid: 1729, sess_ser: 3 -------------------------------------------------------------------------------

loadavg : 6.47 26.96 34.97 Memory (Avail / Total) = 10598.05M / 64421.55M

Swap (Avail / Total) = 20256.00M / 20479.99M

F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD

0 S oracle 29987 1 0 76 0 - 10541946 semtim Apr05 ? 01:25:21 ora_lck0_orcl2

Short stack dump:

ksedsts()+461<-ksdxfstk()+32<-ksdxcb()+1782<-sspuser()+112<-__restore_rt()<-semop()+7<-skgpwwait()+156<-kslgess()+1799<-ksl_get_shared_latch()+620<-kclbufs()+272<-kclanticheck()+412<-kclahrt()+88<-ksbcti()+212<-ksbabs()+1732<-kclabs()+186<-ksbrdp()+923<-opirip()+623<-opidrv()+603<-sou2o()+103<-opimai_real()+266<-ssthrdmain()+214<-main()+201<-__libc_start_main()+244<-_start()+36*** 2015-06-26 21:54:18.438Process diagnostic dump for oracle@ebtadbsvr2 (LCK0), OS id=29987,

pid: 36, proc_ser: 2, sid: 1729, sess_ser: 3 -------------------------------------------------------------------------------

loadavg : 2.04 13.34 27.63Memory (Avail / Total) = 9519.06M / 64421.55M

Swap (Avail / Total) = 20256.00M / 20479.99M

F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD0 R oracle 29987 1 0 85 0 - 10541965 ? Apr05 ? 01:26:55 ora_lck0_orcl2

Short stack dump:

ksedsts()+461<-ksdxfstk()+32<-ksdxcb()+1782<-sspuser()+112<-__restore_rt()<-kcbo_get_next_qheader()+255<-kclbufs()+321<-kcldirtycheck()+231<-kclahrt()+93<-ksbcti()+212<-ksbabs()+1732<-kclabs()+186<-ksbrdp()+923<-opirip()+623<-opidrv()+603<-sou2o()+103<-opimai_real()+266<-ssthrdmain()+214<-main()+201<-__libc_start_main()+244<-_start()+36

从上述lck0进程的几个时间点的信息来看,第一个时间点21:50:29 :wchan 为semtim。wchan,表示进程sleeping的等待表现形式。semtim表示在该时间点,lck0 进程一直处于sleep状态。所谓的sleep状态,是进程持有的资源是不会释放的。

而在第2个时间点21:54:18,lck0进程的wchan状态是 ?,这表示未知,如果是为空,则表示该进程处理running状态。在21:50到21:52 时间段内,LCK0进程仍然没有恢复正常。那么LCK0到底被什么阻塞了(或者说它需要的资源被谁占用了)?

同时也可以看到内存和swap都空闲很多,CPU也并不很忙。

7、继续检查trace,在21:50时间点我们发现,lck0进程是被MMON进程锁阻塞了

SO: 0x9d10f97c0, type: 2, owner: (nil), flag: INIT/-/-/0x00 if: 0x3 c: 0x3

proc=0x9d10f97c0, name=process, file=ksu.h LINE:11459, pg=0

(process) Oracle pid:31, ser:1, calls cur/top: 0x965657408/0x9b17e3f18

flags : (0x2) SYSTEM

flags2: (0x20), flags3: (0x0)

intr error: 0, call error: 0, sess error: 0, txn error 0

intr queue: empty

ksudlp FALSE at location: 0

(post info) last post received: 0 0 35

last post received-location: ksr2.h LINE:603 ID:ksrpublish last process to post me: 9911283b0 2 6

last post sent: 0 0 26

last post sent-location: ksa2.h LINE:282 ID:ksasnd last process posted by me: 9911283b0 2 6

(latch info) wait_event=0 bits=26

holding (efd=7) 993cfec60 Child object queue header operation level=5 child#=117

Location from where latch is held: kcbo.h LINE:884 ID:kcbo_link_q:

Context saved from call: 0

state=busy(exclusive) [value=0x200000000000001f, holder orapid=31] wlstate=free [value=0]

waiters [orapid (seconds since: put on list, posted, alive check)]: 36 (82, 1435326627, 1) 21 (81, 1435326627, 1)

waiter count=2

holding (efd=7) 9b5a5d630 Child cache buffers lru chain level=2 child#=233

Location from where latch is held: kcb2.h LINE:3601 ID:kcbzgws:

Context saved from call: 0

state=busy [holder orapid=31] wlstate=free [value=0]

holding (efd=7) 9c2a99938 Child cache buffers chains level=1 child#=27857

Location from where latch is held: kcb2.h LINE:3214 ID:kcbgtcr: fast path (cr pin):

Context saved from call: 12583184

state=busy(exclusive) [value=0x200000000000001f, holder orapid=31] wlstate=free [value=0]

Process Group: DEFAULT, pseudo proc: 0x9b11ca008

O/S info: user: oracle, term: UNKNOWN, ospid: 29967

OSD pid info: Unix process pid: 29967, image: oracle@ebtadbsvr2 (MMON)

从上面的trace可以看到之前一直被等待的993cfec60 资源(Child object queue header operation)正被 mmon进程持有。

21:50:29的时候LCK0在等待mmon释放资源,而此时mmon出现异常,因此在21:51:06 mmon 进程被LMHB强制重启。然后在重启后,由于mmon的异常,导致21:54:18该资源仍无法被lck0 进程正常持有,最终导致21:54:20LMHB进程强制重启了整个实例。

因此,最终的罪魁祸首是mmon进程。

Fri Jun 26 21:50:26 2015

LCK0 (ospid: 29987) waits for latch 'object queue header operation' for 77 secs.

Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_lmhb_29939.trc (incident=204141):

ORA-29771: process MMON (OSID 29967) blocks LCK0 (OSID 29987) for more than 70 seconds

Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_204141/orcl2_lmhb_29939_i204141.trc MMON (ospid: 29967) is blocking LCK0 (ospid: 29987) in a wait LMHB (ospid: 29939) kills MMON (ospid: 29967).

Please check LMHB trace file for more detail.

Fri Jun 26 21:51:06 2015

Restarting dead background process MMON

Fri Jun 26 21:51:06 2015

MMON started with pid=213, OS id=16612

mmon进程Oracle是用于进行AWR信息收集的。既然案情发生的原因与它有关,那么接下来的分析自然是查看它的相关trace了。

8、检查MMON的相关trace 可以看到,MMON进程负责处理对象的统计信息。

从trace中可以看到大量的cursor包含了太多的子游标,例如:

User=b1456358 Session=c146d760 ReferenceCount=1 Flags=CNB/[0001] SavepointNum=558d5760

LibraryHandle: Address=2f79eb08 Hash=3dec6f4a LockMode=N PinMode=0 LoadLockMode=0 Status=VALD

ObjectName: Name= select time_mp, scn, num_mappings, tim_scn_map from smon_scn_time where scn = (select max(scn) from smon_scn_time where scn <= :1) FullHashValue=c36d5a579fdc3e19733192893dec6f4a Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=1038905162 OwnerIdn=0

Statistics: InvalidationCount=0 ExecutionCount=23741 LoadCount=107 ActiveLocks=1 TotalLockCount=6093 TotalPinCount=1

Counters: BrokenCount=1 RevocablePointer=1 KeepDependency=106 KeepHandle=106 BucketInUse=6092 HandleInUse=6092

Concurrency: DependencyMutex=2f79ebb8(0, 0, 0, 0) Mutex=2f79ec30(0, 87578, 0, 0)

Flags=RON/PIN/TIM/PN0/DBN/[10012841]

WaitersLists:

Lock=2f79eb98[2f79eb98,2f79eb98]

Pin=2f79eba8[2f79eb78,2f79eb78]

Timestamp: Current=04-05-2015 09:48:42

LibraryObject: Address=dff3bc60 HeapMask=0000-0001-0001 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]

ChildTable: size='112'

Child: id='0' Table=dff3cb60 Reference=dff3c5b0 Handle=2f79e908

Child: id='1' Table=dff3cb60 Reference=dff3c8e0 Handle=2f4e2d90

Child: id='2' Table=dff3cb60 Reference=df3e7400 Handle=2f8c9e90

Child: id='3' Table=dff3cb60 Reference=df3e76e8 Handle=2f8abce8

......

......

Child: id='101' Table=dc86f748 Reference=df02d368 Handle=288e6460

Child: id='102' Table=dc86f748 Reference=dd65c3e0 Handle=274d0b40

Child: id='103' Table=dc86f748 Reference=dd65c6c8 Handle=29aa92f8

Child: id='104' Table=dc86f748 Reference=dd65c9b8 Handle=26f3a460

Child: id='105' Table=dc86f748 Reference=dd65ccd0 Handle=25c02dd8

NamespaceDump:

Parent Cursor: sql_id=76cckj4yysvua parent=0x8dff3bd48 maxchild=106 plk=y ppn=n

Current Cursor Sharing Diagnostics Nodes:

......

......

Child Node: 100 ID=34 reason=Rolling Invalidate Window Exceeded(2) size=0x0

already processed:

Child Node: 101 ID=34 reason=Rolling Invalidate Window Exceeded(2) size=0x0

already processed:

类似上面的信息非常多。很明显,上述parent cursor包含了大量的子游标,这是为什么在20点-21点(节点2还未重启前的时段)的awr报告中出现大量cursor: mutex S 的原因,如下是这个时段的等待事件:

EventWaitsTime(s)Avg wait (ms)% DB timeWait Class
DB CPU47,07293.05
cursor: mutex S31,751,31718,253136.08Concurrency
gc cr multi block request359,8971,28142.53Cluster
gc buffer busy acquire10,465686661.36Cluster
library cache lock9,285550591.09Concurrency

在mmon正常通过内部SQL收集系统信息时,根本不应该出现这种情况,而此时MMON进程却出现异常,这个异常看来应该是与cursor子游标过多有关了。

9、最后数据库实例被强行终止的原因是lck0进程出现异常导致lmhb进程强行终止instance

在最后instance终止之前的diag dump中,lck0进程的状态仍然是hang的状态,同时也阻塞了3个其他session,如下:

SO: 0x9914dbce8, type: 4, owner: 0x9911283b0, flag: INIT/-/-/0x00 if: 0x3 c: 0x3

proc=0x9911283b0, name=session, file=ksu.h LINE:11467, pg=0

(session) sid: 1729 ser: 3 trans: (nil), creator: 0x9911283b0

flags: (0x51) USR/- flags_idl: (0x1) BSY/-/-/-/-/- flags2: (0x408) -/- DID: , short-term DID:

txn branch: (nil) oct: 0, prv: 0, sql: (nil), psql: (nil), user: 0/SYS

ksuxds FALSE at location: 0

service name: SYS$BACKGROUND

Current Wait Stack:

Not in wait; last wait ended 1 min 39 sec ago

There are 3 sessions blocked by this session.

Dumping one waiter: inst: 2, sid: 1009, ser: 1

wait event: 'latch: object queue header operation'

p1: 'address'=0x993cfec60

p2: 'number'=0xa2

p3: 'tries'=0x0

row_wait_obj#: 4294967295, block#: 0, row#: 0, file# 0

min_blocked_time: 81 secs, waiter_cache_ver: 14285

Wait State:

fixed_waits=0 flags=0x20 boundary=(nil)/-1

对于数据库进程,如果状态不是dead,而是busy,而且持有latch不释放,那么这意味着该进程已被挂起,lck0 持有的latch是object queue header operation。oracle mos文档也有关于该event 的描述如下:Scans of the object queue in the buffer cache can hold the "object queue header operation"。

基于上述的分析,我们最终判断,lck0 进程出现问题的原因与cursor 子游标过多有关。同时,这又与在11.2.0.1版本上的child cursor总数阀值限制过高有关(实际在版本10g中就引入了该Cursor Obsolescence游标废弃特性,10g的child cursor 的总数阀值是1024,即子游标超过1024即被过期,但是这个阀值在11g的初期版本中被移除了。这就导致出现一个父游标下大量child cursor即high version count的发生;由此引发了一系列的版本11.2.0.3之前的cursor sharing 性能问题。这意味着版本11.2.0.1和11.2.0.2的数据库,将可能出现大量的Cursor: Mutex S 和 library cache lock等待事件这种症状,进而诱发其他故障的发生。

因此, 强烈建议11.2.0.3以下的版本应尽快将数据库版本升级到11.2.0.3以上(11.2.0.3中默认就有”
_cursor_obsolete_threshold”了,而且默认值为100),或者通过_cursor_features_enabled 和106001 event来强制控制子游标过多的情况。

3. 结案陈词

该案例的分析还是有些曲折,因为常见导致单节点故障最常见的情况主要是心跳、节点资源之类,而该案例的诱发原因相对有些诡异,先是出现了ora-600错误,然后又报了kill mmon的信息,这都让案情分析有些扑朔迷离,当然,最终我们还是找出了问题的主要根源。

通过该起案件我们发现:

  1. 数据库版本的选择绝对是影响系统稳定性的关键要点;

  2. 不要以为性能问题只是影响用户体验,有些性能问题是会诱发系统一系列问题的;

  3. 问题的分析不要想当然,通过trace逐步递进,结合原理与经验,才能更为准确的确定问题;

  4. 子游标过多千万不能小视,最好能找出根源并解决它,如果确实不好解决,那么可通过设置隐含参数_cursor_features_enabled 和106001 event强制失效子游标的方式来防止子游标过多的情况,操作如下:

SQL> alter system set "_cursor_features_enabled"=300 scope=spfile;

SQL> alter system set event='106001 trace name context forever,level 1024' scope=spfile;

正常重启数据库即可。

Q&A

1、在什么情况下可以重用父游标和子游标呢?

父游标只要SQL代码共享就可以重用,子游标的要求的比较多,特别是当使用了绑定变量或者谓词字段的数据分布倾斜的时候,很容易出现多个子游标的情况,具体子游标不能共享的原因,可以查v,这个视图里的一堆字段表明了某个特定父游标的子游标不能共享的各种原因

2、请问一下,监测rac心跳能否用直连网线?一般你们怎么做?

rac的心跳从原理上是可以使用直连网线的,但无论是稳定性还是传输速率都不能完全满足心跳的要求,因此Oracle从9i开始,在白皮书里明确写了不允许使用直连线的方式,主要就是出于心跳稳定和传输速率考虑。其实如果心跳压力非常小的话,用直连肯定也可以,只是用rac的大部分是核心,一般不愿意去冒险。

3、能不能简单说下 rac 的高可用和我们平时做的双机热备有哪些区别呀。

rac的高可用是两节点的数据库实例同时可用,而传统的ha则只是在一个节点上可用实例,另一个节点的实例并没有启动,因此,简单来说,rac比ha至少在高可用能力上更强(两节点同时在用,一旦单节点故障,故障节点的会话可以无缝切换到另一可用节点,前端没有业务中断的感觉,当然,这个需要配置好才行),而ha一旦单节点故障,业务一定得中断,等待另一节点实例起来之后才能连接。 同时,rac也能同时发挥两台机器的效能,而ha的一个节点完全是浪费着(有的用户为了避免这种浪费,就把两个库分别在ha的两个节点运行,让两节点的两个库互为热备)

4、请问除了子游标以外,还有哪些因素会导致,RAC宕机或者导致其不稳定。

rac不稳定的因素很多,最典型的就是心跳线不稳定或者心跳线出现数据风暴,此外,11g的DRM特性也很容易导致rac单节点宕机,一般我们都会建议禁用DRM特性。此外,11g还有很多新特性都会诱发节点宕机,比如我们以前还遇到过由于asm实例内存太小,而在rac的asm上部署的数据库太多导致asm实例挂掉,从而导致rac库宕掉的。原因很多了

5、能否简单介绍下 在 oracle优化中对游标的优化思路与RAC常用优化方向。

游标的优化思路,最简单也是最根本的就是在适当的场景下用绑定变量,在不该用的时候不要乱用绑定。比如,谓词倾斜的字段就极度不适合绑定。另外,统计信息的准确性,尤其是倾斜字段的统计信息准确性也直接影响着子游标的产生。还有一些参数也要注意,特别是cursor_sharing,宁愿设置成force,也尽量不要用similar,similar很容易遭遇bug,导致一堆子游标撑爆shared pool。最后就是我们那个案例中的不同版本对子游标数的限制,不能放任子游标无穷增长。

rac的优化牵扯面比较多,我先零零星星写一些吧,太多了。比如sequence,在rac下一定要开启cache,而且不能太小,我们对于一些常用的sequence甚至建议开启cache到500以上,决不能使用order。

再比如如果发现GC的enq特别多,那么就要考虑做业务分割,把操作不同表的会话连接到不同的节点实例上,减少两节点对同一张表的征用。

6、请说一下,RAC宕机的处理思路,谢谢。

对于宕机,基本上都是从数据库的alert.log看起,一般告警日志里都会有最后宕掉时数据库做的事情,甚至有更为详细的trace文件信息,那么就需要根据这些信息结合rac各进程的关系来进行分析,这个的确不是一两句话能说的完的。总之,肯定是要看数据库告警日志和crs日志的,asm的日志有时候也要看。而导致宕机的原因同样五花八门,有些是系统原因,比如asm存储阵列出问题、光纤链路不稳定、swap耗尽等等,有些是数据库问题,比如心跳检测超时,为了恢复出问题的节点,自动宕掉那个节点重启,比如由于一些数据库的bug或者异常导致Oracle的某些关键进程被强制杀掉之类。。。可能性非常多了

相关推荐

MYSQL数据同步(mysql数据同步方式)

java开发工程师在实际的开发经常会需要实现两台不同机器上的MySQL数据库的数据同步,要解决这个问题不难,无非就是mysql数据库的数据同步问题。但要看你是一次性的数据同步需求,还是定时数据同步,亦...

SpringBoot+Redis实现点赞收藏功能+定时同步数据库

由于点赞收藏都是高频率的操作,如果因此频繁地写入数据库会造成数据库压力比较大,因此采用redis来统计点赞收藏浏览量,之后定时一次性写入数据库中,缓解数据库地压力。一.大体思路设计redis中的储存结...

双11订单洪峰:Codis代理层如何扛住Redis集群搞不定的120万QPS?

双11订单洪峰下的技术挑战每年的双11购物节,都是对电商平台技术架构的极限考验。当零点钟声敲响,海量用户瞬间涌入,订单量呈指数级增长,系统需要承受每秒数十万甚至上百万次的请求。作为电商系统的核心组件之...

基于spring boot + MybatisPlus 商城管理系统的Java开源商城系统

前言Mall4j项目致力于为中小企业打造一个完整、易于维护的开源的电商系统,采用现阶段流行技术实现。后台管理系统包含商品管理、订单管理、运费模板、规格管理、会员管理、运营管理、内容管理、统计报表、权限...

商品券后价产品设计方案(显示券后价)

如何设计一套高效、准确且稳定的券后价计算系统,是电商产品设计中的关键挑战之一。本文详细介绍了商品券后价的产品设计方案,从背景目标、功能设计、系统实现逻辑到异常处理机制等多个方面进行了全面阐述。一、背景...

外观(门面)模式-Java实现(java 门面模式)

定义外观模式(FacadePattern),也叫门面模式,原始定义是:为了子系统中的一组接口提供统一的接口。定义一个更高级别的接口,使子系统更易于使用。大大降低应用程序的复杂度,提高了程序的可维护性...

Mall - 用 SpringBoot 实现一个电商系统

目前最为主流的Web开发技术,包括SpringBoot、MyBatis、MongoDB、Kibina、Docker、Vue等,都是开发者十分需要掌握的技术。有没有一个全面而又实际的项目,能把这...

腾讯云国际站:哪些工具能实现可视化运维?

本文由【云老大】TG@yunlaoda360撰写开源工具Grafana:开源的可视化平台,可与Prometheus、Elasticsearch、MySQL等多种数据源集成,将复杂监控数据转化...

系统稳定性保障全流程实战:事前、事中、事后 Java 代码详解

在互联网架构中,系统稳定性是生命线。本文基于“事前预防、事中管控、事后复盘”三阶段模型,结合Java实战代码,深度解析如何构建高可用系统,让你的服务稳如磐石!一、事前:未雨绸缪,筑牢防线1.发...

Java面试题:拆分微服务应该注意哪些地方方,如何拆分?

在拆分微服务时,需要综合考虑业务、技术和组织等多方面因素,以下是关键注意事项及拆分策略的详细说明:一、拆分注意事项1.业务边界清晰化单一职责原则:每个服务应专注于单一业务能力,例如订单服务仅处理订单...

软件性能调优全攻略:从瓶颈定位到工具应用

性能调优是软件测试中的重要环节,旨在提高系统的响应时间、吞吐量、并发能力、资源利用率,并降低系统崩溃或卡顿的风险。通常,性能调优涉及发现性能瓶颈、分析问题根因、优化代码和系统配置等步骤,调优之前需要先...

Docker Compose实战,多容器协同编排的利器,让开发部署更高效!

开篇导读你是否有过这样的经历?启动一个项目,数据库、Redis、Web服务得一个个敲dockerrun?想让别人复现你的开发环境,却得发一堆复杂的启动命令?明明都是容器,为什么不能“一键启动”所...

如何设计Agent的记忆系统(agent记忆方法)

最近看了一张画Agent记忆分类的图我觉得分类分的还可以,但是太浅了,于是就着它的逻辑,仔细得写了一下在不同的记忆层,该如何设计和选型先从流程,作用,实力和持续时间的这4个维度来解释一下这几种记忆:1...

不了解业务和技术术语怎么做好产品和项目?

基础技术术语术语分类解释API开发技术应用程序接口,不同系统间数据交互的协议(如支付接口、地图接口)。SDK开发工具软件开发工具包,包含API、文档和示例代码,帮助快速接入服务。RESTfulAPI...

Docker 架构详解与核心概念实战图解:一文读懂容器的前世今生

不懂Docker架构,你只是“用容器的人”;理解了它的底层逻辑,才能成为真正的高手!在学习Docker之前,很多同学可能会陷入一个误区:“反正我用dockerrun就能跑起服务,架构这种...

取消回复欢迎 发表评论: