Skip to content

生成执行计划的过程:编译器:分为三部分:
2.优化器:–包括三个部分

查询转换器RBO–>CBO,目前是CBO ,optimizer_mode–ALL_ROWS参数值,适合OLTP。FIRST_ROWS_N适合分页,OLAP。

查询转化器:

视图合并–视图时直接用视图SQL语句对应表做基表进行连接。

谓词推进,子查询非嵌套化–相关子查询;OR–UNION合并

成本估算器:

拿数据字典里统计信息,主要有:

表:dba_tab_statistics –行数,块数

表中字段:dba_tab_col_statistics –选择率 selectivity 字段:number_distinct

索引:dba_ind_statistics 叶块 高度 聚簇因子

系统评估:CPU IO

数据字典本身:tab$,obj$,col$,con$

内部表:x$bh,x$ksmsp

计划生成器:访问路径–索引OR全表扫描,表连接的类型、顺序和方法

Oracle根据提交的SQL语句再查询相应的数据对象是否有统计信息。如果有统计信息的话,那么CBO将会使用这些统计信息产生所有可能的执行计划(可能多达成千上万个)和相应的Cost,最终选择Cost最低的那个执行计划。如果查询的数据对象无统计信息,则按RBO的默认规则选择相应的执行计划。这个步骤也是解析中最耗费资源的,因此我们应该极力避免硬解析的产生。

3.行源生成器:执行函数–对应执行计划中

4.执行引擎:

至此,解析的步骤已经全部完成,Oracle将会根据解析产生的执行计划执行SQL语句和提取相应的数据。

共享池之七:执行计划的生成过程

latch:library cache –desc v$librarycache;

latch:library cache用于保护hash bucket.
library cache lock保护HANDLE。
library cache pin保护library cache object–LCO.
从10G开始,library cache lock和library cache pin被MUTEX部分取代。暂时不讨论MUTEX。
latch:library cache的数量:
SYS@ bys3>select name from v$latch_children where name like ‘%librarycache%’;
隐含参数:_kgl_bucket_count,默认值大于等于系统中CPU个数的最小素数-不超过67。查询时会显示为0–BUG。
一个latch:library cache管理着多个librarycache buckets.

latch:library cache多是因为局部latch:library cache访问比较频繁,增大其数量并不能解决。
如果shared pool过小,也会引发librarycache latch竞争,进而引起shared pool latch竞争—参考AWR–Shared Pool Advisory
具有高version_count的SQL也容易导致latch:library cache,因为在搜索到子LCO前会一直持有latch:library cache。
#########

library cache lock保护HANDLE–父游标和子游标的handle

在硬解析时,需要以独占模式(EXCLUSIVE)持有librarycache lock和library cache pin。
进程访问LCO,首先需要在latch:librarycache的保护下获得library cache lock,才能访问和修改HANDLE;然后获取library cache pin,才能访问和LCO。
子游标的HANDLE和LCO的访问和上面一样。

MODE有三类: null 1;shared 2;exclusive 3;

null 1;空锁:空锁和独占锁互相不阻塞,主要起“标记”目的。标记对象正在使用中,或者标记对象以后还会用。保证对象内存不会被覆盖或释放。–可以执行三次,查看
select kglhdadr,kglhdpar,kglhdlmd,kglobhs0,kglobhd0,kglobhd6 from x$kglob wherekglnaobj like ‘select * from aaa’;
查看游标是否关闭。执行不大于3次,不会缓存,如有其它语句,则将未缓存的清空。
select * from bys.dept 执行三次,
SYS@ bys3>select kglhdadr,kglhdpar,kglhdlmd,kglhdpmd,kglobhs0,kglobhd0,kglobhd6from x$kglob where kglnaobj like ‘select * from bys.dept’;
KGLHDADR KGLHDPAR KGLHDLMD KGLHDPMD KGLOBHS0 KGLOBHD0 KGLOBHD6
——– ——– ———- ———- ———- ——– ——–
2499B1C0 24965DB4 1 0 4372 246C5CE0 252F0DD0 —-被缓存的子游标,
24965DB4 24965DB4 1 0 4500 23CC848C 00
被缓存的游标:当内存不足时,子游标堆6可以被覆盖,其它HADNLE等不可被覆盖。–原因是:重建执行计划的信息–父堆0,子堆0等都有可以快速重建执行计划-也算硬解析,但是消耗资源比正常硬解析少。

等待事件的P1 P2 P3分别是:

