cursor: pin S => cursor: pin S wait on X => library cache: mutex X 的优化过程

os: centos 7.4
db: oracle 11.2.0.4

版本

# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
# 
# su - oracle
Last login: Tue Jan 21 03:40:05 CST 2020 on pts/0
$ sqlplus / as sysdba;

SQL*Plus: Release 11.2.0.4.0 Production on Mon Feb 3 10:29:09 2020

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> set lines 300;
SQL> set pages 300;
SQL> 
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE	11.2.0.4.0	Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> 

准备基础表、数据


$ sqlplus scott2/oracle

SQL*Plus: Release 11.2.0.4.0 Production on Tue Mar 3 02:05:48 2020

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> 
SQL> set lines 300;
set pages 300;

SQL> create table tmp_t0 (
  c0 integer not null,
  c1 varchar2(100) not null,
  c2 varchar2(2000) 
);

SQL> alter table TMP_T0 add constraint pk_tmp_t0 primary key (C0);

SQL> insert into tmp_t0
select level as id,
       level||'_'||level as name,
       level||'_'||level||'_'||level as memo
  from dual
  connect by level <=1000000
  ;

SQL> commit;
 

准备压测脚本

# su - oracle
$ vi select.sh

#!/bin/bash
for((i=1;i<=100;i++));
do
(
sqlplus -S /nolog <

cursor: pin S

开始执行并发脚本

$ ./select.sh

SQL> select s."EVENT#",
       s."EVENT",
       count(1)
from v$session s
where 1=1
and s."USERNAME"='SCOTT2'
group by s."EVENT#",
         s."EVENT"
;

    EVENT# EVENT							      COUNT(1)
---------- ---------------------------------------------------------------- ----------
       354 SQL*Net message from client						     6
       281 cursor: pin S							   100
       350 SQL*Net message to client						     1


优化 cursor: pin S

$ vi select_1.sh

#!/bin/bash
for((i=1;i<=100;i++));
do
(
sqlplus -S /nolog <

开始压测

$ chmod 755 ./select_1.sh
$ ./select_1.sh

SQL> select s."EVENT#",
       s."EVENT",
       count(1)
from v$session s
where 1=1
and s."USERNAME"='SCOTT2'
group by s."EVENT#",
         s."EVENT"
;

    EVENT# EVENT							      COUNT(1)
---------- ---------------------------------------------------------------- ----------
       289 library cache: mutex X						     3
      1021 kksfbc child completion						    11
       354 SQL*Net message from client						     6
       282 cursor: pin S wait on X						    83
       350 SQL*Net message to client						     1
       288 library cache load lock						     1
       287 library cache lock							     2

7 rows selected.

出现了其它的等待事件

SQL> select s."EVENT#",
       s."EVENT",
       s.sql_id,
       sa."SQL_TEXT"
from v$session s
     left outer join v$sqlarea sa
                  on s.sql_id = sa.sql_id
where 1=1
and s."USERNAME"='SCOTT2'
;

    EVENT# EVENT							    SQL_ID                                    SQL_TEXT
---------- ---------------------------------------------------------------- -------------------------------------------------------------------------------------

       282 cursor: pin S wait on X					    6a4x85vsp51k6  select/*+ 182941*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    0ut10d7fu26wx  select/*+ 182945*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    82mmhxj4nygxn  select/*+ 182940*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
      1021 kksfbc child completion					    38ac1y5k200ba  select/*+ 182939*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    38ac1y5k200ba  select/*+ 182939*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    331tu1famzw32  select/*+ 182944*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    331tu1famzw32  select/*+ 182944*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       287 library cache lock						    0ut10d7fu26wx  select/*+ 182945*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1
       282 cursor: pin S wait on X					    02c2vx389dyc2  select/*+ 182953*/ c1	     from tmp_t0 t0    where 1=1      and t0.c0=:1

107 rows selected.

进一步优化 cursor: pin S wait on X

cursor: pin S wait on X 是硬解析过多,进一步优化下

$ vi select_2.sh

#!/bin/bash
for((i=1;i<=100;i++));
do
(
sqlplus -S /nolog <

开始压测

$ chmod 755 ./select_2.sh
$ ./select_2.sh

SQL> select s."EVENT#",
       s."EVENT",
       count(1)
from v$session s
where 1=1
and s."USERNAME"='SCOTT2'
group by s."EVENT#",
         s."EVENT"
;

    EVENT# EVENT							      COUNT(1)
---------- ---------------------------------------------------------------- ----------
       289 library cache: mutex X						    93
       354 SQL*Net message from client						     6
       279 cursor: mutex S							     3
       281 cursor: pin S							     4
       350 SQL*Net message to client						     1

又出现事件 library cache: mutex X

SQL> select s."EVENT#",
       s."EVENT",
       s.sql_id,
       sa."SQL_TEXT"
from v$session s
     left outer join v$sqlarea sa
                  on s.sql_id = sa.sql_id
where 1=1
and s."USERNAME"='SCOTT2'
;

继续优化 library cache: mutex X

Library cache: mutex等待事件产生常见原因:

1 os资源不足(cpu、内存)
2 sga设置不合理,shared_pool不足,或动态调整导致hard parse
3 hot object contention
4 hard parse
5 sql high version count 由于子游标太多,扫描时会形成锁
6 library cache object失效导致重编译
7 bug


参考:

你可能感兴趣的:(#,oracle,advanced,knowledge,cursor,pin,S,pin,S,wait,on,X,library,cache,mutex,X)