enq: TX - row lock contention事件测试与跟踪

enq: TX - row lock contention事件:表的行锁等待事件。

查询资料获取:row lock contention事件产生的原因有以下五种:

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

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

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

4、第四种情况:调用dbms_repair包时也会产生TX--在网上看到的,具体怎么个原理,后面有空再研究该包

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

    Bug 3159414    documents another case where we might see a TX request in mode 4 when constraints are involved.

    Bug 5849679    documents an undetected deadlock case with RAC.

产生该等待事件的原因基本上就是上面五种情况,前三种优为常见。

一、创建一个enq: TX - row lock contention 锁(使用行操作的方式)

    创建临时表bd_ma


enq: TX - row lock contention事件测试与跟踪_第1张图片
临时表bd_ma

    然后打开一个sql窗口(创建一个session)执行delete命令,但不提交


enq: TX - row lock contention事件测试与跟踪_第2张图片
delete不提交

再打开一个sql窗口(再创建一个session)也执行delete命令


enq: TX - row lock contention事件测试与跟踪_第3张图片
新session执行delete

此时就可以发现该命令一直等待上一个delete结束,此时即创造了一个enq: TX - row lock contention事件。


二、被用户创建后,如何在当时找到该事件,并处理

1、视图v$session中事件等于enq: TX - row lock contention的

enq: TX - row lock contention事件测试与跟踪_第4张图片
v$session视图

sid = 37的session在等待


2、同样通过v$session找到处理的对象

enq: TX - row lock contention事件测试与跟踪_第5张图片
找到对应的对象

obj_id = 91674,该对象可能是表也可能是索引或者其他的

3、看下该对象是什么查找dba_object表,中id = 91674的

enq: TX - row lock contention事件测试与跟踪_第6张图片

发现该对象是表,名称是bd_ma.

到此知道发生行锁等待事件的对象是bd_ma这个表造成的。

4、继续找到是哪个用户在执行什么操作造成:

同样通过v$session去找,发现osuser是derek,即客户端是derek这台客户端造成的,信息部可以追踪到该客户端的使用用户。

找客户端


5、找到是哪个语句造成的,通过v$session和v$sql找到sqltext。

enq: TX - row lock contention事件测试与跟踪_第7张图片
找sqltext

到此就可发现是因为delete命令一直没有提交造成。


三、若是历史AWR中如何找到线索?

1、通过dba_hist_active_sess_history找到发生过enq: TX - row lock contention事件的session_id.sql_id

enq: TX - row lock contention事件测试与跟踪_第8张图片
dba_hist_active_sess_history

发现历史有两个,分别是session = 40和session = 15。
2、找到对应的session具体信息,是哪个machine

enq: TX - row lock contention事件测试与跟踪_第9张图片
v$active_session_history

3、找到当时发生时候的语句。

enq: TX - row lock contention事件测试与跟踪_第10张图片
v$sql v$active_session_history


附当时发生时候跟踪的所有sql

--找到发生enq: TX - row lock contention的等待事件

select event,sid,p1,p2,p3 from v$session_wait where event = 'enq: TX - row lock contention';

--1 enq: TX - row lock contention 37 1415053318 589833 1934

--看这些session在等什么对象

select event, ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW# from v$session

where event='enq: TX - row lock contention';

--1 enq: TX - row lock contention 91674 5 10441 0

--说明在等91674这个对象

--看91674这个对象是什么

select object_name,object_id,owner,object_type from dba_objects where object_id='91674';

--1 BD_MA 91674 NC633 TABLE                原来是table

--另,查看是什么语句造成的等待事件,填入等待事件的sid

select sid,sql_text from v$session a,v$sql b where sid in('37')

and (b.sql_id=a.sql_id );

--看下是哪里的客户端造成的

select sid,serial#,username,status,osuser,machine,port,terminal,program,sql_id,sql_exec_start,prev_sql_id, type from v$session where sid = '37'

--1 37 162 NC633 ACTIVE derek WORKGROUP\DEREKPC 60452 DEREKPC plsqldev.exe 8tzau2c2gbdtr 2015/8/12 13:45:58 9m7787camwh4m USER

select * from v$lock where type = 'TX';

select s.sid, q.sql_id,q.SQL_FULLTEXT

from v$session s, v$sql q

where sid in

(select sid

from v$session

where state in ('WAITING')

and wait_class != 'Idle'

and event = 'enq: TX - row lock contention'

and (q.sql_id = s.sql_id or q.sql_id = s.prev_sql_id));


附历史发生时候查找的sql

--查找历史发生过enq: TX - row lock contention事件的记录

select session_id,session_serial#,sql_id from dba_hist_active_sess_history

where event = 'enq: TX - row lock contention' order by sample_time;

--找到session_id 和sql_id是1 40 298 8tzau2c2gbdtr

-- 77 15 680 8tzau2c2gbdtr

--查看对应session_id的信息

select distinct session_id,sql_id,sql_opname,program,module,action,machine from v$active_session_history where session_id in ('40','15')

and event = 'enq: TX - row lock contention'

and is_awr_sample = 'Y'

--查看对应session执行的语句

select -- s.SAMPLE_TIME,

distinct s.SESSION_ID,

sq.SQL_TEXT,

--sq.SQL_FULLTEXT,

sq.SQL_ID

from v$sql sq, v$active_session_history s

where s.SQL_ID = sq.SQL_ID

and s.SESSION_ID in ('15','40')

and sq.SQL_ID = '8tzau2c2gbdtr'


附参考:

enq: TX - row lock contention等待事件http://blog.csdn.net/songyang_oracle/article/details/6433753

解决一则enq: TX - row lock contention的性能故障http://www.oracleonlinux.cn/2012/11/resolve-row-lock-contention/

oracle的TM锁、TX锁
http://blog.sina.com.cn/s/blog_95b5eb8c0101i22x.html 


结语:不适合写这种文章……以后不写了。字体都太大了~~~看起来好累

你可能感兴趣的:(enq: TX - row lock contention事件测试与跟踪)