P1=HANDLE ADDRESS
P2=LOCK/PIN ADDRESS
PS=MODE*100+NAMESPACE
NAMESPACE分以下类型:
1.SQL AREA
2.TABLE/PROCEDURE/FUNCTION/PACKAGE HEADER
3.PACKAGE BADY
4.TRIGGER
5.INDEX
6.CLUSETER
7.PIPE
13.JAVA SOURCE
14.JAVE RESOURCE
32.JAVA DATA

常见的library cache lock持有模式的情况:

以独占持有的语句是:
ALTER TABLE……,
CREATE OR REPLACE PROCEDURE;
共享模式持有:SQL解析阶段
在SQL执行阶段,由共享模式转换为NULL。
定位引起library cache lock等待事件的语句:
select b.sid from x$kgllk a,v$session b where a.kgllkhdl in (select p1raw fromv$session_wait where wait_time=0 and event=’library cache lock’) and a.kgllkmod<>0and b.saddr=a.kgllkuse;

常见的library cache pin持有模式的情况:

以独占模式持有的是:
ALTER PROCEDURE ..COMPLE;
硬解析产生执行计划过程中需要
以共享模式持有的是:SQL执行阶段、PROCEDURE执行阶段。
定位引起library cache pin等待事件的会话:
select a.sid from x$kglpn b,v$session a where b.kglpnhdl in (select c.p1rawfrom v$session_wait c where c.wait_time=0 and c.event like ‘library cachepin%’) and b.kglpnmod<>0 and a.saddr=b.kglpnuse;

共享池之六:shared pool latch/ library cache latch /lock pin 简介

SubPool技术及优势:
从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争。
Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List、内存结构以及LRU List、shared pool latch。同时Oracle提供多个Latch对各个子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理)。从10G开始,每个SubPool由4个SUB PARTITION组成。
SubPool的个数和大小
每四个CPU分配一个SubPool,最多可以有7个。Shared Pool Latch也就从原来的一个增加到现在的7个。
在Oracle 9i中,每个SubPool至少为128MB。
10G-10.2.0.3,每个SubPool至少为256MB
10.2.0.3之后,最少为512M。
_kghdsidx_count 隐含参数:ORACLE启动时,优化根据此参数设置SubPool数量。
SubPool缺点:
从ORACL 10G开始,ORACLE进程在某个SubPool中请求内存失败,会到下一个SubPool中请求—过小的SubPool碎片问题可能更严重–ORA-4031出现机率更大。
过多的SubPool还会带来更高的管理协调成本。
比如以下错误就是与SubPool相关:
ORA-04031: unable to allocate 4216 bytes of shared memory
(“shared pool”,”unknown object”,”sga heap(2,0)”,”library cache”)
共享池大小的判断
LRU链表分两条:transient LRU(瞬时LRU)、 RECURRENT(周期LRU)。Chunk在第一次使用时,被放入瞬时LRU,第二次使用时,会被移至周期LRU。

DSI中建议用如下SQL统计LRU和相关信息:
select KGHLUTRN transient,KGHLURCR recurrent ,KGHLUFSH Flush_chunk_number, KGHLUOPS Pin_or_release_operations from X$KGHLU;
–查询出的是自数据库启动以来的,执行ALTER SYSTEM FLUSH SHARED_POOL不会清零。
其中:
TRANSIENT,瞬时LRU链长度。
RECURRENT,周期LRU链长度。
FLUSH_CHUNK_NUMBER,Flush Chunk数。
PIN_OR_RELEASE_OPERATIONS,Pin或释放Chunk操作的次数。
如果瞬时LRU链长度超过周期LRU链长度3倍,大量只用一次的Chunk堆积在LRU中,说明共享池太大了。
如果Flush Chunk数和Pin、释放Chunk操作次数的比小于1:20,说明共享池太小了。这个比例,简单点说,Oracle认为每20次操作Chunk,只有一次Flush Chunk操作,还是可以接受的。如果再低,说明共享池有点小。

######Chunk数和Pin、释放Chunk操作次数的比小于1:20,说明共享池太小了。
这一句错了吧,应该是大于20分之1(每20次操作有一次需要FLUSH CHUNK)时,如十分之1(每十次操作需要一次需要FLUSH CHUNK),说明共享池太小。
共享池一般不超过10G,5、6G即可。过大共享池需要更大管理成本
#####################################################################
结果集缓存–RESULT CACHE
DB_BUFFER只能缓存访问过的BLOCK,部分解决了物理读的问题,查询仍然需要大量的逻辑读。
物化视图提供的是查询重写的功能,对于大部分的情况,只是简化了SQL的复杂度,即使是完全满足查询的条件,物化视图的扫描也是不可避免的。
而缓存结果集——RESULT CACHE则截然不同,它缓存的是查询的结果。不在需要大量的逻辑读,不在需要任何的复杂计算,而是直接将已经缓存的结果返回。—SQL的几乎全部开销都可以避免。这些开销包括,解析时间、逻辑读、物理读和任意的通常可能会遭遇的争用。

