librarycache内存详解.docx

上传人:b****8 文档编号:29830810 上传时间:2023-07-27 格式:DOCX 页数:93 大小:470.71KB
下载 相关 举报
librarycache内存详解.docx_第1页
第1页 / 共93页
librarycache内存详解.docx_第2页
第2页 / 共93页
librarycache内存详解.docx_第3页
第3页 / 共93页
librarycache内存详解.docx_第4页
第4页 / 共93页
librarycache内存详解.docx_第5页
第5页 / 共93页
点击查看更多>>
下载资源
资源描述

librarycache内存详解.docx

《librarycache内存详解.docx》由会员分享,可在线阅读,更多相关《librarycache内存详解.docx(93页珍藏版)》请在冰豆网上搜索。

librarycache内存详解.docx

librarycache内存详解

librarycache的内存结构

1.写在最前

一.objecthandle和object(leap0)还有leap1-11是在逻辑上连续的,但是他们存放在不同的memoryaddress里面.它们三个都有自己的address.

二.parentscursor和childcursor他们两个都有自己的objecthandle,object.

三.parentscursor有leap0但没有leap1-11,childcursor有leap0和leap1-11

四.parentscursor和childcursor的主要信息都存放在leap0里面,child还有一个leap1-11的指针parents和childcursor只是不同objecthandle中的两类

五.父游标里主要包含两种信息:

SQL文本以及优化目标(optimizergoal)

六.parentscursor有hashvalue但是childcursor没有hashvalue?

?

?

?

七.childcursor的librarycacheobjecthandle对应的动态性能视图是v$sql

八.PARENTCURSOR的librarycacheobjecthandle对应的动态性能视图为v$sqlarea

九.同一个SQL,会生成多个childcursor和一个parentcursor.每生成一个childcursor,在parentcursor就记录为一个version。

在v$sqlarea.version_count中记录的数字是所有曾生成过的childcursor

一十.parentcursor和childcursor都是librarycacheobject,它们的结构是一摸一样的

一十一.子游标随时可以被交换出librarycache,当子游标被交换出librarycache时,oracle可以利用父游标的信息重新构建出一个子游标来,这个过程叫reload----可以使用下面的方式来确定reload的比率:

SELECT100*sum(reloads)/sum(pins)Reload_RatioFROMv$librarycache

一十二.

2.sharedpool

Howisitmanaged

Sharedpool和PGA都是由一个Oracle的内存管理器来管理,我们称之为KGHheapmanager。

HeapManager不是一个进程,而是一串代码。

HeapManager主要目的就是满足server进程请求memory的时候分配内存或者释放内存。

HeapManager在管理PGA的时候,HeapManager需要和操作系统来打交道来分配或者回收内存。

但是呢,在sharedpool中,内存是预先分配的,HeapManager管理所有的空闲内存。

当某个进程需要分配sharedpool的内存的时候,HeapManager就满足该请求,HeapManager也和其他ORACLE模块一起工作来回收sharedpool的空闲内存。

3.librarycache

LibraryCacheManager

LibrarycacheManager可以看做是HeapManager的客户端,因为librarycachemanager是根据HeapManager来分配内存从而存放librarycacheobjects。

LibrarycacheManager控制所有的librarycacheobject,包括package/procedure,cursor,trigger等等。

librarycache最主要的功能

librarycache最主要的功能就是存放用户提交的SQL语句、SQL语句相关的解析树(解析树也就是对SQL语句中所涉及到的所有对象的展现)、执行计划、用户提交的PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被oracle执行的代码等。

为了对这些内存结构进行管理,还存放了很多控制结构,包括lock、pin、dependencytable等。

librarycache存放的信息

librarycache还存放了很多的数据库对象的信息,包括表、索引等等。

有关这些数据库对象的信息都是从dictionarycache中获得的。

如果用户对librarycache中的对象信息进行了修改,则这些修改会返回到dictionarycache中。

在librarycache中存放的所有的信息单元都叫做对象(object),这些对象可以分成两类:

一类叫存储对象,也就是上面所说的数据库对象。

它们是通过显式的SQL语句或PL/SQL程序创建出来的,如果要删除它们,也必须通过显示的SQL命令进行删除。

这类对象包括表、视图、索引、包、函数等等;另一类叫做过渡对象,也就是上面所说的用户提交的SQL语句或者提交的PL/SQL程序块等。

