谈笑有鸿儒,往来无白丁

在恰当的时间、地点以恰当的方式表达给恰当的人...  阅读的时候请注意分类,佛曰我日里面是谈笑文章,其他是各个分类的文章,积极的热情投入到写博的队伍中来,支持blogjava做大做强!向dudu站长致敬>> >

os环境:windows server 2008 64位

数据库版本:11.2.0

 

今天在使用rman备份的时候随意的查看了一下等待事件,除了了我们现在系统遇到的io瓶颈外,还额外的发了enq: tx - row lock contention等待事件

 

1:查询当前系统的等待事件

 

select event,sid,p1,p2,p3 from v$session_wait where event not like 'sql*%' and event not like 'rdbms%';


event                                   sid         p1              p2             p3
----------------------------------     ----      ----------       ----------    ----------
enq: tx - row lock contention     4    1415053318     196638        55836
rman backup & recovery i/o      5            1               256       2147483647
enq: tx - row lock contention    12    1415053318     524293        51153
rman backup & recovery i/o     25           1                256      2147483647
db file sequential read             27          16             2876703         1
pmon timer                             33         300                0               0
db file scattered read               39          33              790536         128
vktm logical idle wait            49           0                   0               0
streams aq: qmn slave idle wait         50          1          0          0
asynch descriptor resize           53          1              4294967295    1237
jobq slave wait                       54          0                     0          0

 

event                                   sid         p1           p2                 p3
-------------------------------------------    -------       ----------          ----------
db file sequential read             170         33         1100519            1
direct path read                      181         44          469892           124
enq: tx - row lock contention    212 1415053318     524293         51153
smon timer                             225        300          0       0
enq: tx - row lock contention    232 1415053318     524293         51153
direct path read                      234         16           1099776         128
streams aq: qmn coordinator idle wait  242          0          0         0

 

 

上面的等待事件说明session4,12,212,232想加锁,但是有别的session占着,所以等待。

 

 

enq是一种保护共享资源的锁定机制,一个排队机制,先进先出(fifo)

发生tx锁的原因一般有几个

1.不同的session更新或删除同一个记录。

2.唯一索引有重复索引

3.位图索引多次更新

4.同时对同一个数据块更新

5.等待索引块分裂

 

 

2:下面我们通过enq: tx - row lock contention来看看这些session都在等什么

 

select row_wait_obj#,row_wait_file#,row_wait_block#,row_wait_row# from v$session where event='enq: tx - row lock contention';

 

row_wait_obj# row_wait_file# row_wait_block# row_wait_row#
------------- -------------- --------------- -------------
        87556             57             395            88
        87564             57             435             0
        87564             57             435             0
        87564             57             435             0
        87564             57             435             0

 

 

 


3:通过上面sql查找出来的对象编号找到对应的对象名称

 

sql> select object_name from dba_objects where object_id in (87564);

object_name
-----------
qrtz_locks

 

 

4:通过对象名称找出该对象的对应属性,对象属性为table

 

sql> select owner,object_name,object_id,data_object_id, object_type from all_objects where object_name='qrtz_locks';

 

owner      object_name  object_id data_object_id object_type

schedule   qrtz_locks     87564          87564               table 

 

5:通过正在等待的sid查看它们都在执行什么操作

sql> select sid,sql_text from v$session a,v$sql b where sid in(4,12,41,212,232) and (b.sql_id=a.sql_id or b.sql_id=a.prev_sql_id);

 sid sql_text
---- ----------------------------------------------------------------------------------------------------
   4 update qrtz_cron_triggers set cron_expression = :1 where trigger_name = :2 and trigger_group = :3
  12 select * from qrtz_locks where lock_name = :1 for update
  41 select * from qrtz_locks where lock_name = :1 for update
 212 select * from qrtz_locks where lock_name = :1 for update
 232 select * from qrtz_locks where lock_name = :1 for update

 

从上面的结果可以看出,schedule用户下的五个session同时在执行一条相同的sql语句,对应的对象则是qrtz_locks 这个表, 所以发生了锁,从而产生等待,通过和同事的交流,得知这个一个etl程序要访问的表,里面只有五条数据,但是却要时时调度。  

6:下面我们去找一下对应sid产生的锁

 

sql> select sid,ty,id1,id2,lmode,request,ctime,block from v$lock where block=1 or request<>0;
         sid ty        id1        id2      lmode    request      ctime      block
 ---------------- ---- -- ---------- ---------- ---------- ---------- ---------- ----------
         41  tx     524293      51153          0          6       3846             0
         12  tx     524293      51153          0          6       4190             0
         232 tx     524293      51153          0          6       4626             0
         212 tx     524293      51153          0          6       4749             0
      
    4  tx     196638      55836          0          6       4755              1
         44  tx     196638      55836          6          0       4765              1

 

由此可以查看,block=1的sid是该等待事件的根源,其他session则等待该锁被释放。

解决方法:

1:通过v$session找到block=1的用户,告知用户提交事务

2:通过sid找到pid,kill掉该进程

3:更改sql语句,select * from qrtz_locks where lock_name = :1 for update no wait

加nowait的意思是得到或者得不到,不会等待

posted on 2015-03-20 15:20 坏男孩 阅读(1470) 评论(0)  编辑  收藏 所属分类: oracle篇章
网站地图