RESULT CACHE的结果对于所有的SESSION都是可见的。
RESULT CACHE是满足一致性读的,而且当缓存表数据发生变化的时候,Oracle会自动INVALIDATE缓存结果集:
是否使用RESULT_CACHE与Oracle的执行计划无关:
RESULT CACHE忽略SQL语句的执行计划,即使执行计划发生了变化,只有最终获取的结果是一样的,Oracle仍然会使用RESULT CACHE。
注意当执行计划不同导致结果不同时,Oracle使用RESULT CACHE可能会得到不正确的结果。

对于SQL中间结果使用RESULT CACHE必须使用RESULT_CACHE提示进行强制。
RESULT CACHE功能对于下列情况是无效的:系统表和临时表;序列的NEXTVAL和CURRVAL伪列;SYSDATE、SYSTIMESTAMP等函数;所有非确定性PL/SQL函数。
RESULT_CACHE和NO_RESULT_CACHE
Oracle新增了两个HINT,RESULT_CACHE和NO_RESULT_CACHE。通过这两个提示,可以明确的指出下面的语句是否进行RESULT CACHE。

Oracle还增加了几个初始化参数来管理RESULT CACHE功能,如:RESULT_CACHE_MODE、RESULT_CACHE_MAX_SIZE等。
RESULT_CACHE_MAX_SIZE指明SGA中RESULT CACHE功能可以使用的最大的内存容量。如果这个参数设置为0,则关闭RESULT CACHE功能。
RESULT_CACHE_MODE参数设置Oracle如何使用RESULT CACHE,有三个值:MANUAL、AUTO、FORCE。
当参数值设置为MANUAL时,只有通过HINT明确提示的SQL才会读取缓存结果集。如果不加提示,那么Oracle不会利用已经缓存的结果。
对于AUTO模式,Oracle如果发现缓冲结果集已经存在,那么就会使用。但是如果缓冲结果集不存在,Oracle并不会自动进行缓冲。只有使用HINT的情况下,Oracle才会将执行的结果集缓存。
对于FORCE参数,就是会对所有的SQL进行缓存,除非明确使用NO_RESULT_CACHE提示:
result_cache_max_result设置单个sql语句占用整个RESULT CACHE缓冲区的百分比,默认5%。
RESULT_CACHE_MAX_SIZE用来设置RESULT CACHE的总体大小–不超过过SHARED_POOL_SIZE的75%

在11.2.0.4中,默认是:MANUAL
BYS@ bys3>show parameter result_cache_mode
NAME TYPE VALUE
———————————— ———– ——————————
result_cache_mode string MANUAL
Oracle提供了DBMS_RESULT_CACHE包来管理和维护RESULT CACHE。
Oracle还新增了几个关于RESULT CACHE的系统视图,用户可以看到和RESULT CACHE相关的各种信息,视图包括:V$RESULT_CACHE_DEPENDENCY、V$RESULT_CACHE_MEMORY、V$RESULT_CACHE_OBJECTS和V$RESULT_CACHE_STATISTICS等。
关于结果集缓存详见:
http://www.itpub.net/thread-846890-1-1.html
http://database.ctocio.com.cn/tips/365/8273865.shtml

共享池之五:Shared Pool子池与结果集缓存技术

字典缓冲区: dictionary cache,也叫row cache;
用于保存数据字典信息:如表空间相关信息、用户权限、objects信息、histogram信息等。
字典缓冲区在大小无法直接调整,只能通过调整共享池大小来调整字典缓冲区大小。
SYS@ bys3>select pool,name ,bytes/1024/1024 MB from v$sgastat where name like ‘row cache%’;
POOL NAME MB
———— ————————– ———-
shared pool row cache child latch .004959106
shared pool row cache 4.12324524
我的实验环境,字典缓冲区大小为4M多一点,还可以统计出row cache child latch的大小。
#####################################################################
row cache child latch