这些过渡对象是在执行SQL语句或PL/SQL程序的过程中产生的,并缓存在内存里。

如果实例关闭则删除,或者由于内存不足而被交换出去,从而被删除。

Howisitmanaged----librarycache

当用户提交SQL语句或PL/SQL程序块到oracle的sharedpool以后,在librarycache中生成的一个可执行的对象,这个对象就叫做游标(cursor)。

不要把这里的游标与标准SQL(ANSISQL)的游标混淆起来了,标准SQL的游标是指返回多条记录的SQL形式,需要定义、打开、关闭。

下面所说到的游标如无特别说明,都是指librarycache中的可执行的对象。

游标是可以被所有进程共享的,也就是说如果100个进程都执行相同的SQL语句,那么这100个进程都可以同时使用该SQL语句所产生的游标,从而节省了内存。

每个游标都是由librarycache中的两个或多个对象所体现的,至少两个对象。

一个对象叫做父游标(parentcursor),包含游标的名称以及其他独立于提交用户的信息。

从v$sqlarea视图里看到的都是有关父游标的信息;另外一个或多个对象叫做子游标(childcursors),如果SQL文本相同,但是可能提交SQL语句的用户不同,或者用户提交的SQL语句所涉及到的对象为同名词等,都有可能生成不同的子游标。

因为这些SQL语句的文本虽然完全一样,但是上下文环境却不一样,因此这样的SQL语句不是一个可执行的对象,必须细化为多个子游标后才能够执行。

子游标含有执行计划或者PL/SQL对象的程序代码块等。

深入解析Cursor和绑定变量

Oracle里的cursor分为两种:

一种是sharedcursor,一种是sessioncursor

子游标和父游标都存储在objecthandle的

子游标和父游标是独立的.他们都有自己的handle,有自己的object.子游标的heap6存放解析过的sql语句(执行计划和parsetree).父游标的

所谓的sharedcursor就是指缓存在librarycache里的一种librarycacheobject,说白了就是指缓存在librarycache里的sql和匿名pl/sql。

它们是Oracle缓存在librarycache中的几十种librarycacheobject之一,它所属于的namespace是CRSR(也就是cursor的缩写)。

parentcursor和childcursor都是sharedcursor,它们都是以librarycacheobjecthandle的方式存在librarycache里,当一条sql第一次被执行的时候,会同时产生parentcursor和childcursor,parentcursor的librarycacheobjecthandle的heap0(table字段里面的childtable项里面的handle---子游标的handle的address)里会存储其childcursor的handle的地址,这个sql的执行计划会存储在上述childcursor的librarycacheobjecthandle的heap6中,第一次执行上述sql所产生的parentcursor和childcursor的过程也就是所谓的“硬解析”主要做的事情。

如果上述sql再次执行,Oracle只需要去扫描相应的librarycacheobjecthandle,找到上次硬解析后产生的childcursor,把里面的parsetree和执行计划直接拿过用就可以了,这就是所谓的“软解析”。

Oracle里的第二种cursor就是sessioncursor,sessioncursor又分为三种:

分别是implicitcursor,explicitcursor和refcursor。

所谓的sessioncursor其实就是指的跟这个session相对应的serverprocess的PGA里(准确的说是UGA)的一块内存区域(或者说内存结构),它的目的是为了处理且一次只处理一条sql语句(这里是指一个implicitcursor一次只处理一条sql,explicitcursor和refcursor处理sql的数量是由你自己所控制)。

 

一个sessioncursor只能对应一个sharedcursor,而一个sharedcursor却可能同时对应多个sessioncursor。

当session_cached_cursors的值大于0的时候,当一个sessioncursor处理完一条sql后,它就不会被destroy,Oracle会把其cache起来(我们称之为softclosedsessioncursor),这么做的目的是很明显的,当在这个session中再次执行同样的sql的时候,Oracle就不再需要reopen这个cursor了(即省掉了重新open和close这个cursor的时间),直接把刚才已经softclosed掉的sessioncursor拿过来用就好了,这就是所谓的“软软解析”。

几个关于cursor的参数

1、open_cursors

open_cursors指的是在单个session中同时能以open状态存在的sessioncursor的最大数量 

2、session_cached_cursors

session_cached_cursors指的是单个session中同时能cache住的softclosedsessioncursor的最大数量

