oracle job enq tx,oracle 等待事件 enq TX - row lock contention

产生原因:

第一种情况:当两个会话对同一行进行更新时,ORACLE为了保证数据库的一致性,加了一个TX锁,这时另一个或多个会话必须等待第一个会话commit或rollback,否则会一等待下去,这是最为常见的一种模式!

第二种情况:两个或多个会话向具有唯一主健索引的表中插入或更新相同的数据行,既然是唯一主健索引,那么先获得插入的session以TX排它锁模式进行添加,此时其它session只能等待,也是常见的一种情况

第三种情况:两个或多个会话插入或更新具有位图索引的列,跟据位图索引的特性,一个索引键值对应多个数据行的rowid值,此种情况下也是以TX模式访问,一般在OLTP系统中很少有位图索引,但不排除个别系统。

第四种情况:调用dbms_repair包时也会产生TX

第五种情况:由ORACLE BUG引起的

Bug 5849679 - Undetected deadlock in RAC involving a TM lock

产生该等待事件的原因基本上就是上面五种情况,前三种优为常见,那么跟据本例中的

模拟环境:

会话1执行:

create table test

( id number(10),

name varchar2(16)

) ;

insert into test values(1001, 'kk');

insert into test values(1002, 'tttt');

commit;

SQL> update test set name='ken' where id=1001;

1 row updated.

会话2执行:

SQL> update test set name='kerry' where id=1001;

会话2 被hang 住

会话3 执行:

找出出现该等待事件的会话及sql

set lines 1000

col USERNAME for a20

col SQL_FULLTEXT for a50

col EVENT for a50

col SQL_ID for a20

col STATUS for a10

select a.sid,

a.SERIAL#,

a.EVENT,

a.USERNAME,

a.BLOCKING_SESSION, ----锁的持有者的sid

b.sql_id,

b.SQL_FULLTEXT,

a.SECONDS_IN_WAIT -----等待时间

from gv$session a, v$sql b

where a.EVENT = 'enq: TX - row lock contention'

and a.SQL_ID = b.SQL_ID;

51fbe4f788a4c495e1d95eeca856d722.pnghttps://www.cndba.cn/leo1990/article/2769

https://www.cndba.cn/leo1990/article/2769

https://www.cndba.cn/leo1990/article/2769

找到等待的热块信息

select blocking_session,sid,serial#,wait_class,seconds_in_wait

from v$session

where blocking_session is not NULL

and sid in(' 33');

9a81135cd08e8837ccc5cf324f3861fa.pnghttps://www.cndba.cn/leo1990/article/2769https://www.cndba.cn/leo1990/article/2769

查询阻塞会话的sid

select sid,serial#,machine,program,EVENT,SQL_ID,STATUS from v$session where sid in('1');

4caeadd6f2868346e392dcee1df70ab5.pnghttps://www.cndba.cn/leo1990/article/2769https://www.cndba.cn/leo1990/article/2769

https://www.cndba.cn/leo1990/article/2769https://www.cndba.cn/leo1990/article/2769

https://www.cndba.cn/leo1990/article/2769

确认之后杀掉这个阻塞会话

alter system kill session '1,7';

rac 执行命令alter system kill session 'sid,serial#,@1';

也可以系统层面杀进程

select spid from v$process where addr in (select paddr from v$session where sid=1);

SPID

------------------------

3258

kill -9 3258

杀掉阻塞会话之后,会话2正常更新。

SQL> update test set name='kerry' where id=1001;

1 row updated.

在会话3 查看没有阻塞

SQL> set lines 1000

col USERNAME for a20

col SQL_FULLTEXT for a50

col EVENT for a50

col SQL_ID for a20

col STATUS for a10

select a.sid,

a.SERIAL#,

a.EVENT,

a.USERNAME,

a.BLOCKING_SESSION, ----锁的持有者的sid

b.sql_id,

b.SQL_FULLTEXT,

a.SECONDS_IN_WAIT -----等待时间

from gv$session a, v$sql b

where a.EVENT = 'enq: TX - row lock contention'

and a.SQL_ID = b.SQL_ID;

8 9 10 11

no rows selected

解决方案:

第一步:找到那些会话在等待

set lines 1000

col USERNAME for a20

col SQL_FULLTEXT for a50

col EVENT for a50

col SQL_ID for a20

col STATUS for a10

select a.sid,

a.SERIAL#,

a.EVENT,

a.USERNAME,

a.BLOCKING_SESSION, ----锁的持有者的sid

b.sql_id,

b.SQL_FULLTEXT,

a.SECONDS_IN_WAIT -----等待时间

from gv$session a, v$sql b

where a.EVENT = 'enq: TX - row lock contention'

and a.SQL_ID = b.SQL_ID;

第二步:找到等待的热块信息

select blocking_session,sid,serial#,wait_class,seconds_in_wait

from v$session

where blocking_session is not NULL

and sid in(sid);

第三步:杀掉seconds_in_wait=0的会话,即可解决现实问题

alter system kill session 'sid,serail#'

第四步:跟据SQL_ID找到对应的SQL,向开发人员反馈,修改相应的业务逻辑,是否可避免此类情况的发生

第五步:查看表和索引的统计信息是否过旧,及时收集表和索引的统计信息

版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值