V$ROWCACHE视图可以查询保存在row cache中的对象信息。
row cache child latch的子latch个数:
SYS@ bys3>select count(name),name from v$latch_children where name like ‘row cache%’ group by name;
COUNT(NAME) NAME
———– —————————————————————-
52 row cache objects
每个子latch管理着不同的对象。
使用场景:
硬解析时需要从数据字典信息中生成执行计划,row cache信息由row cache child latch保护,所以在并发访问row cache时会引起row cache child latch竞争。

row cache child latch 常见场景:
1.DDL操作需要修改数据字典
2.SEQUENCE:原因是SEQUENCE的NEXTVAL操作对row cache objects以SSX(SHARED SUB_EXVLUSIVE)独占模式获得row cache lock. 当多个进程同时对同一SEQUENCE的NEXTVAL进行调用时会发生:latch:row cache objects等待事件。
如CACHE过小,当CACEH分配的值用完会重新获取一次CACHE,会更新seq$基表并提交—修改ROW CACHE信息,会话会一直持有SQ锁,会出现enq:sq-contention等待事件。—P2值是对象号。
NOCACHE:每次使用NEXTVAL,都要更新seq$基表并提交。
关于SEQUENCE,详见:http://blog.csdn.net/haibusuanyun/article/details/17248029#t2

3.SYS.AUDSED$: ORACLE 10.2.0.4之前SYS.AUDSED$的CACHE值为20,主要用于V$SESSION.AUDSID的取值。当出现大量并发短连接–登陆风暴,容易因SYS.AUDSED$的CACHE值过小引起会话一直持有SQ锁,出现enq:sq-contention等待事件。===解决方法:将SYS.AUDSED$的CACHE值改大。
10.2.0.4之后,SYS.AUDSED$的CACHE值默认为10000.

4.通过远程DBLINK访问的SQL在本地解析时要获取16号row cache child latch,可能会引起争用–可以在内存足够情况下增大共享池及PGA大小,增加session_cache_cursor大小—注意要重启库且要注意增大会占用更多内存。 –此案例见周亮《ORACLE DBA 实战攻略》301页。

共享池之四: row cache–字典缓冲区

Library cache结构
Library cache最主要的功能就是存放用户提交的SQL语句,SQL语句相关的解析树(解析树也就是对SQL语句中所涉及到的所有对象的展现)—>共享SQL区(shared SQL areas),私有SQL区(private SQLareas,如果配置了共享服务器),执行计划,用户提交的PL/SQL程序块(包括匿名程序块,存储过程,包,函数等)以及它们转换后能够被Oracle执行的代码等,为了对这些内存结构进行管理,library cache中还存放了很多控制结构,包括lock,pin,dependency table,11G中的mutex等。
Library cache需要解决三个问题:
(1).快速定位的问题:Library cache中对象众多,Oracle如何管理这些对象,以便服务进程可以迅速找到他们需要的信息。比如某个服务进程需要迅速定位某个SQL是否存在于Librarycache中。- –Oracle利用hash table结构来解决library cache中快速定位的问题
(2).关系依赖的问题:Library cache中的对象存在复杂的依赖关系,当某个objec失效时,可以迅速将依赖其的对象也置为失效状态。比如某个表发生了结构变化,依赖其的SQL语句需要重新解析。—LCO中 dependency table
(3).并发控制的问题:Library cache中必须有一个并发控制的机构,比如锁机制,来管理大量共享对象的并发访问和修改的问题,比如某个SQL在重新编译的同时,其所依赖的对象不能被修改。—-LATCH LOCK PIN

Library cache由一个hash表组成,hash表是由hash buckets组成的数组。
每个hash bucket都是包含library cache handle的一个双向链表。
library cache handle指向library cache object和一个引用列表。
library cache 对象进一步分为:依赖表、子表、授权表等
同一个SQL语句,HASH值相同,放在同一个library cache handle–如绑定变量,是用同一个library cache handle下不同的的子游标。不同的SQL语句,HASH值相同放在同一hash bucket的不同library cache handle。
Hash 算法
Oracle在内部管理中大量的使用到了hash,使用hash的目的就是为了快速查找和定位.
对数值进行hash运算,产生一个索引号,然后根据索引号将数值放置到相应的hash bucket中去.
根据hash运算的法则,会产生多个索引号,每一个索引号对应一个hash bucket(一个数值列).
在寻找数值的时候,将搜寻的数值进行hash,产生一个索引号,那么这个数值一定在这个索引号对应的 hash bucket中,于是直接跳转到这个hash bucket中进行遍历。这样在定位数据的时候,就能够大大的减少遍历的数量。

