[20160811]dbms_shared_pool清除子光标.txt

[20160811]dbms_shared_pool清除子光标.txt

--工作需要,看了一下使用dbms_shared_pool包的purge清除子光标.顺便做一些细节测试看看:

1.环境与说明:
SCOTT@test01p> @ ver1
PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.1.0.1.0     Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

--我一般使用的脚本如下,原始的链接找不到了
$ cat flush_sql.sql

DECLARE
name varchar2(100);
version varchar2(3);
BEGIN
select regexp_replace(version,'\..*') into version from v$instance;

if version = '10' then
execute immediate
q'[alter session set events '5614566 trace name context forever']'; -- bug fix for 10.2.0.4 backport
end if;

select address||','||hash_value into name from v$sqlarea where sql_id like '&1';
dbms_shared_pool.purge(name,'C',&2);
END;
/

SYS@test> @ desc_proc sys dbms_shared_pool purge
INPUT OWNER PACKAGE_NAME OBJECT_NAME
sample : @desc_proc sys dbms_stats gather_%_stats


OWNER      PACKAGE_NAME         OBJECT_NAME   SEQUENCE ARGUMENT_NAME        DATA_TYPE            IN_OUT    DATA_TYPE            DEFAULTED
---------- -------------------- ----------- ---------- -------------------- -------------------- --------- -------------------- ----------
SYS        DBMS_SHARED_POOL     PURGE                1 NAME                 VARCHAR2             IN        VARCHAR2             N
                                                     2 FLAG                 CHAR                 IN        CHAR                 Y
                                                     3 HEAPS                NUMBER               IN        NUMBER               Y
                                                     1 SCHEMA               VARCHAR2             IN        VARCHAR2             N
                                                     2 OBJNAME              VARCHAR2             IN        VARCHAR2             N
                                                     3 NAMESPACE            NUMBER               IN        NUMBER               N
                                                     4 HEAPS                NUMBER               IN        NUMBER               N
                                                     1 HASH                 VARCHAR2             IN        VARCHAR2             N
                                                     2 NAMESPACE            NUMBER               IN        NUMBER               N
                                                     3 HEAPS                NUMBER               IN        NUMBER               N
10 rows selected.

http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_shared_pool.htm#sthref7227

--我感兴趣的是heaps参数:
heaps
   
Heaps to be purged. For example, if heap 0 and heap 6 are to be purged:

1<<0 | 1<<6 => hex 0x41 => decimal 65, so specify heaps =>65.Default is 1, that is, heap 0 which means the whole object
would be purged

--按照介绍: heap 0 = 1,heap6=2^6=64,如果heap 0清除了,整个对象也清除了.因为heap6是下面一个子堆.

2.测试:
SCOTT@test01p> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--sql_id=4xamnunv51w9j,过程略.保险起见,执行多次以上语句.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       000007FF2894D4B0 000007FF28936528       4032      12144       3115     19291      19291  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--为了避免以上语句光标锁定,退出看看是否可以清除.

3.使用包dbms_shared_pool.purge:

SYS@test> @ flush_sql 4xamnunv51w9j 64
PL/SQL procedure successfully completed.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       000007FF2894D4B0 00                     4072          0       3115      7187       7187  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--确实子游标句柄地址的KGLOBHD6=00.

SYS@test> @ flush_sql 4xamnunv51w9j 1
PL/SQL procedure successfully completed.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       00               00                        0          0       3115      3115       3115  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--确实子游标句柄地址的KGLOBHD0=00.

SYS@test> @ flush_sql 4xamnunv51w9j 1
DECLARE
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 12

--也就是这个时候v$sqlarea视图已经无法查询到对应记录.
SYS@test> select * from v$sql where sql_id='4xamnunv51w9j';
no rows selected

--v$sql视图也查询不到.

4.重新执行在测试看看:

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       000007FF57663820 000007FF28936528       4072      12144       3115     19331      19331  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

SYS@test> @ flush_sql 4xamnunv51w9j 1
PL/SQL procedure successfully completed.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       00               00                        0          0       3115      3115       3115  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--可以发现heap0 清除了,heap 6也一起清除.
--另外从以上测试可以发现父游标句柄地址不会清除的.

5.测试打开光标的情况下是否可以清除:
--打开session 1:
SCOTT@test01p> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--不退出,也不执行其他语句,安装vage介绍,这样光标是没有关闭,从11g开始要执行下一条语句才会关闭.

----打开session 2:
SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       000007FF57663820 000007FF28936528       4032      12144       3115     19291      19291  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

SYS@test> @ flush_sql 4xamnunv51w9j 65
PL/SQL procedure successfully completed.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       00               00                        0          0       3115      3115       3115  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--看来我理解错误!!^_^.仅仅清除了子光标.
--再次执行以上语句.
--打开session 1:
SCOTT@test01p> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--打开session 2:
SYS@test> alter system flush shared_pool;
System altered.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游标句柄地址 000007FF2894D568 000007FF57D67660 select * from dept where deptno=10       00               00                        0          0       3115      3115       3115  911274289 4xamnunv51w9j          0
父游标句柄地址 000007FF57D67660 000007FF57D67660 select * from dept where deptno=10       000007FF28C12090 00                     4072          0          0      4072       4072  911274289 4xamnunv51w9j      65535

--//依旧无法清除父游标.也就是正在执行完的语句(还没有其他语句执行),是无法清除父光标的.

--打开session 1,执行其他语句:
SCOTT@test01p> select * from dept where deptno=20;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        20 RESEARCH       DALLAS

--打开session 2:
SYS@test> alter system flush shared_pool;
System altered.

SYS@test> @ sharepool/shp4 4xamnunv51w9j 0
no rows selected

--这样才彻底清除干净.

总结:
1.包dbms_shared_pool.purge仅仅能清除子光标的heap6,heap0,当然清除heap0 ,heap6 也一起清除.
2.如果在会话正在执行该语句的情况下没有其他语句执行的情况下,alter system flush shared_pool;仅仅能清除子光标,必须等下一次
执行别的语句,alter system flush shared_pool;才能彻底清除.

--附上sharepool/shp4.sql脚本:
$ cat sharepool/shp4.sql
column N0_6_16 format 99999999
SELECT DECODE (kglhdadr,
               kglhdpar, '父游标句柄地址',
               '子游标句柄地址')
          text,
       kglhdadr,
       kglhdpar,
       substr(kglnaobj,1,40) c40,
       kglobhd0,
       kglobhd6,
       kglobhs0,kglobhs6,kglobt16,
       kglobhs0+kglobhs6+kglobt16 N0_6_16,
           kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20,
           kglnahsh,
           kglobt03 ,
           kglobt09
  FROM x$kglob
WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1' or KGLNAHSH= &2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值