微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用DBMS_ROWID获取被阻塞行的rowid

在使用v$session视图在查询会话的行锁的等待事件时,视图中提供了会话等待的对象号(ROW_WAIT_OBJ#)、文件号(ROW_WAIT_FILE#)、块号(ROW_WAIT_BLOCK#)和行号(ROW_WAIT_ROW#)但是如何使用这些信息定位出会话等待的是哪一行呢?答案就是使用DBMS_ROWID

打开两个会话同时更新同一条数据

#session1
zx@ORCL>selectdistinctsidfromv$mystat;

SID
----------
	22

zx@ORCL>
zx@ORCL>updatezxsetname='zx'whereid=1;

1rowupdated.

#session2
zx@ORCL>selectdistinctsidfromv$mystat;

SID
----------
145

zx@ORCL>updatezxsetname='zx'whereid=1;

此时session2会被session1阻塞,查询v$session会话145在等待enq: TX - row lock contention

zx@ORCL>coleventfora40
zx@ORCL>selectSID,EVENT,ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#fromv$sessionwheresid=145;

SIDEVENT				ROW_WAIT_OBJ#ROW_WAIT_FILE#ROW_WAIT_BLOCK#ROW_WAIT_ROW#
---------------------------------------------------------------------------------------------------------
145enq:TX-rowlockcontention		99754	18	15571	7

查询v$lock确认会话145在请求会话22的TX锁

zx@ORCL>selectsid,type,id1,id2,lmode,requestfromv$lockwheresid=145orsid=22orderby1;

SIDTYPE	ID1	Id2lMODEREQUEST
--------------------------------------------------------
	22AE		100	0	4	0
	22TM	99754	0	3	0
	22TX	4390915	581	6	0
145TM	99754	0	3	0
145TX	4390915	581	0	6
145AE		100	0	4	0

使用如下语句查询会话145等待哪个表的哪个行

zx@ORCL>colownerfora10
zx@ORCL>colobject_namefora10
zx@ORCL>colrowidfora30
zx@ORCL>selectb.owner,b.object_name,dbms_rowid.rowid_create(1,s.ROW_WAIT_OBJ#,s.ROW_WAIT_FILE#,s.ROW_WAIT_BLOCK#,ROW_WAIT_ROW#)"rowid"fromv$sessions,dba_objectsbwheres.ROW_WAIT_OBJ#=b.object_idands.si
d=145;
OWNER	OBJECT_NAMrowid
--------------------------------------------------
ZX	ZX	AAAYWqAASAAADzTAAH
--使用上面查询出的rowid查看数据,即为session2等待的行
zx@ORCL>select*fromzx.zxwhererowid='AAAYWqAASAAADzTAAH';

	IDNAME
----------------------------------------
	1ZX

官方文档:http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_rowid.htm#ARPLS053

使用下面语句查找会话之间的阻塞关系

SELECT('节点'||a.inst_id||'session'||a.sid||','||a_s.serial#||
'阻塞了节点'||b.inst_id||'session'||b.sid||','||b_s.serial#)blockinfo,a.inst_id,a_s.sid,a_s.schemaname,a_s.module,a_s.status,a_s.event,a.typelock_type,a.id1,a.id2,decode(a.lmode,'none',1,NULL,2,'row-S(SS)',3,'row-X(SX)',4,'share(S)',5,'S/Row-X(SSX)',6,'exclusive(X)')lock_mode,a.ctimetime_hold,'后为被阻塞信息'remark_flag,b.inst_idblocked_inst_id,b.sidblocked_sid,b.typeblocked_lock_type,decode(b.request,'exclusive(X)')blocked_lock_request,b.ctimetime_wait,b_s.schemanameblocked_schemaname,b_s.moduleblocked_module,b_s.statusblocked_status,b_s.sql_idblocked_sql_id,b_s.event,obj.ownerblocked_owner,obj.object_nameblocked_name,obj.object_typeblocked_object_type,CASE
WHENb_s.row_wait_obj#<>-1THEN
dbms_rowid.rowid_create(1,obj.data_object_id,b_s.row_wait_file#,b_s.row_wait_block#,b_s.row_wait_row#)
ELSE
'-1'
ENDblocked_rowid,--被阻塞数据的rowid
decode(obj.object_type,'TABLE','select*from'||obj.owner||'.'||obj.object_name||
'whererowid='''||
dbms_rowid.rowid_create(1,b_s.row_wait_row#)||'''',NULL)blocked_data_querysql
FROMgv$locka,gv$lockb,gv$sessiona_s,gv$sessionb_s,dba_objectsobj
WHEREa.id1=b.id1
ANDa.id2=b.id2
ANDa.block>0--阻塞了其他人
ANDb.request>0--AND((a.INST_ID=b.INST_IDANDa.SID<>b.SID)OR(a.INST_ID<>b.INST_ID))
ANDa.sid=a_s.sid
ANDa.inst_id=a_s.inst_id
ANDb.sid=b_s.sid
ANDb.inst_id=b_s.inst_id
ANDb_s.row_wait_obj#=obj.object_id(+)
ORDERBYa.inst_id,a.sid;

原文地址:https://www.jb51.cc/oracle/210609.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