2016-12-09 34 views
4

我們在生產中發生了一些非常奇怪的鎖定。我們已經建立了一個PL/SQL腳本,用於查找被鎖定時間超過5秒的對象並向我們發送警報電子郵件。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只是一個SELECT查詢(甚至不是一個SELECT FOR UPDATE)
  2. 指數IDX_005具有表ITEMST沒有什麼聯繫,但塊中的剩餘3屆哪些更新ITEMST反正

所以我的問題是: 怎麼[1]發生,爲什麼它塊U更新到表ITEMST

這可能是Oracle中的一個錯誤嗎? 我們正在使用Oracle 11.2.0.4企業版,順便說一句。

回答

4

您的查詢返回的sql_id可能會或可能不會與實際獲取該鎖的查詢相關。

在SID 669,例如,如果我更新ITEMST,然後運行一個查詢,但我沒有犯我update,你會看到,669正在運行SELECT聲明,它持有鎖。這是會議早期實際獲得鎖的UPDATE(或INSERT或其他)。只有一種簡單的方法可以查看會話已經完成的早期查詢,獲得了其他會話現在正在等待的鎖定。

+0

謝謝Justin,這很有道理。實際上,在鎖定採樣之前,我針對涉及ITEMST的任何SQL檢查了會話669的ASH,但找不到任何SQL。難道說oracle只是沒有對涉及實際獲得鎖的SQL的會話進行採樣? – toddlermenot

+1

@toddlermenot - 當然,這完全有可能。 ASH只是從查詢每秒頂部活動的會話開始。假設查詢花費了不到一秒鐘的時間,那麼完全有可能它在初始樣本中不會被捕獲。取決於這是多大,ASH下采樣數據時也可能會丟失。 –