hash bucket:库缓存中就是使用hash bucket来管理的
1、首先根据shared_pool_size指定的尺寸来自动计算hash bucket的个数
2、每个hash bucket后面都串联着多个句柄
句柄描述了library cache里面的对象的一些属性,包括名称、标记、指向对象所处的内存地址的指针

library cache handle:—–OBJECT Handle
一个handle管理着一个library cache object,handle对LCO起到指针作用。
Library cache中所有对象的访问是通过利用library cache handle来实现的
当一个进程请求library cache object, librarycache manager就会应用一个hash 算法,从而得到一个hash 值,根据相应的hash值到相应的hash bucket中去寻找。
如果library cache object在内存中,那么这个library cache handle就会被找到。有时候,当shared pool不够大,library cache handle会保留在内存中,然而library cache heap由于内存不足被age out,这个时候我们请求的object heap就会被重载。最坏的情况下,library cache handle在内存中没有找到,这个时候就必须分配一个新的library cachehandle,同时object heap也会被加载到内存中。

###############

library cache object的结构: –LCO
见上图,主要保存SQL的实际信息,包括:
dependency table –当前LCO依赖的其它LCO信息,如SQL语句依赖的表、视图等。
1.Chile table—-保存当前LCO的子LCO信息
一个LCO会有多个子LCO—多版本问题。—一条SQL至少有一个parent cursor 和 child cursor。
存在不同版本SQL可能是:不同用户执行相同SQL文件的SQL.–也可能是BUG。

SQL语句文本一样-HASH值一样,执行计划不一样的情况有:–多版本
1.不同用户下有同名的表,不同的用户执行查询此表操作,就会出现不同执行计划。
2.绑定变量时,如果绑定变量的字符串( 详见:绑定变量分级)变化达到一定程度,执行计划也会不一样

HIGH VERSION高版本的SQL语句有多个子LCO,每个子HANDLE对应一个子LCO。—parent cursor 里对应的所有child cursor的指针都会保存在child table里面。- -parent cursor和child cursor都是用library cache object handle 存储在Library Cache里的。—结构一样
当子LCO数量很多–SQL版本数(VERSION COUNT)很高,会话扫描BUCKET时间变长,持有latch:library cache时间也变长,定位到具体的child sql cursor时间相应变长(顺序扫描HANDLE),latch:library cache争用的概念增加。
查看SQL版本信息:
BYS@ bys3>select * from (select version_count,sql_id,sql_text from v$sqlarea order by version_count desc) where rownum<5 ;

BYS@ bys3>select version_count,sql_id,sql_text from v$sqlarea where sql_text like ‘select * from bys.dept’;
VERSION_COUNT SQL_ID SQL_TEXT
————- ————- ——————————
1 f4yk5kundsxfd select * from bys.dept
2.data blocks —保存SQL语句、执行计划、执行文本等信息。
ORACLE通过地址指向存储 这些信息的HEAP /CHUNK。HEAP 6存储着SQL执行计划。
ORACLE 10.2.0.4开始可以通过dbms_shared_pool.purge 包清理HEAP 6中执行计划。
3.dependency table
指向本对象所依赖的对象,比如:select * from emp这个cursor的对象,依赖emp这个表,这里指向了emp这个表的handle。
####################################################3
通过x$kglob找出SQL语句父游标地址,并DUMP library cache,在TRACE文件中父游标的地址中找到SQL语句。
会话1
SYS@ bys3>select * from bys.dept;
SYS@ bys3>col KGLNAOBJ for a40
SYS@ bys3> select kglhdadr,kglhdpar,kglnaobj,kglobhd0 from x$kglob where kglnaobj like ‘select * from bys.dept%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHD0
——– ——– —————————— ——–
23ACB574 248344B8 select * from bys.dept 242B7D1C –23ACB574子游标地址
248344B8 248344B8 select * from bys.dept 23FE4684 –248344B8父游标地址,父游标heap 0地址-其实是描述符-23FE4684

select KGLHDADR,KGLHDPAR,KGLNAOBJ,KGLOBHD0 from x$kglob where kglnaobj like ‘select * from bys.dept%’ and KGLHDADR<>KGLHDPAR ; 查出子游标
select KGLHDADR,KGLHDPAR,KGLNAOBJ,KGLOBHD0 from x$kglob where kglnaobj like ‘select * from bys.dept%’ and KGLHDADR=KGLHDPAR ; 查出父游标

