sql version count引發cursor:pin s wait x及library cache latch library cache lock

531968912發表於2015-12-16

背景

   某Q友在其生產系統AWR發現library cache latch及library cache lock及cursor:pin s wait x等待事件非常嚴重,經排查發生某些底層SQL的多版本現象非常嚴重,最高達到4000多左右
結論
   1,oracle為了控制某個SQL的子游標個數不止過高過多,採用繫結變數分級機制,即繫結變數的長度(位元組)在一個範圍內,就隸屬一個子遊標,否則就會新建立一個子遊標
   2,可以透過v$sql_bind_metadata獲取上述繫結變數分量的具體分界點
   3,v$sql_shared_cursor可以分析某SQL產生多個子遊標的原因,然後進行不同的原因進行分析
   4,進一步基於第3步分析(這裡子游標不能共享的原因是bind_mismatch),在MOS查詢相關文件 ,發現
      High Version Count Due To BIND_MISMATCH [ID 336268.1]
   5,基於第4步,我們已經知道多版本的產生原因,現在要解決這個問題,因為是生產系統, 可以採用10503事件進行暫時控制
      但不能成功


   6,基於第5步,就要分析為何事件配置不成功,繼續檢視MOS,以關鍵字進行查詢,event 10503
      發現文章:
         Bug 10274265 - Event 10503 does not work at session level [ID 10274265.8]


    7,基於第6步,要思考下,即便配置10503事件成功了,畢竟是生產系統,會不會引發其它的一些問題或BUG呢,還是老辦法,檢視MOS
         
event可能導致ORA-600: [kxspoac : EXL 1]錯誤


ORA-600: [kxspoac : EXL 1] Occuring During Query If Event 10503 Is Set [ID 810194.1]






    8,由上述引發一些思考:






--由此可見ORACLE知識聯絡是非常複雜的,要調整一個引數,必須要從全方位考慮與分析


1,配置引數的命令是什麼
2,如果配置引數不成功,它為何不成功,可能也有相關的MOS文章進行介紹
3,如果配置引數成功,會引發什麼其它的問題,也要進行全面考慮,否則解決舊問題,引發新問題


引申一下,可見應用人員設計表以及開發人員,在編寫程式碼時,也要考慮到這點,比如:不要在宣告變數長度時
過分宣告,比如本來20位元組就夠了,你宣告瞭1000個位元組,而且每個開發人員宣告長度不同
,這樣就會引發本文的子游標不能共共享的問題




4,基於關鎮字檢視是否是相關的BUG


5,進一步引證了TOP 5等待事件有時未必是因,很可能它只是一個果,而且它的原因不在本時間點取樣的AWR(或者說不能很明白得看出來)
   也就是說需要你檢視此時間點之前的AWR進行分析




分析


SQL> select sql_id,sql_text from v$sql where lower(sql_text) like '%select pos#,intcol#%';


SQL_ID        SQL_TEXT
------------- ----------------------------------------------------------------------------------------------------
1qb4fr2qc8jsu select sql_id,sql_text from v$sql where lower(sql_text) like '%select pos#,intcol#%'
6769wyy3yf66f select pos#,intcol#,col#,spare1,bo#,spare2 from icol$ where obj#=:1


SQL> select sql_id,count(*) from v$sql where sql_id='6769wyy3yf66f' group by sql_id;


SQL_ID          COUNT(*)
------------- ----------
6769wyy3yf66f          1


SQL> select sid,event,prev_sql_id,sql_id from v$session where nvl(prev_sql_id,sql_id)='6769wyy3yf66f';


no rows selected


SQL> select count(*) from v$session where nvl(prev_sql_id,sql_id)='6769wyy3yf66f';


  COUNT(*)
----------
         0


SQL> desc icol$;
 Name              Null?    Type
 ----------------- -------- ------------
 OBJ#              NOT NULL NUMBER
 BO#               NOT NULL NUMBER
 COL#              NOT NULL NUMBER
 POS#              NOT NULL NUMBER
 SEGCOL#           NOT NULL NUMBER
 SEGCOLLENGTH      NOT NULL NUMBER
 OFFSET            NOT NULL NUMBER
 INTCOL#           NOT NULL NUMBER
 SPARE1                     NUMBER
 SPARE2                     NUMBER
 SPARE3                     NUMBER
 SPARE4                     VARCHAR2(100
                            0)
 SPARE5                     VARCHAR2(100
                            0)
 SPARE6                     DATE


SQL> select count(*) from icol$;


  COUNT(*)
----------
      2416




SQL> select obj#,bo#,col#,pos#,segcol#,offset,spare1,spare2 from icol$ where rownum<=10 order by 1;


      OBJ#        BO#       COL#       POS#    SEGCOL#     OFFSET     SPARE1     SPARE2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
         3          2          1          1          0          0          0          0
         7          6          1          1          0          0          0          0
         9          8          1          1          0          0          0          0
         9          8          2          2          0          0          0          0
         9          8          3          3          0          0          0          0
        11         10          1          1          0          0          0          0
        24         23          1          1          0          0          0          0
        24         23          2          2          0          0          0          0
        26         25          1          1          0          0          0          0
        26         25          2          2          0          0          0          0


10 rows selected.


