如何找出引起enq:TX - row lock contention的记录

V$SESSION中有如下4个列,用来记录当发生enq:TX-row lock contention的时候,
导致挂起的行。

 ROW_WAIT_OBJ#                                      NUMBER  --包含该记录的OBJECT_ID
 ROW_WAIT_FILE#                                     NUMBER  --该记录所在的相对文件号
 ROW_WAIT_BLOCK#                                    NUMBER  --该记录所在的BLOCK号
 ROW_WAIT_ROW#                                      NUMBER  --该记录所在块中的行号


大部分人采用如下的SQL来查询引起堵塞的行:

select c.OBJECT_NAME,a.ROW_WAIT_OBJ#,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#,
dbms_rowid.rowid_create(1,c.OBJECT_ID,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#) rid 
from v$session a , v$enqueue_lock b, dba_objects c
where a.sid=b.SID and b.type='TX' and a.ROW_WAIT_OBJ#=object_id(+)

而且一般情况下是没问题的。
如下:

SESSION 1:

SQL> select rowid from test where rownum=1;

ROWID
------------------
AAp/YEAAFAACmXkAAA

SQL> delete from test where rownum=1;

1 row deleted.

SQL> 


SESSION 2:

SQL> update test set object_name=object_name where rownum=1;


SESSION 2将会被HANG住。


通过另外的SESSION执行如下的查询可以看到引起堵塞的记录是
TEST表的ROWID=‘AAp/YEAAFAACmXkAAA’的记录。

SQL> select c.OBJECT_NAME,a.ROW_WAIT_OBJ#,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#,
  2  dbms_rowid.rowid_create(1,c.OBJECT_ID,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#) rid 
  3  from v$session a , v$enqueue_lock b, dba_objects c
  4  where a.sid=b.SID and b.type='TX' and a.ROW_WAIT_OBJ#=object_id(+);

OBJECT_NAM ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# RID
---------- ------------- -------------- --------------- ------------- ------------------------------------
TEST            11007492              5          681444             0 AAp/YEAAFAACmXkAAA


SQL> select rowid,object_id from scott.test where rowid='AAp/YEAAFAACmXkAAA';

ROWID               OBJECT_ID
------------------ ----------
AAp/YEAAFAACmXkAAA        258

SQL> select rowid,object_id from scott.test where rowid='AAp/YEAAFAACmXkAAA' for update skip locked;

no rows selected



但是这是在TEST表的OBJECT_ID和DATA_OBJECT_ID一致的情况下才行。

SQL> select object_id,data_object_id from user_objects where object_name='TEST';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
  11007492       11007492
  
  一旦OBJECT_ID和DATA_OBJECT_ID不一样,那么查询结果将是错误的。
  
  因为V$SESSION.ROW_WAIT_OBJ#记录的是对象的OBJECT_ID
  而DBMS_ROWID.CREATE_ROWID需要的是对象的DATA_OBJECT_ID
  
 如下:
 
 SESSION 1:
 
SQL> alter table test move;

Table altered.

SQL> select object_id,data_object_id from user_objects where object_name='TEST';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
  11007492       11007579

SQL> select rowid from test where rownum=1;

ROWID
------------------
AAp/ZbAAFAACmjsAAA

SQL> delete from test where rownum=1;

1 row deleted.

SQL> 

SESSION 2:

SQL> update test set object_name=object_name where rownum=1;

将会HANG住。

SESSION 3:

SQL> select c.OBJECT_NAME,a.ROW_WAIT_OBJ#,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#,
  2  dbms_rowid.rowid_create(1,c.OBJECT_ID,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#) rid 
  3  from v$session a , v$enqueue_lock b, dba_objects c
  4  where a.sid=b.SID and b.type='TX' and a.ROW_WAIT_OBJ#=object_id(+)
  5  /

OBJECT_NAM ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# RID
---------- ------------- -------------- --------------- ------------- ------------------------------------
TEST            11007492              5          682220             0 AAp/YEAAFAACmjsAAA

SQL> SELECT rowid from scott.test where rowid='AAp/YEAAFAACmjsAAA';
SELECT rowid from scott.test where rowid='AAp/YEAAFAACmjsAAA'
                        *
ERROR at line 1:
ORA-01410: invalid ROWID

ROWID_CREATE中的C.ROW_WAIT_OBJ#需要改为DATA_OBJECT_ID才行。


SQL> select c.OBJECT_NAME,a.ROW_WAIT_OBJ#,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#,
  2  dbms_rowid.rowid_create(1,c.DATA_OBJECT_ID,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.ROW_WAIT_ROW#) rid 
  3  from v$session a , v$enqueue_lock b, dba_objects c
  4  where a.sid=b.SID and b.type='TX' and a.ROW_WAIT_OBJ#=object_id(+);

OBJECT_NAM ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# RID
---------- ------------- -------------- --------------- ------------- ------------------------------------
TEST            11007492              5          682220             0 AAp/ZbAAFAACmjsAAA

SQL> SELECT rowid from scott.test where rowid='AAp/ZbAAFAACmjsAAA';

ROWID
------------------
AAp/ZbAAFAACmjsAAA

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值