SYS@ bys3> select KSMCHPTR,KSMCHCOM,KSMCHCLS,KSMCHSIZ from x$ksmsp where KSMCHPAR=’23FE4684′; –通过上一步查出的 heap 0描述符找到查看父游标所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
241D3A44 KGLH0^a8dc75cd recr 4096

新打开一个会话:DUMP library cache并查找SQL语句。
SYS@ bys3>alter session set events ‘immediate trace name heapdump level 2050’;
SYS@ bys3>select value from v$diag_info where name like ‘De%’;
VALUE
—————————————————————————————————-
/u01/diag/rdbms/bys3/bys3/trace/bys3_ora_31638.trc
#################
VI中查询: 在241D3A44这个地址开始的这个 Chunk中找到了SQL语句
Chunk 241d3a44 sz= 4096 recreate “KGLH0^a8dc75cd ” latch=(nil)
ds 23fe4684 sz= 4096 ct= 1
Dump of memory from 0x241D3A44 to 0x241D4A44
241D3A40 80001001 241D2A44 00000000 [….D*.$….]
241D3A50 00000000 00000000 00000000 000A0FFF […………….]
………………

Chunk 2405e530 sz= 4096 recreate “SQLA^bf04295e ” latch=(nil)
Dump of memory from 0x2405E530 to 0x2405F530
2405E530 80001001 2405E164 2526A6EC 237A8414 [….d..$..&%..z#]
………………
2405E680 00000000 00000000 00000000 00000000 […………….]
2405E690 00000000 00000000 F4A4D8E8 735DAFAF […………..]s]
2405E6A0 00000000 00000049 2405E65C 11390064 [….I…\..$d.9.]
2405E6B0 01748F8F 18150001 407EC500 0A8A0500 [..t…….~@….]
2405E6C0 00020103 00090203 093A0000 1E070604 [……….:…..]
2405E6D0 F0836A0A A8E0F183 E036E426 83E426A8 [.j……&.6..&..]
2405E6E0 03F383F5 02030302 008E0000 00000025 […………%…]
2405E6F0 2405E6A4 110B3B04 656C6573 2A207463 […$.;..select *]
2405E700 6F726620 7962206D 65642E73 00257470 [ from bys.dept%.]
2405E710 0000003D 2405E6EC 110B3B34 0000000D [=……$4;……]
2405E720 00000801 00170040 00010369 00000018 [….@…i…….]
…………
###########################################################################

通过x$kglob找出SQL语句子游标地址及堆6地址,并DUMP library cache,在TRACE文件中查看的内容。
堆0 heap 0 –属于父游标-library cache handle,子游标里也有两个堆,堆0 存放指向堆6的地址
SYS@ bys3>select * from bys.dept;
SYS@ bys3>col KGLNAOBJ for a25
SYS@ bys3> select kglhdadr,kglhdpar,kglnaobj,KGLOBHS0,kglobhd0,KGLOBHS6,KGLOBHD6 from x$kglob where kglnaobj like ‘select * from bys.dept%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHS0 KGLOBHD0 KGLOBHS6 KGLOBHD6
——– ——– ————————- ———- ——– ———- ——–
2358B76C 23D0705C select * from bys.dept 4348 2526A068 4060 243F2238
23D0705C 23D0705C select * from bys.dept 4516 23D65B44 0 00
父游标LibraryHandle 地址KGLHDPAR:23D0705C 子游标LibraryHandle地址KGLHDADR:2358B76C,
父游标堆0描述KGLOBHD0:23D65B44,子游标堆0描述:2526A068,子游标堆6描述KGLOBHD6:243F2238

这一点可以DUMP查看, alter session set events ‘immediate trace name heapdump_addr level 2,addr0x23b31e80‘; 类似以下:desc=0x23b31e80这种就可以与上面查出的KGLOBHD0字段信息对应–我这是后来增加的,没法对应上了。

******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x23b31e80
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x23b31e4c nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x240b19c4
EXTENT 0 addr=0x240b19c4
Chunk 240b19cc sz= 44 p

SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’23D65B44′;
–通过上一步查出的父游标heap 0描述符找到查看父游标所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
243F1D68 KGLH0^a8dc75cd recr 4096
SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’2526A068′;
–通过上一步查出的子游标heap 0描述符找到查看子游标堆0所在CHUNK地址大小描述状态:
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
23FDD830 KGLH0^a8dc75cd recr 4096 –KGLH0^a8dc75cd –H0 heap 0
SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’243F2238’;
–通过上一步查出的子游标heap 6描述符,找到查看子游标堆6所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
23FDB830 SQLA^a8dc75cd recr 4096 –SQLA^a8dc75cd -SQL area

