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

简介: [20151229]关于共享池4x-SQL内存结构父子游标 (补充3).txt -- 前几天的测试,还是有点问题,链接如下: -- http://blog.itpub.

[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,其他版本我不确定是这种情况。

目录
相关文章
|
11月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
934 55
|
11月前
|
Go 开发者
Go语言内存共享与扩容机制 -《Go语言实战指南》
本文深入探讨了Go语言中切片的内存共享机制与自动扩容策略。切片作为动态数组的抽象,其底层结构包含指针、长度和容量。多个切片可能共享同一底层数组,修改一个切片可能影响其他切片。当切片容量不足时,`append`会触发扩容,新容量按指数增长以优化性能。为避免共享导致的副作用,可通过`copy`创建独立副本或在函数中使用只读方式处理。最后总结了最佳实践,帮助开发者高效使用切片,写出更优代码。
272 10
|
存储 NoSQL Redis
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 +  无锁架构 +  EDA架构  + 异步日志 + 集群架构
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
|
SQL 存储 缓存
【赵渝强老师】达梦数据库的内存结构
本文介绍了达梦数据库管理系统的内存结构,包括内存池、缓冲区、排序区和哈希区。内存池分为共享内存池和运行时内存池,能够提高内存申请与释放效率,并便于监控内存使用情况。缓冲区涵盖数据缓冲区、日志缓冲区、字典缓冲区和SQL缓冲区,用于优化数据读写和查询性能。排序区和哈希区分别提供排序和哈希连接所需的内存空间,通过合理配置参数可提升系统效率。文内附有具体配置示例及视频讲解,帮助用户深入理解达梦数据库的内存管理机制。
436 0
|
SQL 监控 数据库
如何解决 SQL Server 占用内存过多问题
SQL Server 占用过多内存会导致响应缓慢和查询性能低下。解决流程包括:1) 查看内存使用情况,2) 分析各数据库内存占用,3) 优化 SQL Server 配置(如限制最大内存),4) 优化查询(如创建索引),5) 持续监控效果。通过这些步骤可有效控制内存占用,提升系统性能。
1429 0
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
198 3
|
存储 算法 Java
聊聊jvm的内存结构, 以及各种结构的作用
【10月更文挑战第27天】JVM(Java虚拟机)的内存结构主要包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和运行时常量池。各部分协同工作,为Java程序提供高效稳定的内存管理和运行环境,确保程序的正常执行、数据存储和资源利用。
478 10
|
存储 安全 Java
JVM内存结构
这篇文章详细介绍了Java虚拟机(JVM)的内存结构,包括类的加载过程、类加载器的双亲委派机制、沙箱安全机制、程序计数器、Java栈、Java堆、本地方法和本地方法栈等关键组件及其作用。
JVM内存结构
下一篇
开通oss服务