3、cursor_space_for_time

关于cursor_space_for_time有三点需要注意:

1)10.2.0.5和11.1.0.7里它已经作废了;2)把它的值调成true后如果还同时用到了绑定变量,则由于Bug6696453的关系,可能会导致logicaldatacorruption;3)把它的值调成true后,所有的childcursor在执行完后依然会持有librarycachepin,直到其parentcursor关闭

hash算法

简介

在介绍librarycache的内部管理机制前,先简单介绍一下所谓的hash算法。

oracle内部在实现管理的过程中大量用到了hash算法。

hash算法是为了能够进行快速查找定位所使用一种技术。

哈希表是一个以空间换取时间的数据结构.所谓hash算法,就是根据要查找的值,对该值进行一定的hash算法后得出该值所在的索引号,然后进入到该值应该存在的一列数值列表(可以理解为一个二维数组)里,通过该索引号去找它应该属于哪一个列表。

然后再进入所确定的列表里,对其中所含有的值,进行一个一个的比较,从而找到该值。

这样就避免了对整个数值列表进行扫描才能找到该值,这种全扫描的方式显然要比hash查找方式低效很多。

其中,每个索引号对应的数值列在oracle里都叫做一个hashbucket。

我们来列举一个最简单的hash算法。

假设我们的数值列表最多可以有10个元素,也就是有10个hashbuckets,每个元素最多可以包含20个数值。

则对应的二维数组就是t[10][20]。

我们可以定义hash算法为nMOD10。

通过这种算法,可以将所有进入的数据均匀放在10个hashbucket里面,hashbucket编号从0到9。

比如,我们把1到100都通过这个hash函数均匀放到这10个hashbucket里,当查找32在哪里时,只要将32MOD10等于2,这样就知道可以到2号hashbucket里去找,也就是到t[2][20]里去找,2号hashbucket里有10个数值,逐个比较2号hashbucket里是否存在32就可以了。

详解oracle如何使用hash算法

librarycache就是使用多个hashbucket来管理的,其hash算法当然比我们前面列举的要复杂多了。

每个hashbucket后面都串连着多个句柄(该句柄叫做librarycacheobjecthandle),这些句柄描述了librarycache里的对象的一些属性,包括名称、标记、指向对象所处的内存地址的指针等。

可以用下图一来描述librarycache的整体结构。

hashbucket后面跟了句柄(handle)---->句柄里面包括了各种内存管理信息---->Heap0(内存指针,堆)是对象的概要信息,下面又有heap1...heap6...记录了详细信息。

objecthandle----又叫做librarycachehandle

简介

当一条SQL语句进入librarycache的时候,先将SQL文本转化为对应ASCII数值,然后对该这些ASCII数值进行hash函数的运算,传入函数的是SQL语句的名称(name,对于SQL语句来说其name就是SQL语句的文本)以及命名空间(namespace,对于SQL语句来说是“SQLAREA”,表示共享游标。

可以从视图v$librarycache里找到所有的namespace)。

运用hash函数后得到一个值,该值就是hashbucket的号码,从而该SQL语句被分配到该号的hashbucket里去。

实际上,hashbucket就是通过串连起来的对象句柄才体现出来的,它本身是一个逻辑上的概念,是一个逻辑组,而不像对象是一个具体的实体。

oracle根据shared_pool_size所指定的sharedpool尺寸自动计算hashbuckets的个数,sharedpool越大,则可以挂载的对象句柄(objecthandle)就越多。

当某个进程需要处理某个对象时,比如处理一条新进入的SQL语句时,它会对该SQL语句应用hash函数算法,以决定其所在的hashbucket的编号,然后进入该hashbucket进行扫描并比较。

有可能会发生该对象的句柄存在,但是句柄所指向的对象已经被交换出内存的情况出现。

这时对应的对象必须被再次装载(reload)。

也可能该对象的句柄都不存在,这时进程必须重新构建一个对象句柄挂到hashbucket上,然后再重新装载对象。

SQL语句相关的对象有很多(最直观的就是SQL语句的文本),这些对象都存放在librarycache里,它们都通过句柄来访问。

可以把librarycache理解为一本书,而SQL语句的对象就是书中的页,而句柄就是目录,通过目录可以快速定位到指定内容的页。

对象句柄(objectshandle)存放的信息