SYS@ bys3>col sql_text for a25
SYS@ bys3>select sql_id,hash_value,address,child_address,sql_text from v$sql where sql_text like ‘select * from bys.dept%’;
–查看SQL语句的SQL_ID,HASH_VALUE ADDRESS CHILD_AD等信息,与下面DUMP的信息对照。
SQL_ID HASH_VALUE ADDRESS CHILD_AD SQL_TEXT
————- ———- ——– ——– ————————-
f4yk5kundsxfd 2833020365 23D0705C 2358B76C select * from bys.dept
新会话DUMP
SYS@ bys3>alter session set events ‘immediate trace name library_cache level 16’;
Session altered.
level 1,转储library cache统计信息;level 2,转储hash table 概要
level 4,转储library cache对象基本信息;level 4,转储library cache对象详细信息
level 16,增加了heap sizes信息。
SYS@ bys3>select value from v$diag_info where name like ‘De%’;
VALUE
—————————————————
/u01/diag/rdbms/bys3/bys3/trace/bys3_ora_22403.trc

#########################################
Bucket: #=30157 Mutex=0x26ab5658(2e0000, 78, 0, 6)
LibraryHandle: Address=0x23d0705c Hash=a8dc75cd LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD
##Address=0x23d0705c与x$kglob.KGLHDPAR父游标地址相符.Hash=a8dc75cd与x$ksmsp.KSMCHCOM相符,转换为10进制则与v$sql.HASH_VALUE相符;
ObjectName: Name=select * from bys.dept ##执行的语句内容,与x$kglob.KGLNAOBJ
FullHashValue=2cd147d1d9b8972be27a4596a8dc75cd Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=2833020365 OwnerIdn=0
##Identifier=2833020365与v$sql.HASH_VALUE相符,Namespace=SQL AREA(00) SQL区域
Statistics: InvalidationCount=0 ExecutionCount=1 LoadCount=2 ActiveLocks=0 TotalLockCount=1 TotalPinCount=1
Counters: BrokenCount=1 RevocablePointer=1 KeepDependency=1 Version=0 BucketInUse=0 HandleInUse=0 HandleReferenceCount=0
Concurrency: DependencyMutex=0x23d070c4(0, 1, 0, 0) Mutex=0x23d07120(46, 39, 0, 6)
Flags=RON/PIN/TIM/PN0/DBN/[10012841]
WaitersLists:
Lock=0x23d070b4[0x23d070b4,0x23d070b4]
Pin=0x23d070a4[0x23d070a4,0x23d070a4]
LoadLock=0x23d070e8[0x23d070e8,0x23d070e8]
Timestamp: Current=01-04-2014 18:03:50 ##时间戳
HandleReference: Address=0x23d0718c Handle=(nil) Flags=[00]
ReferenceList:
Reference: Address=0x23fdcb14 Handle=0x2345e2a8 Flags=ROD[21]
LibraryObject: Address=0x243f1dc8 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]
DataBlocks:
Block: #=’0′ name=KGLH0^a8dc75cd pins=0 Change=NONE
Heap=0x23d65b44 Pointer=0x243f1e1c Extent=0x243f1d84 Flags=I/-/P/A/-/-
FreedLocation=0 Alloc=1.546875 Size=3.988281 LoadTime=4405191980
ChildTable: size=’16’
Child: id=’0′ Table=0x243f2d18 Reference=0x243f2390 Handle=0x2358b76c ##子指针
Children:
Child: childNum=’0′
L ibraryHandle: Address=0x2358b76c Hash=0 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD
##子游标LibraryHandle地址Address=0x2358b76c,与x$kglob.KGLHDADR子游标地址相符
Name: Namespace=SQL AREA(00) Type=CURSOR(00)
Statistics: InvalidationCount=0 ExecutionCount=1 LoadCount=1 ActiveLocks=0 TotalLockCount=1 TotalPinCount=2
Counters: BrokenCount=1 RevocablePointer=1 KeepDependency=0 Version=0 BucketInUse=0 HandleInUse=0 HandleReferenceCount=0
Concurrency: DependencyMutex=0x2358b7d4(0, 0, 0, 0) Mutex=0x23d07120(46, 39, 0, 6)
Flags=RON/PIN/PN0/EXP/CHD/[10012111]
WaitersLists:
Lock=0x2358b7c4[0x2358b7c4,0x2358b7c4]
Pin=0x2358b7b4[0x2358b7b4,0x2358b7b4]
LoadLock=0x2358b7f8[0x2358b7f8,0x2358b7f8]
ReferenceList:
Reference: Address=0x243f2390 Handle=0x23d0705c Flags=CHL[02]
LibraryObject: Address=0x23fdd890 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]
Dependencies: count=’1′ size=’16’ table=’0x23fde7a4′
Dependency: num=’0′
Reference=0x23fddcb0 Position=18 Flags=DEP[0001]
Handle=0x2433a460 Type=TABLE(02) Parent=BYS.DEPT
ReadOnlyDependencies: count=’1′ size=’16’
ReadDependency: num=’0′ Table=0x23fde7f0 Reference=0x23fddc1c Handle=0x2345e2a8 Flags=DEP/ROD/KPP[61]
Accesses: count=’1′ size=’16’
Dependency: num=’0′ Type=0009
DataBlocks:
Block: #=’0′ name=KGLH0^a8dc75cd pins=0 Change=NONE
Heap=0x2526a068 Pointer=0x23fdd8e4 Extent=0x23fdd84c Flags=I/-/-/A/-/-
#####Heap=0x2526a068子游标堆0的地址,与x$kglob.KGLOBHD0相符
FreedLocation=0 Alloc=1.382812 Size=3.964844 LoadTime=4405191980
Block: #=’6′ name=SQLA^a8dc75cd pins=0 Change=NONE
Heap=0x243f2238 Pointer=0x23fdc624 Extent=0x23fdb84c Flags=I/-/-/A/-/E
##Heap=0x243f2238这个就是子游标堆6的地址,与x$kglob.KGLOBHD6相符
FreedLocation=0 Alloc=3.785156 Size=3.964844 LoadTime=0
NamespaceDump: –子游标信息
Child Cursor: Heap0=0x23fdd8e4 Heap6=0x23fdc624 Heap0 Load Time=01-04-2014 18:03:50 Heap6 Load Time=01-04-2014 18:03:50
NamespaceDump:
Parent Cursor: sql_id=f4yk5kundsxfd parent=0x243f1e1c maxchild=1 plk=n ppn=n
##父游标,sql_id=f4yk5kundsxfd与v$sql.sql_id相符,
###############################################

