love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

About enq: TX – row lock contention deadlock?

本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

本文链接地址: About enq: TX – row lock contention deadlock?

以前一个客户今天联系我,有个死锁的问题,如下的客户提供的信息,看上去有点意思,如下:

可以看到这是同一个表的不同的2行数据,在进行DML操作的时候出现了死锁。下面我们来看下Mode是多少:

这里的event是enq: TX – row lock contention,而54580006其实是分为2部分,前面是Name,后面的0006是mode。

从执行计划来看,出现了INLIST ITERATOR操作,这是一个迭代操作。说明sql是根据or或in操作有关系,这一点从前面的SQL可以看出来。

下面我在自己的10.2.0.4环境进行模拟一下,再现这个问题。

下面分别开2个会话窗口来进行模拟:

我们可以看到,成功模拟出了这个ora-00600死锁的情况,下我们来看下trace 文件的内容:

接着我们来看下这个process的dump信息:

搜索Plan关键字,可以定位到该SQL的执行计划:

我们可以看到执行计划中出现了INLIST ITERATOR。至于Or的情况,大家可以自行模拟。不过我这里模拟的情况和客户的实际情况
还是有一点细微差异,他这里的执行计划中还有一个回表的操作:TABLE ACCESS BY INDEX ROWID

不过,这个模拟已经可以说明问题了。对于enq: TX – row lock contention的死锁,如果Mode=6,那么其实只有这样一样情况。

这里需要我们注意的是,有些人以为这里是row lock contention,那么肯定是因为Index的关系,其实这是错误的理解。

对于row的操作,Oracle首先会申请一个表级别的TM锁,然后再申请Tx. 这里是否存在Index其实一点关系都没有.

为了说明这一点,我drop掉Index,一样会出现这个死锁,如下:

其中process dump如下:

此时的SQL执行计划肯定是全表扫描了,如下:

说了这么多,对于这种enq: TX – row lock contention 死锁,如果mode=6,那么唯一的解决方法就是kill 会话或者调整业务逻辑。

如果你遇到的enq: TX – row lock contention 死锁的mode为4即使shared mode,那么请检查如下几个方面是否存在问题:

1) ITL争用,建议调整INITRANS
2)涉及unique Index,那么说明index可能涉及到重复键值
3)检查是否用了位图Index。
如果是TM死锁,那么通常是外键缺乏Index导致。

Leave a Reply

You must be logged in to post a comment.