用hanganalyze解决row cache lock

今天某省的一位同事来说,在执行一个split分区的脚本时长时间没有响应。登录上去查看,手工执行了split脚本,发现确实会hang住:

检查该session的等待事件:

查了网上的一些资料,说和sga的shared pool大小不足有关,或者和sequence的cache不大有关。经过分析,这2个原因应该都不是。因为1、如果是shared pool不足,这样的现象一般是某个sql执行的比较慢,但是还是会执行完,而不是像现在这样的挂住;2,只是执行split分区,并没有和sequence相关。

在这里,我们用hanganalyze来进行分析。

hanganalyze用法:

这里的level有如下几级:

我们现在来看看出来的trace文件:

我们来看看([nodenum]/cnode/sid/sess_srno/session/ospid/state/start/finish/[adjlist]/predecessor)部分:
nodenum是hanganalyze自己为了记录这些会话而定制的编号,从0开始排起。
cnode是Node Id
sid是 Session ID
sess_srno是serial#
proc_ptr是Process Pointer
ospid 是OS Process ID
state 是node的状态
adjlist是临近的node(通常代表一个blocker node)
predecessor是Predecessor node ,通常代表一个 waiter node

state部分有几个比较重要的状态:
1.IN_HANG:这表示该node处于死锁状态,通常还有其他node(blocker)也处于该状态
2.LEAF/LEAF_NW:该node通常是blocker。通过条目的”predecessor”列可以判断这个node是否是blocker。LEAF说明该NODE没有等待其他资源,而LEAF_NW则可能是没有等待其他资源或者是在使用CPU.
3.NLEAF:通常可以看作这些会话是被阻塞的资源。发生这种情况一般说明数据库发生性能问题而不是数据库hang
4.IGN/IGN_DMP:这类会话通常被认为是空闲会话,除非其adjlist列里存在node。如果是非空闲会话则说明其adjlist里的node正在等待其他node释放资源。
5.SINGLE_NODE/SINGLE_NODE_NW:近似于空闲会话

现在我们来看看我们的trace出来的文件:
Cycle 1 : :
<0/329/43816/0x4d6b5638/23487/row cache lock>
— <0/254/19761/0x4d687438/23307/library cache lock>
Cycle 2 : :
<0/295/57125/0x4d6b8978/19237/row cache lock>
Cycle 3 : :
<0/295/57125/0x4d6b8978/19237/row cache lock>

cycle表示oracle内部确定的死锁。其中我们的当前手工执行split的295进程也在里面。
我们观察其他的进程在做什么,如329:

发现也是在执行split语句,但是问了同事,他已经把之前运行失败的脚本完全kill掉了。
估计在数据库中进程挂死了,没有完全的释放。
kill掉329号进程后,发现还是挂住,所以我们继续做hanganlyze:

我们继续把其他的进程杀掉。终于295的split执行成功。

继续执行split下一个分区,也很快完成。

至此,问题解决。

相关文章

3条评论

  1. [238]/0/239/57618/0x4d7b18a0/13476/IN_HANG/395/402/[294][238][328][253]/none
    [253]/0/254/19761/0x4d7bb710/23307/IN_HANG/397/400/[328][238][294]/294
    [294]/0/295/57125/0x4d7d6820/19237/IN_HANG/396/401/[294][238][253]/238
    [328]/0/329/43816/0x4d7ecf40/23487/IN_HANG/398/399/[253]/253
    329堵塞住了254
    254堵塞住了295
    295堵塞住了238

    杀掉的应该是329,254,295这三个吧

回复 mengxb001 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据