create table icol$                                     /* index column table */
( obj#          number not null,                      /* index object number */
  bo#           number not null,                       /* base object number */
  col#          number not null,                            /* column number */
  pos#          number not null,        /* column position number as created */
  segcol#       number not null,                 /* column number in segment */
  segcollength  number not null,             /* length of the segment column */
  offset        number not null,                         /* offset of column */
  intcol#       number not null,                   /* internal column number */
  spare1        number,                                              /* flag */
                                              /* 0x01: this is an expression */
                                                  /* 0x02: desc index column */
                                          /* 0x04: filter by col for dom idx */
                                           /* 0x08: order by col for dom idx */
  spare2        number,            /* dimension table internal column number */
  spare3        number,           /* pos# of col in order by list of dom idx */
  spare4        varchar2(1000),
  spare5        varchar2(1000),
  spare6        date
)
cluster c_obj#(bo#)




SQL> create table t_bind(a varchar2(100));


Table created.


SQL> insert into t_bind values(1);


1 row created.


SQL> commit;


Commit complete.


SQL> var x varchar2(10);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> var x varchar2(100);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,sql_text from v$sql where sql_text like '%select a from t_bind where a=%';


SQL_ID        SQL_TEXT
------------- ----------------------------------------------------------------------------------------------------
3swjj5kc9kfkp select a from t_bind where a=:x
3swjj5kc9kfkp select a from t_bind where a=:x


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(38);
SQL> select a from t_bind where a=:x;


no rows selected


---發現子游標沒有繼續增加
SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y    




SQL> var x varchar2(50);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


---會不會變數長度,也有個分級,不同分級的長度,會產生新的子游標呢
SQL> alter table t_bind modify a varchar2(1000);


Table altered.


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


no rows selected


SQL> var x varchar2(10);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N


SQL> var x varchar2(100);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(200);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 N




SQL> var x varchar2(500);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 N


SQL> var x varchar2(1000);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 N


---可見重新整理共享池只會儲存
SQL> alter system flush shared_pool;


System altered.


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 N






---繼續分析下到底繫結變數分級,到度在哪些值範圍內,隸屬一個子遊標,否則會新生一個子遊標


經查MOS,發現文章:High Version Count Due To BIND_MISMATCH [ID 336268.1]
對於繫結變數,ORACLE根據變數長度進行了分級,對於VARCHAR2型別共有如下4級:


第一級:1-32
第二級:33-128
第三級:129-2000
第四級:2000+


SQL> alter table t_bind modify a varchar2(300);


Table altered.




SQL> var x varchar2(50);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N


SQL> var x varchar2(129);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y




SQL> var x varchar2(2001);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y
3swjj5kc9kfkp 0000000064964090 0000000066EA5F40            2 Y




SQL> var x varchar2(15);
SQL> select a from t_bind where a=:x;


no rows selected




---mos說,可以用10503事件暫時解決上述版本過高問題,好像10503事件沒起作用
SQL> alter session set events '10503  trace name context forever ,level 4096';


Session altered.


SQL> alter table t_bind modify a varchar2(300);


Table altered.


SQL> var x varchar2(15);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N




SQL> var x varchar2(120);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(600);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(2600);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y
3swjj5kc9kfkp 0000000064964090 0000000066EA5F40            2 Y




----繼續分析10503事件為何不生效,看來不是105032命令的次序問題


SQL> alter session set events '10503  trace name context level 4096,forever';


Session altered.


SQL> alter table t_bind modify a varchar2(300);


Table altered.




SQL> var x varchar2(12);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N




SQL> var x varchar2(100);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(250);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y


SQL> var x varchar2(2500);
SQL> select a from t_bind where a=:x;


no rows selected


SQL> select sql_id,address,child_address,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='3swjj5kc9kfkp';


SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER B
------------- ---------------- ---------------- ------------ -
3swjj5kc9kfkp 0000000064964090 0000000064961FC0            0 N
3swjj5kc9kfkp 0000000064964090 00000000649A1FA8            1 Y
3swjj5kc9kfkp 0000000064964090 0000000066EA5F40            2 Y


---繼續經查MOS,發現文章
Bug 10274265 - Event 10503 does not work at session level [ID 10274265.8]


可見即使在會話層面配置了10503事件,仍然不會生效


---而且即使設定10503事件成功,可能會引發ORA-600報錯
event可能導致ORA-600: [kxspoac : EXL 1]錯誤


ORA-600: [kxspoac : EXL 1] Occuring During Query If Event 10503 Is Set [ID 810194.1]




--由此可見ORACLE知識聯絡是非常複雜的,要調整一個引數,必須要從全方位考慮與分析


1,配置引數的命令是什麼
2,如果配置引數不成功,它為何不成功,可能也有相關的MOS文章進行介紹
3,如果配置引數成功,會引發什麼其它的問題,也要進行全面考慮,否則解決舊問題,引發新問題


引申一下,可見應用人員設計表以及開發人員,在編寫程式碼時,也要考慮到這點,比如:不要在宣告變數長度時
過分宣告,比如本來20位元組就夠了,你宣告瞭1000個位元組,而且每個開發人員宣告長度不同
,這樣就會引發本文的子游標不能共共享的問題




基於關鎮字檢視是否是相關的BUG










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

相關文章