Oracleでレコードがロックされている場合、どのレコードがロックされているかを知ることができますか?


10

レコードがロックされている場合、どのレコードがロックされているかを知ることができますか?

レコードのROWIDまたはその他の情報を取得するにはどうすればよいですか?


このSQLでいくつかの情報を得ることができます

SELECT c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
   FROM v$locked_object a, dba_objects b, v$session c    
WHERE a.object_id = b.object_id    
    AND a.SESSION_ID = c.sid(+) 

関数を使用してROWIDを取得する方法をWebで見つけました DBMS_ROWID.ROWID_CREATE()

しかし、それは機能していないようです。


2
トランザクションによって保持されているロックではなく、一部のプロセスが待機しているロックのみを表示できます。
a_horse_with_no_name 2013年

@a_horse_with_no_name-v $ lockは、トランザクションが保持しているロックを示します
Chris Saxon

@ChrisSaxon:その通りです。どのがロックされているのかはわかりませんが、もっとはっきりしているはずです。
a_horse_with_no_name 2013年

Oracle(他のデータベースとは異なり)には、ロックの共有構造がありません。これにより、データベースはスケーラブルになりますが、一方で、すべてのロックを確認することはできません。ロックはデータベースブロックに直接保存されます。誰かがブロックされた瞬間に、「ホルダー・ウェイター」という構造が作成されます。次に、このペアがに表示されV$LOCKます。
ibre5041

回答:


13

セッションによってロックされているすべての行を実際にリストすることはできません。ただし、セッションが別のセッションによってブロックされると、どのセッション/行がそれをブロックしているかを確認できます。

Oracleは、個々の行ロックのリストを維持しません。むしろ、ロックは行自体の中に直接登録されます-それは追加の列と考えてください。

V$LOCKビューを介してオブジェクトのロックを取得したセッションを見つけることができますが、これは行レベルではなく、一般情報のみをリストします。

このビューでは、セッションが別のセッションによってブロックされているかどうかも確認できます。その場合、セッションが別のセッションによってブロックされていると、行情報が情報に表示されV$SESSIONます。

ROWIDを取得できます。2つのセッションを持つ例を作成してみましょう:

SESSION1> create table test as select * from all_objects;

Table created

SESSION1> select rowid from test where object_name = 'TEST' for update;

ROWID
------------------
AAMnFEAAaAAALTDAAz

/* setting identifiers to help with identifying this session later */
SESSION2> exec dbms_application_info.set_client_info('012345');

PL/SQL procedure successfully completed

SESSION2> select 1 from test where object_name = 'TEST' for update;
/*  this will block */

セッション2はセッション1で待機しています。ブロッキング行を検出するには、次のようにします。

SESSION1> SELECT o.object_name,
       2         dbms_rowid.ROWID_CREATE (1,
       3                                  s.ROW_WAIT_OBJ#,
       4                                  s.ROW_WAIT_FILE#,
       5                                  s.ROW_WAIT_BLOCK#,
       6                                  s.ROW_WAIT_ROW#) rid
       7     FROM dba_objects o, v$session s
       8    WHERE o.object_id = s.row_wait_obj#
       9      AND s.client_info = '012345';

OBJECT_NAME     RID
--------------- ------------------
TEST            AAMnFEAAaAAALTDAAz

参考資料Tom Kyteによるプロセスの説明


3

次のクエリを実行すると、Oracleデータベースのすべてのテーブルロックを検索できます。

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a ,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.