对象句柄存放了对象的名称(name)、对象所属的命名空间(namespace)、有关对象的一些标记(比如对象是否为只读、为本地对象还是远程对象、是否被pin在内存中等等)以及有关对象的一些统计信息等。

而且,对象句柄中还存放了当前正在lock住和pin住该对象的用户列表、以及当前正在等待lock和pin该对象的用户列表。

对象句柄中存放的最重要的内容就是指向Heap0对象的指针了。

Heap0用来存放与对象有直接关系的一些信息,比如对象类型、对象相关的表(比如依赖表、子表等)、指向对象的其他数据块的指针(这些数据块指向了实际存放SQL文本、PL/SQL代码、错误信息等的大内存块,这些大内存块依次叫做Heap1、2、3、4等)等信息。

librarycacheobjecthandle的结构如下:

∙handleaddrMemoryaddressoftheobjecthandle

∙nameNameofthelibrarycacheobject

∙hashValuethatthisobjecthashedto

∙timestampTimestampoftheobject’slastmodification

∙namespaceCRSR:

cursor,TABL/PRCD/TYPE:

table/procedure/type,BODY/TYBD:

packagebody/typebody,TRIG:

trigger,INDX:

index,CLST:

cluster,OBJE:

object,PIPE:

pipe,LOB:

lob,DIR:

directory,QUEU:

queue,OBJG:

replicationobjectgroup,PROP:

replicationpropagator,JVSC:

Javasource,JVRE:

Javaresource,ROBJ:

server-sideRepAPI,REIP:

replicationinternalpackage,CPOB:

contextpolicyobject,EVNT:

pub_subinternalinformation,SUMM:

summary,DIMN:

dimension,CTX:

applicationcontext,OUTL:

storedoutline,RULS:

rulesetobject,RMGR:

resourcemanager,IFSD:

IFSdata,PPLN:

pendingschedulerplan,PCLS:

pendingschedulerclass,SUBS:

subscriptioninformation,LOCS:

locationinformation,RMOB:

remoteobjectsinformation,RSMD:

RepAPIsnapshotmetadata,JVSD:

Javashareddata.

∙flagsRON:

readonly,REM:

remoteobject,FIX:

fixedobject,CGA:

objectinCGAmemory,TIM:

validtimestamp,PTM:

hasloggedaprevioustimestamp,PKP:

permanentlykeptobject,OBS:

hasbeenmarkedobsolete,KEP:

ismarkedtobekeptinthesharedpool,FUL/FUP:

objectshouldbefreeduponunlockorunpin,USE:

inuse(donotunpin),PN0:

heap0shouldbekeptpinnedaslongasanyuserhasalockonthehandle,SML/MED/LRG:

small/medium/largeindicatessizeofthehandle,SEC:

thisobjectissecondary.

∙lockCurrentlockmode(0:

nolock,N:

Null,S:

Share,X:

Exclusive)

∙pin:

Currentpinmode(0:

nolock,S:

Share,X:

Exclusive)

∙latch:

Associatedchildlatchid

∙lockowners

∙lockwaiters也就是LWTLockwaiterslinkedlist

∙ltm:

Temporarylockslinkedlist.Brokenlocksandlocksthatareinthemiddleofbeingprocessedareinthetemporarylist.

∙pinowners

∙pinwaits也就是pwt:

Pinwaiterslinkedlist

∙ptm:

Temporarypinslinkedlist.Pinsthatareinthemiddleofbeingprocessedareinthetemporarylist.

∙ref:

Referencelist.Thisisalistofhandlesthatarereferencedbythisobjects.Eachreferencehasaflagdeterminingwhethertheyareadependency,achild,aread-onlydependency,andsoon.

∙flag

∙heap0(Object)

namespace的定义

1.Librarycacheobjectsaregroupedinnamespacesaccordingtotheirtype.

2.Eachobjectcanonlybeofonetype.

3.Alltheobjectsofthesametypeareinthesamenamespace.

4.Anamespacemaybeusedbymorethanonetype.

5.Themostimportantnamespaceiscalledcursor(CRSR)andhousesthesharedSQLcursors.

在obj$看到的关于namespace的解释当然是不全的,因为像sharedcursor这样的librarycacheobject根本就不在obj$里。

所以实际上你可以这样理解:

namespace是针对缓存在

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 从业资格考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1