1229关于共享池4-SQL内存结构父子游标补充3

[20151229]关于共享池4x-SQL内存结构父子游标 (补充3).txt

-- 前几天的测试,还是有点问题,链接如下:
-- http://blog.itpub.net/267265/viewspace-1942280/
-- 继续做1点补充:

1.环境:
SCOTT@book> @ &r/ver1

PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

--session 1:
SCOTT@book> select * from dept where deptno=10;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--sql_id=4xamnunv51w9j,这个可以查询v$sql获得。

2.测试:
--session 2:
$ cat shp4.sql
SELECT DECODE (kglhdadr,
               kglhdpar, '父游标句柄地址',
               '子游标句柄地址')
          text,
       kglhdadr,
       kglhdpar,
       substr(kglnaobj,1,40) c40,
       kglobhd0,
       kglobhd6,
       kglobhs0,kglobhs6,kglobt16,
       kglobhs0+kglobhs6+kglobt16,
           kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20,
           kglnahsh,
           kglobt03
  FROM x$kglob
WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1';

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
old  16:  WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1'
new  16:  WHERE kglobt03 = '4xamnunv51w9j'  or kglhdpar='4xamnunv51w9j' or kglhdadr='4xamnunv51w9j'

TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000006318D1D0 0000000061B435C0 select * from dept where deptno=10       000000006653F0F8 00000000695D1770       4488      12144       3067    19699      19699  911274289 4xamnunv51w9j
父游标句柄地址 0000000061B435C0 0000000061B435C0 select * from dept where deptno=10       000000007C37E8D0 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

3.前面我的测试提到如果这个时候执行刷新共享池不会导致这条语句从共享池退出。
SYS@test> alter system flush shared_pool;
System altered.

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000006318D1D0 0000000061B435C0 select * from dept where deptno=10       00               00                        0          0       3067     3067       3067  911274289 4xamnunv51w9j
父游标句柄地址 0000000061B435C0 0000000061B435C0 select * from dept where deptno=10       000000007C37E8D0 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

--子游标句柄 的KGLOBHD0 ,KGLOBHD6 不在. 但是父游标句柄与子游标句柄以及父游标堆0不会清除。

--实际上我一直认为如果session 1不退出,这条语句不会从共享池退出,实际上存在一点点小错误。如果回到会话1执行其他语句,在回
--到session 2再刷新共享池,就可以刷新将这条语句清除出去。

--session 1:
SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2015-12-29 09:36:01

SYS@book> alter system flush shared_pool ;
System altered.

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
old  16:  WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1'
new  16:  WHERE kglobt03 = '4xamnunv51w9j'  or kglhdpar='4xamnunv51w9j' or kglhdadr='4xamnunv51w9j'
no rows selected

4.再回到session 1,执行3次。

--session 1:
select * from dept where deptno=10;
select * from dept where deptno=10;
select * from dept where deptno=10;

SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2015-12-29 09:39:04

SCOTT@book> @&r/spid
       SID    SERIAL# SPID       PID  P_SERIAL# C50
---------- ---------- ------ ------- ---------- --------------------------------------------------
        90       5157 13988       32          2 alter system kill session '90,5157' immediate;

--session 2:
SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
SADDR                   SID USER_NAME  ADDRESS          HASH_VALUE SQL_ID        SQL_TEXT                           LAST_SQL_ACTIVE_TIM SQL_EXEC_ID CURSOR_TYPE
---------------- ---------- ---------- ---------------- ---------- ------------- ---------------------------------- ------------------- ----------- --------------------
0000000084EC6260         90 SCOTT      000000006307E710  911274289 4xamnunv51w9j select * from dept where deptno=10                                 DICTIONARY LOOKUP CU
                                                                                                                                                    RSOR CACHED
--CURSOR_TYPE类型变为"DICTIONARY LOOKUP CURSOR CACHED".

--这个时候刷新看看:

SYS@book> alter system flush shared_pool ;
System altered.

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000008505B4D8 000000006307E710 select * from dept where deptno=10       00               00                        0          0       3067     3067       3067  911274289 4xamnunv51w9j
父游标句柄地址 000000006307E710 000000006307E710 select * from dept where deptno=10       000000006193DB68 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

--子游标句柄 的KGLOBHD0 ,KGLOBHD6 不在. 但是父游标句柄与子游标句柄以及父游标堆0不会清除。
--换一句话讲如果执行的sql语句执行3次在一个会话中,CURSOR_TYPE='DICTIONARY LOOKUP CURSOR CACHED'.

--回到session 1,再执行2次:

select * from dept where deptno=10;
select * from dept where deptno=10;

SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2015-12-29 09:46:05

--session 2:
SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
no rows selected

--????没有记录。也就是CURSOR_TYPE="DICTIONARY LOOKUP CURSOR CACHED",刷新共享池会导致该语句不会被会话缓存。

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000008505B4D8 000000006307E710 select * from dept where deptno=10       0000000085053450 000000006114F6F8       4528      12144       3067    19739      19739  911274289 4xamnunv51w9j
父游标句柄地址 000000006307E710 000000006307E710 select * from dept where deptno=10       000000006193DB68 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

