librarycache内存详解.docx
- 文档编号:29830810
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:93
- 大小:470.71KB
librarycache内存详解.docx
《librarycache内存详解.docx》由会员分享,可在线阅读,更多相关《librarycache内存详解.docx(93页珍藏版)》请在冰豆网上搜索。
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是针对缓存在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- librarycache 内存 详解