1.ロックの基本情報取得
SQL> SELECT * FROM V$LOCK WHERE TYPE IN ('TX','TM');
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ----- ---- --------- ------- ------ ------- ----- -----
0840E798 0840E868 13 TX 196609 115 6 0 9 0
0332772C 03327740 13 TM 3378 0 3 0 9 0
列名 データ型 格納されているデータの内容
KADDR RAW(4) ロックアドレス
SID NUMBER ロックを保持しているセッションID
TYPE VARCHAR2(2) 要求しているロックタイプ。
TM: DMLエンキュー(TMが表ロック)
TX: トランザクションエンキュー (TXが行ロック)
LMODE NUMBER 保持するロックモード。現在かけられているロックを示す
0:なし
1:NULL NULL
2:SS 行共有
3:SX 行排他
4:S 共有
5:SSX 共有/行排他
6:X 排他
REQUEST NUMBER 要求するロックモード。要求されているロックを示す
0:なし
1:NULL NULL
2:SS 行共有
3:SX 行排他
4:S 共有
5:SSX 共有/行排他
6:X 排他
CTIME NUMBER 現行のモードが付与されてから経過した時間
BLOCK=1が「待たせている原因のロック」
2.ロックをかけているユーザ&program
SELECT
SADDR
, SID
, SERIAL#
, USERNAME
, PROGRAM
FROM V$SESSION
WHERE SID = ANY(SELECT SID FROM V$LOCK WHERE TYPE IN ('TX','TM'));
3.ロックをかけているSQL文
SELECT
A.SQL_TEXT
, A.ADDRESS
FROM V$SQLAREA A
, V$SESSION B
WHERE A.ADDRESS = B.SQL_ADDRESS
AND B.SID = ANY(SELECT SID FROM V$LOCK WHERE TYPE IN ('TX','TM'));
4.ロックをしている、されているオブジェクト
データを更新すると必ず、TYPE=TM(DMLエンキュー)とTYPE=TX(トランザクショ
ンエンキュー)が対で取得される。TMが表ロックに対応し、TXが行ロックに対応
すると思っていいだろう。TYPE=TMのときID1はオブジェクトIDを示すので
DBA_OBJECTSからオブジェクト名が取得できる。
DBA_OBJECTSからオブジェクト名を取得
SQL>SELECT OBJECT_ID,OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_ID=3378;
OBJECT_ID OBJECT_NAME
--------- ------------
3378 A
set lines 1000
col username for a10
col program for a15
col sql_text for a8
col object_name for a20
col status for a8
col sid for 99999
col server for a7
col lmode for 999
col SERIAL# for 9999999
col block for 9999
col SQL_TEXT for a6
SELECT b.status
, a.sid
, b.serial#
, b.server
, a.type
, b.username
, b.program
, substr(c.sql_text, 1, 6) as SQL_TEXT
, d.object_name
, a.id1
, a.lmode
, a.request
, a.ctime
, a.block
FROM V$LOCK a
, ( SELECT
SADDR
, SID
, SERIAL#
, USERNAME
, PROGRAM
, SQL_ADDRESS
, STATUS
, SERVER
FROM V$SESSION
WHERE SID = ANY(SELECT SID FROM V$LOCK WHERE TYPE IN ('TX','TM'))
) b
, v$sqlarea c
, dba_objects d
WHERE TYPE IN ('TX','TM')
AND a.sid = b.sid
AND a.id1 = d.object_id(+)
AND b.sql_address = c.address(+)
ORDER BY a.sid