DUMP SQL语句父子游标的堆0和堆6
SYS@ bys3>select kglhdadr,kglhdpar,kglnaobj,KGLOBHS0,kglobhd0,KGLOBHS6,KGLOBHD6 from x$kglob where kglnaobj like ‘select * from bys.test%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHS0 KGLOBHD0 KGLOBHS6 KGLOBHD6
——– ——– ————————- ———- ——– ———- ——–
240EDA68 239948A4 select * from bys.test 4348 23B31E80 4060 245908B0
239948A4 239948A4 select * from bys.test 4500 241368BC 0 00

alter session set events ‘immediate trace name heapdump_addr level 2,addr 0x241368BC’; –使用这样的语句把父子游标的堆0、堆6全DUMP出来。

我把三个DUMP文件的开头贴一下:

父游标堆0:desc=字段与x$kglob.KGLOBHD0对应,heap name=”KGLH0^ 堆名字也表明是堆0
******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x241368bc
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x24136888 nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x245903fc
EXTENT 0 addr=0x245903fc
Chunk 24590404 sz= 44 perm “perm ” alo=44
Dump of memory from 0x24590404 to 0x24590430

子游标堆0:–我的版本是11.2.0.4,有的版本DUMP出来的heap name=”CCURSE,,比较直观说明是子游标。。这 里只能通过desc=字段与x$kglob.KGLOBHD6对应

******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x23b31e80
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x23b31e4c nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x240b19c4
EXTENT 0 addr=0x240b19c4
Chunk 240b19cc sz= 44 perm “perm ” alo=44

子游标堆6: –从DUMP名字也可以看出是存放SQL执行计划等的SQL区域。–有的版本DUMP出来这里显示的heapname=”SQL AREA,我这个11.2.0.4版本上看就这样了。。

******************************************************
HEAP DUMP heap name=”SQLA^1020848″ desc=0x245908b0
extent sz=0xff4 alt=32767 het=184 rec=0 flg=2 opc=2
parent=0x200010b4 owner=0x245907e4 nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x27, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x24b12c54
EXTENT 0 addr=0x24b12c54
Chunk 24b12c5c sz= 44 perm “perm ” alo=44

shared pool:library cache结构/library cache object的结构-dump LibraryHandle