2016-12-09 5 views
4

生産時に非常に奇妙なロックが発生しています。 5秒以上ロックされたオブジェクトを検出し、アラート電子メールを送信するPL/SQLスクリプトをセットアップしました。Oracle SQL - SELECTクエリでインデックスがロックされ、DMLセッションがブロックされる

以下

は、そのスクリプトのカーソルです:

select l.sid, trunc(l.id1/power(2, 16)) rbs, 
    bitand(l.id1, to_number('ffff', 'xxxx')) + 0 slot, 
    l.id2, l.lmode, l.request, l.ctime, l.block, 
    substr(v.osuser, 1, 12) osuser, 
    substr(v.machine, 1, 15) machine, 
    substr(v.module, 1, 12) module, 
    decode(v.blocking_session_status||l.block, 'VALID0', 
      dbms_rowid.rowid_create(1, v.row_wait_obj#, v.row_wait_file#, 
         v.row_wait_block#, v.row_wait_row#), '.') lrow, 
    o.object_name, 
    decode(v.sql_id, null, v.prev_sql_id, v.sql_id) sql_id, 
    o.owner 
from v$lock l, v$session v, all_objects o 
where l.sid = v.sid 
    and v.row_wait_obj# = o.object_id(+) 
    and l.ctime > 5 and l.type = 'TX' and (l.request = 6 or l.block = 1) 
order by 2, 3, 4, 8 desc, 7 desc; 

そして、我々はロックのために今日の警告を得た:

SID TRANS-ID  L-TYPE CTIME BLOCK OSUSER  MACHINE   MODULE  SQLID   ROWID   OBJECT 
---- --------------- ------- ------ ----- ---------- --------------- ------------ ------------- ------------------ -------------------- 
669 132,11,40475 6/0  70  1  userpr1  serv1023  userpr1-00002 fbnhs4gd9a7yn .     IDX_005 
1133 132,11,40475 0/6  62  0  userpr1  serv1023  userpr1-00000 f0gm2rx85qjja AAAgOuAAFAAD04TAAW ITEMST 
924 132,11,40475 0/6  53  0  userpr1  serv1023  userpr1-00002 f0gm2rx85qjja AAAgOuAAFAAD04TAAW ITEMST 
927 132,11,40475 0/6  27  0  userpr1  serv1023  userpr1-00001 f0gm2rx85qjja AAAgOuAAFAAD04TAAW ITEMST 

をだから、上から、私たちはセッション669のSQLID fbnhs4gd9a7ynを観察することができますインデックスIDX_005をロックし、残りのセッションの残りをブロックしています。最も奇妙な部分は今

  1. SQLID fbnhs4gd9a7ynは、インデックスIDX_005がテーブルITEMSTに接続されていない
  2. ( UPDATE FORさえSELECTない)だけでSELECTクエリですが、それのブロックが残っています 方法[1]起こったと、なぜそれをuをブロックしない:だから、私の質問はとにかく

ITEMSTを更新3つのセッションテーブルITEMSTにpdateしますか?

これはOracleのバグですか? Oracle 11.2.0.4 Enterprise Edition、btwを使用しています。

答えて

4

クエリが返すのは、実際にロックを取得したクエリに関連する場合とない場合があります。私はITEMSTを更新し、クエリを実行しますが、私は私のupdateを犯していない場合は、SID 669で

は、たとえば、あなたは669がSELECT文を実行し、それがロックを保持していることをされていることを参照してくださいね。セッションが実際にロックを取得したのは、先にUPDATE(またはINSERTなど)でした。他のセッションが現在待機しているロックを取得したセッションが以前クエリしたものを確認する簡単な方法はありません。

+0

Justin、ありがとう。実際には、ロックがサンプリングされる前にITEMSTを含むSQLのセッション669をASHでチェックしましたが、何も見つかりませんでした。 Oracleが実際にロックを取得したSQLに関連するセッションをサンプリングしていない可能性はありますか? – toddlermenot

+1

@toddlermenot - それは完全に可能です、確かに。 ASHはちょうど各秒の上にアクティブだったセッションを照会することから始まります。見た目を取ったクエリが1秒未満で実行されたと仮定すると、最初のサンプルでは検出されなかった可能性があります。これがどれほど古いかによって、ASHがデータをダウンサンプリングしたときに失われている可能性もあります。 –

関連する問題