首页 » ORACLE 9i-23c » bind variable在11g 中出现Cursor: mutex S

bind variable在11g 中出现Cursor: mutex S

今天看到一个案例,从10G升级到11GR2后cpu负载迅速上升,很快达到100%,通过OWI显示出现大量“Cursor: mutex S”事件,mutex S是发生在cursor cache上的序列化mutex,它的发生一般出现在两个或以上session尝试parse(hard/soft)相同的sql命令(相同sql_id),可以确认存在大量的解析,后来很快从v$sql发现了一个sql_id包含1000以上的child cursor(也可以通过v$sqlarea),并县随着时间的流逝,child cursor还在不停的增加,因此sql查询正确的cursor version时间也就越来越长,导致latch contention 对于library cache latches

有一种临时解决方法
DECLARE
SQ_ADD VARCHAR2(100) := ”;
BEGIN
execute immediate ‘select address from v$sqlarea where sql_id = ”someSQLIDfoo”’ into SQ_ADD;
dbms_shared_pool.purge (SQ_ADD||’,123454321′,’C’);
END;

用dbms_shared_pool.purge每1分钟flush out from libary cache一次,建立了一个job,sql的address因为一些原因有可能改变(db重启,手动flush等等),但是sql_id 是根据sql text的hash value 另一种表现形式,在一个数据库通常不会改变,但是DB版本升级会带来sql_id的变化如10G升级11G,正像这个案例一样。
sql_id 转换hash_value Tanel Poder’s note

select
    trunc(mod(sum((
        instr('0123456789abcdfghjkmnpqrstuvwxyz',substr(lower(trim('&1')),level,1))-1)*power(32,length(trim('&1'))-level)),power(2,32))) hash_value
    , lower(trim('&1')) sql_id
from
    dual
connect by
    level <= length(trim('&1'))
/

但是谁都不想在数据库中跑一个每分钟执行一次的job解决这样的问题,从那个version count很高的sql 看出是一个包含47个绑定变量的update,child cursor不能重用的原因也是bind mismatch,随后做了10046 ,从trace 文件 中发现了有相同的字段不同数据类型变量加上不同字段组合的原因。之前关于version count我记也记录过http://www.anbob.com/?p=1669

这次记录分析10046 trace的方法。主要是根据oacdty

SQL> var a varchar2(25);
SQL> var b number;

SQL> exec :a:='TABLE';
SQL> exec :b:=10;

SQL> alter session set events '10046 trace name context forever,level 12';
SQL> select * from anbob.obj where object_id<:b and object_type=:a;
SQL> alter session set events '10046 trace name context off';


PARSING IN CURSOR #1 len=61 dep=0 uid=0 oct=3 lid=0 tim=1321000186605824 hv=3134025673 ad='dfa229e8'
select * from anbob.obj where object_id<:b and object_type=:a
END OF STMT
PARSE #1:c=0,e=52,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1321000186605821
BINDS #1:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=00 csi=00 siz=152 off=0
  kxsbbbfp=7f334cd78590  bln=22  avl=02  flg=05
  value=10
 Bind#1
  oacdty=01 mxl=128(50) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=01 csi=852 siz=0 off=24
  kxsbbbfp=7f334cd785a8  bln=128  avl=05  flg=01
  value="TABLE"


oacdty  - Datatype code
mxl     - Maximum length of the bind variable value (private maximum length in parentheses)
mxlc    - appears to be the maximum number of characters for the bind variable, but only if the variable uses character length semantics.
mal     - array length
scl     - Scale
pre     - Precision
oacflg  - Special flag indicating bind options
fl2     - second part of oacflg
frm     - Unknown        :(
csi     - Unknown        :(
siz     - Amount of memory to be allocated for this chunk
off     - Offset into this chunk for this bind buffer
kxsbbbfp- Bind address
bln     - Bind buffer length
avl     - actual value length
flg     - bind status flag
value   - Value of the bind variable


SQL> var var1 varchar2(50 char);
SQL> exec :var1 :='TABLE';  
SQL> select * from anbob.obj where object_type=:var1;  

BINDS #1:
kkscoacd
 Bind#0
  oacdty=01 mxl=128(100) mxlc=50 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000010 frm=01 csi=852 siz=128 off=0
  kxsbbbfp=7fdb6c3a88c8  bln=128  avl=05  flg=05
  value="TABLE"

oacdty=
1 VARCHAR2/NVARCHAR2
2 NUMBER(p,s)
8 LONG
12 DATE
etc..

Datatype code read reference ORACLE doc
http://docs.oracle.com/cd/B12037_01/server.101/b10758/sqlqr06.htm

对于为什么10G下运行正常11G出问题,作者提交SR后得到回复

the MOS “Manager Performance Team Americas” stated in the SR:

Its important to note that cursor obsoletion code was removed in version 11. That means we no longer obsolete a parent cursor when it reaches 1024 child cursors.

给我们的启示是做版本升级前,一定要经过测试。

打赏

对不起,这篇文章暂时关闭评论。