enq是一种保护共享资源的锁定机制,一个排队机制
排它机制从一个事务的第一次改变直到rollback or commit 结束这个事务,
TX等待mode是6,当一个session 在一个表的行级锁定时另一个会话总是等待,一般发生在一些用户insert or update,而另一个用户同样也在insert or update 这同一批数据时发生。这种类型的等待通常就是eventenq:TX-rowlockcontention.解决方法是让第一个会话commit or rollback 结束这个事务
tx等待mode如果是4,这种一般发生在同时更新一个数据块上的数据,但不一定是同一条记录,这就是传说种的热块,这里有一个概念就是ITL(interested transaction list),有一个建表参数maxtrans ,也就是说允许一个块上有多少个active transaction, 不过到了oracle 10G,这个参数被放弃,默认最大为255,这种类型的等待通常叫eventenq:TX-allocateITLentry
对于这种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导致。
这里的event是enq: TX - row lock contention,而54580006其实是分为2部分,前面是Name,后面的0006是mode。
============
Plan Table
============
-----------------------------------------------------+-----------------------------------+
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------+-----------------------------------+
| 0 | UPDATE STATEMENT | | | | 16 | |
| 1 | UPDATE | MMSPLT | | | | |
| 2 | INLIST ITERATOR | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | MMSPLT | 86 | 430 | 16 | 00:00:01 |
| 4 | INDEX RANGE SCAN | MMSPLT_IDX02| 124 | | 4 | 00:00:01 |
-----------------------------------------------------+-----------------------------------+
从执行计划来看,出现了INLIST ITERATOR操作,这是一个迭代操作。说明sql是根据or或in操作有关系,这一点从前面的SQL可以看出来。
tx mode is 4 也是有可能导致那个等待,就是多次更新位图索引时,TX原因还有很多,如下:
1.不同的session更新或删除同一个记录。
2.唯一索引有重复索引
3.位图索引多次更新
4.同时对同一个数据块更新
5.等待索引块分裂
简单可以通过以下查询
#对于当前时间下
select sid,username,event,wait_class,command from v$session where state in('WAITING') and wait_class<>'Idle';
select ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW# from v$session where event='enq: TX - row lock contention';
# 对于过去时间的
/*
col file# for 99999
col block# for 999999
col obj for a18
col type for a9
col lm for 99
col bsid for 9999
*/
----row lock
select sid,
chr(bitand(p1, -16777216) / 16777215) ||
chr(bitand(p1, 16711680) / 65535) "Name",
(bitand(p1, 65535)) "Mode"
from v$session_wait
where event = 'enq: TX - row lock contention';
select count(*) cnt,
session_id sid,
substr(event, 1, 30) event,
mod(p1, 16) as lm,
sql_id,
CURRENT_OBJ# || ' ' || object_name obj,
o.object_type type,
CURRENT_FILE# file#,
CURRENT_BLOCK# block#,
blocking_session bsid
from v$active_session_history ash, all_objects o
where event like 'enq: T%'
-- and SAMPLE_TIME between xx and xx
and o.object_id(+) = ash.current_obj#
group by event,
session_id,
p1,
sql_ID,
CURRENT_OBJ#,
OBJECT_NAME,
OBJECT_TYPE,
CURRENT_FILE#,
CURRENT_BLOCK#,
BLOCKING_SESSION
order by count(*)
------------
#Show which segments have undergone the most row lock waits:
SELECT owner, object_name, subobject_name, value
FROM v$segment_statistics
WHERE statistic_name='row lock waits'
AND value > 0
ORDER BY 4 DESC;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。