--session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2015-12-29 09:48:33

--session 2:
SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
SADDR                   SID USER_NAME  ADDRESS          HASH_VALUE SQL_ID        SQL_TEXT                           LAST_SQL_ACTIVE_TIM SQL_EXEC_ID CURSOR_TYPE
---------------- ---------- ---------- ---------------- ---------- ------------- ---------------------------------- ------------------- ----------- --------------------
0000000084EC6260         90 SCOTT      000000006307E710  911274289 4xamnunv51w9j select * from dept where deptno=10                                 DICTIONARY LOOKUP CU
                                                                                                                                                    RSOR CACHED

--执行3次,CURSOR_TYPE="DICTIONARY LOOKUP CURSOR CACHED"

--session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2015-12-29 09:49:18

--session 2:
SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
SADDR                   SID USER_NAME  ADDRESS          HASH_VALUE SQL_ID        SQL_TEXT                           LAST_SQL_ACTIVE_TIM SQL_EXEC_ID CURSOR_TYPE
---------------- ---------- ---------- ---------------- ---------- ------------- ---------------------------------- ------------------- ----------- ---------------------
0000000084EC6260         90 SCOTT      000000006307E710  911274289 4xamnunv51w9j select * from dept where deptno=10                                 SESSION CURSOR CACHED

--执行4次,CURSOR_TYPE="SESSION CURSOR CACHED".

--这个时候再刷新看看:

SYS@book> alter system flush shared_pool ;
System altered.

SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
SADDR                   SID USER_NAME  ADDRESS          HASH_VALUE SQL_ID        SQL_TEXT                           LAST_SQL_ACTIVE_TIM SQL_EXEC_ID CURSOR_TYPE
---------------- ---------- ---------- ---------------- ---------- ------------- ---------------------------------- ------------------- ----------- ---------------------
0000000084EC6260         90 SCOTT      000000006307E710  911274289 4xamnunv51w9j select * from dept where deptno=10                                 SESSION CURSOR CACHED

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000008505B4D8 000000006307E710 select * from dept where deptno=10       00               00                        0          0       3067     3067       3067  911274289 4xamnunv51w9j
父游标句柄地址 000000006307E710 000000006307E710 select * from dept where deptno=10       000000006193DB68 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

5.退出会话1:

SYS@book> select * from v$open_cursor where sql_id='4xamnunv51w9j';
no rows selected

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000008505B4D8 000000006307E710 select * from dept where deptno=10       00               00                        0          0       3067     3067       3067  911274289 4xamnunv51w9j
父游标句柄地址 000000006307E710 000000006307E710 select * from dept where deptno=10       000000006193DB68 00                     4720          0          0     4720       4720  911274289 4xamnunv51w9j

SYS@book> alter system flush shared_pool ;
System altered.

SYS@book> @ &r/sharepool/shp4 4xamnunv51w9j
no rows selected

--也就是退出会话,在session cache cursor不存在了,再刷新共享池就可以将这条sql语句占用共享池的内存清除干净。

--总结:
1.实际上session 1执行第1次,在session 2 查看v$open_cursor视图,对应会话的CURSOR_TYPE='OPEN'.这个时候刷新共享池还会有部分内容占据共享池。(父子游标以及父游标堆0,父游标堆0的DS描述符).
2.这个时候session 1在执行别的语句,在session 2 查看v$open_cursor视图,对应会话才不存在,刷新共享池可以清除干净。
3.重新再来session 1执行3次后,在session 2 查看v$open_cursor视图,对应会话的CURSOR_TYPE='OPEN'.再执行别的语句,在session 2 查看v$open_cursor视图CURSOR_TYPE='DICTIONARY LOOKUP CURSOR CACHED'。
4.这个时候刷新共享池还会有部分内容占据共享池。查看v$open_cursor视图,对应的sql语句的CURSOR_TYPE='DICTIONARY LOOKUP CURSOR CACHED'。
5.但是这个时候session 1 相同语句,打开光标要重新记数,执行4次以上,CURSOR_TYPE="SESSION CURSOR CACHED".
6.这个时候无论如何刷新共享池还会有部分内容占据共享池,但是这个时候session 1 相同语句,打开光标还要重新记数。

--总之如果语句在执行完成没有其他执行,当前的光标是open状态,这个时候无法完全从共享池清除。
--如果CURSOR_TYPE='DICTIONARY LOOKUP CURSOR CACHED'(执行3次) 或者CURSOR_TYPE='SESSION CURSOR CACHED'(执行4次),这个时候无法完全从共享池清除。但是重新打开的光标要重新记数。
--在v$open_cusor无法查询到,才能彻底的清除干净。所以按照vage的介绍,如果出现ora-4031,临时解决要清除kill一组相似的应用,才能临时解决这个问题。

--这个是我的测试结果,环境11.2.0.4,其他版本我不确定是这种情况。

时间: 2024-09-15 18:42:24

