cursor: pin S wait on X等待事件。

wei-xh發表於2010-12-05
select * from v$version;
BANNER
------------------------------------------------------------------------------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
CORE    11.1.0.7.0      Production
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production


先建立一張測試表。
create table wxh_tbd as select * from dba_objects;

Table created.

create index t1 on wxh_tbd(object_id);

Index created.

同時在session1,和session2執行如下語句,在session3觀察等待事件:
session1語句):
select sid from v$mystat where rownum=1;

       SID
----------
      1058

declare
  s varchar2(100) := 'alter system flush shared_pool';
  sql_text     varchar2(200);
begin
  FOR j IN 1 .. 300 loop
    execute immediate s;
    for i in 1 .. 100 loop
      sql_text := 'select object_id from wxh_tbd where object_id=' || i;
      execute immediate sql_text;
    end loop;
  end loop;
end;
/

session2的語句):
select sid from v$mystat where rownum=1;

       SID
----------
      1248

declare
  s varchar2(100) := 'alter system flush shared_pool';
  sql_text     varchar2(200);
begin
  FOR j IN 1 .. 300 loop
    execute immediate s;
    for i in 1 .. 100 loop
      sql_text := 'select object_id from wxh_tbd where object_id=' || i;
      execute immediate sql_text;
    end loop;
  end loop;
end;
/

session3的語句:
select b.*, sq.sql_text
  from v$session se,
       v$sql sq,
       (select a.*, s.sql_text
          from v$sql s,
               (select sid sid1,
                       event,
                       wait_class,
                       p1,
                       p2raw,
                       to_number(substr(p2raw,1,8),'xxxxxxxx') sid2
                  from v$session_wait
                 where event like 'cursor%') a
         where s.HASH_VALUE = a.p1) b
where se.sid = b.sid1
   and se.sql_hash_value = sq.hash_value;
   
如果不知道這個SQL什麼意思,看看官方文件對p1,p2引數的解釋,你就差不多理解了。就是想找到獲得X鎖的會話執行的SQL,和需要獲得S鎖的會話正在執行的SQL.並且查出他們的SQL文字和等待事件。
cursor: pin S wait on XA session waits for this event when it is requesting a shared mutex pin and another session is holding an exclusive mutex pin on the same cursor object.
Wait Time: Microseconds
ParameterDescription
P1 Hash value of cursor
P2 Mutex value (top 2 bytes contains SID holding mutex in exclusive mode, and bottom two bytes usually hold the value 0)
P3 Mutex where (an internal code locator) OR'd with Mutex Sleeps
session3的輸出如下圖,你每次點選,基本都能出現這個等待事件,而且兩個session的文字是一樣的(圖如果不清晰,直接點選開啟):

cursor: pin S wait on X等待事件。
7e78c1e904cbccd55d09fa4ec4b279b6.jpg


剛做這個實驗的時候,我並沒有透過session3的語句去專一的查cursor: pin S wait on X.而是在pl/sql developer裡快速的點選查詢按鈕,觀察等待事件(比較等級哈):
select * from v$session_wait where wait_class<>'Idle';
基本上等待事件都是cursor: pin S wait on X  和shared pool latch。後者是用來為sql 的執行計劃分配記憶體的。有了這樣的經驗後,才透過session3的語句看cursor: pin S wait on X 等待的session都在幹什麼,拿我這個實驗為例,就是sid為1058的已經獲得了X鎖正在對SQL進行解析,這個時候有另一個session也想要對同一個SQL進行解析,那麼就會產生等待事件cursor: pin S wait on X 。看來cursor: pin S wait on X 等待是由於有N個session 要對同一個sql解析導致的,而ORACLE 只把解析的任務給第一個SESSION,其他session 就等待吧,直到解析完成,他們共享解析成果就行了。




那10G下的實驗又會如何呢?

SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production


實驗步驟我就不寫了,跟上面差不多,session3的語句就不用執行了,因為這個等待時間根本不會出現,你就低階點,在PL/SQL裡狂點查詢的滑鼠吧。
select * from v$session_wait where wait_class<>'Idle';
等待事件除了shared pool latch外,基本都是library cache pin了。

看來就SQL解析層面來說,cursor: pin S wait on X取代了10G之前的library cache pin。



[ 本帖最後由 wei-xh 於 2010-12-5 17:30 編輯 ]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-680938/,如需轉載,請註明出處,否則將追究法律責任。

相關文章