1229关于共享池4-SQL内存结构父子游标补充3的相关文章

1224关于共享池4SQL内存结构父子游标补充

[20151224]关于共享池4x-SQL内存结构父子游标 (补充).txt --昨天的测试存在一点小问题,补充说明一下: 1.环境: SYS@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------------------------------------------------------

20150213关于共享池4-SQL内存结构父子游标

[20150213]关于共享池4x-SQL内存结构父子游标.txt --这个主要和recr和freeabl类似. --1.节约内存 --2.减少检索链表的时间. --3.oracle的算法规定,sql语句必须至少是一父一子的情况.很多情况下都是一父多子.也就是说,每个游标,oracle都会为它设置个父游标 --  如果有sql文本相同,但无法共享执行计划的情况出现,那就会出现一父多子的情况. --注意除了sql对象,共享池中其它类型的对象都没有父子游标的概念. --自己按照的介绍,重复测试一遍,

20151223关于共享池4x-SQL内存结构父子游标

[20151223]关于共享池4x-SQL内存结构父子游标.txt --重复测试:http://blog.itpub.net/267265/viewspace-1436541/ --这个主要和recr和freeabl类似. --1.节约内存 --2.减少检索链表的时间. --3.oracle的算法规定,sql语句必须至少是一父一子的情况.很多情况下都是一父多子.也就是说,每个游标,oracle都会为它设置个父游标 --  如果有sql文本相同,但无法共享执行计划的情况出现,那就会出现一父多子的情

Oracle内存结构详解(三) Oracle管理Share Pool

SGA中的共享池由库缓存(Library Cache).字典缓存(Dictionary Cache).用于并行执行消息的缓冲以及控制结构组成. Shared Pool的大小由参数SHARED_POOL_SIZE决定.9i中,在32位系统下,这个参数的默认值是8M,而64位系统下的默认值位64M.最大为4G. 10g 以后可以通过SGA_TARGET 参数来自动调整. 对于Shared Pool的内存管理,是通过修正过的LRU算法表来实现的. 1.库缓存(Library Cache) Librar

ORACLE从共享池删除指定SQL的执行计划

Oracle 11g在DBMS_SHARED_POOL包中引入了一个名为PURGE的新存储过程,用于从对象库缓存中刷新特定对象,例如游标,包,序列,触发器等.也就是说可以删除.清理特定SQL的执行计划,这样在特殊情况下,就避免你要将整个SHARED POOL清空的危险情况.例如某个SQL语句由于优化器产生了错误的执行计划,我们希望优化器重新解析,生成新的执行计划,必须先将SQL的执行计划从共享池中刷出或将其置为无效,那么优化器才能将后续SQL进行硬解析.生成新的执行计划.这在以前只能使用清空共享

Oracle体系结构:内存结构和进程结构

oracle|进程|体系 (一)内存结构和进程结构 Oracle数据库的总体结构如下图:  1:Oracle实例(Instance)           在一个服务器中,每一个运行的Oracle数据库都与一个数据库实例相联系,实例是我们 访问数据库的手段.  实例在操作系统中用ORACLE_SID来标识,在Oracle中用参数INSTANCE_NAME来标识, 它们两个的值是相同的.数据库启动时,系统首先在服务器内存中分配系统全局区(SGA), 构成了Oracle的内存结构,然后启动若干个常驻内

Oracle内存结构详解(一) Oracle SGA简介

Oracle的内存配置与oracle性能息息相关.关于内存的配置,是最影响Oracle性能的配置.内存还直接影响到其他两个重要资源的消耗:CPU和IO. 先看Oracle内存存储的主要内容是什么: 程序代码(PLSQL.Java): 关于已经连接的会话的信息,包括当前所有活动和非活动会话: 程序运行时必须的相关信息,例如查询计划: Oracle进程之间共享的信息和相互交流的信息,例如锁: 那些被永久存储在外围存储介质上,被cache在内存中的数据(如redo log条目,数据块). 每个Orac

《Oracle数据库管理与维护实战》——2.2 Oracle内存结构

2.2 Oracle内存结构 Oracle数据库管理与维护实战 Oracle内存存储了数据字典信息(即关于对象.逻辑结构.模式.权限等等的元数据).缓冲的应用数据.SQL语言.PL/SQL和Java程序数据,以及事物.控制.用户请求信息.图2-3是Oracle内存结构图,Oracle内存主要由SGA(系统全局区,System Global Area)和PGA(程序全局区,Program Global Area)两个区组成,此外还有重做日志缓冲区.大池.Java池等. 2-3 2.2.1 系统全局

共享池的调整与优化(Shared pool Tuning)

--======================================= -- 共享池的调整与优化(Shared pool Tuning) --=======================================       共享池(Shared pool)是SGA中最关键的内存片段,共享池主要由库缓存(共享SQL区和PL/SQL区)和数据字典缓存组成.其中库缓存的作用是存 放频繁使用的sql,pl/sql代码以及执行计划.数据字段缓存用于缓存数据字典.在内存空间有限的容量下