the reserved list
自从oracle7.3引入paged pl/sql代码块时,大量的共享池内存大块大小低于5000 bytes.到这种程序以至于,在一个成熟的实例中查找或搜寻共享池空闲
列表和lru lists为了得到大于这个size的chunks,基本上是futile无效果的.因此,oracle不会这样作.
相反,oracle会为巨大的大块保留部分共享池.这个保留区域的大小默认是共享池的5%,当然也可以用shared_pool_reserved_size来调节.
大于5000bytes的大块会放置在共享池的reserved part.这个门限可由_shared_pool_reserved_min_alloc来控制,但不能改变.微小或细小的大块不会放入the
reserved pool,巨大的大块不会放入或归入共享池的其它部分,除非是在实例启动期间.
共享池的reserved part上面的空闲内存不包含在一般共享池自由列表中,会有一个单独的reserved自由列表来管理这个.但是,共享池对于unpinned recreatable
chunks没有自己的lru lists.但是,当为了一般的自由列表freeing内存时,巨大的大块不会flushed,当为了reserved free list freeing memory,细小的大块不会flushed.
在v$shared_pool_reserved查看reserved pool统计信息.特别是,request_misses列显示从reserved 自由列表中请求一个巨大的大块不能立马满足的次数.这个
度量值应是0,也就是说在共享池的reserved part有足够的空闲内存来满足短暂freeable memory的需要,不用flush unpinned recreatable chunks(这些大块否则会长期进行缓存)
你可以配置你的监控软件来查看v$shared_pool_reserved的used_space列,确定共享池reserved part的大小是否合适.
marking objects for keeping
在一个大小定义适度的共享池情况下,僵死的大块dead chunks将会flush out.但是,任何flushing也可能导致一些有价值的对象同时也被flushed out.特别是间歇使用的
重建对象,但是它们再次重建成本很高的,因为它们很巨大,需要复杂的处理过程.可能你不想缓冲的一些序列被flushed out,因为这导致余下的一些缓存序列不能被使用.
当然,减轻这种风险办法之一,就是在共享池中用dbms_shared_pool.keep标记一些有价值的对象.从而把这些对象以及次级对象立马放入library cache中,标记它们为keeping.
这样操作应尽可能在实例启动后直接作完,以最小化共享池碎片形成.
有时可能错误认为或断言,一些如包的大对象没必要标记为keeping,因为它们会放置在共享池的reserved part,因为不可能会被flushed out.但是大多数
大对象实际上是以多个不同的small chunks加载入共享池的,所以从它们的大小来讲它们没有得到专门特别的保护.
根据使用的高频率来防止一些对象从共享池中age out也不明智之举.如果共享池定义合理well sized,在业务高峰时the lru lists会相当短,unpinned objects将会非常快速
age out,除非你标记它们为keeping.
keeping也应用于保护重复执行的cursors,或者再次执行,再不管它们的大小.
为了完整或从全局考虑,我也提及x$ksmlru可以帮你确认其它kept的library cache objects.x$ksmlru记录需要flushes的最多10个共享池大块分配的统计信息.但是,并不是所有的
chunk allocation可以抓获.事实上,只有最大的分配会被抓获.另一方面,无论何时你查询它时,最不寻常或不常见的信息会完全清除掉,所以你不能偶尔或随意查询(也就是你要有计划地查询x$ksmlru)
flushing the shared pool
合并共享池中的连续空闲的大块,唯一方法就是,通过alter system flush shared_pool来flush 共享池.问题在于到底作还是不作,dba对此有不同的意见分歧.
实际上,flushing共享池可以减轻shared pool latch竞争,极大减少ora-04031,不会马上产生大家通常认为对于性能的影响(或者讲没有哪种强的影响),特别是一些
重要或关键对象标记为keeping.另一方面,如果所有的关键对象标记为keeping,而且你的共享池没有过度定义大小,你很少或基本不用flush 共享池,除非你的实例very demanding,
长期uptime需要.
我个人更倾向flush 共享在夜间(backup后),如果平时或其它时间共享池的空闲空间变得很不足或者碎片过多.但是,你可能也要确保flushing 共享池不会leave
缓存序列的unwanted不必要或空闲的gaps.这可以通过标记序列为keeping或者临时unloading 序列用alter sequence nocache.
heaps and subheaps
你可能发现共享池的x$表是以ksm或者kgh开头.它们分别是oracle memory manager和heap manager modules的名字.
memory manager负责与os交互以获得oracle所用的内存,以及内存的静态分配.动态内存管理是由heap manager来实现.这也就是为何共享叫作sga heap.
一个heap是由一个heap描述符和一个或多个内存extents组成.一个heap也可能包含许多subheaps.这种情况下,heap描述符和subheap的extents在
parent heap是以chunks方式显现.heap描述符大小是与heap类型有关,它包含heap的自由列表和lru lists的列表头list headers.一个extent就是一个指向前面
和下一个extents的小型指针头,它的内存其它部分用于动态分配的heap(and the rest of its memory is available to the heap for dynamic allocation).
除了reserved list特征,共享池中的subheaps的结构与共享池本身一模一样.内存是以chunks方式进行分配.空闲大块根据它们的大小是以自由列表方
式进行组织.另外unpinned 重建大块是以两种lru lists(周期重复和瞬间的大块)来分别组织的.subheaps甚至具有一个包含备用空闲内存的一个主要固定内存大块.
subheaps也可能包含subheaps,嵌套层次可达4层之多.
理解掌握subheaps非常重要,因为缓存在共享池中的大多对象实际上是驻存于subheaps上面,而不是top-level heap最顶端的heap.在一个subheap中查找一个新的
大块空间更像是在共享池中查找一个新的大块空间,除了subheaps的增长是以分配一个新的extents来进行的,但是共享池的extents个数是固定的.给subheaps分配新的extents
是由一个最小的extent size来控制的,因此可能在一个subheap中查找一个small chunk会失败,因为没有一个parent heaps能分配一个必需要的最小的extent sizes的一个大块
出来.
the large pool
如果配置了large_pool_size,large pool配置为sga可变区域中一个独立的heap存在.large pool不是shared pool一部分,它是受large pool latch保护.large pool
仅仅包含空闲和freeable大块.它不包含任何重建的大块,因此不会使用heap manager的lru机制.
为了防止large pool出现碎片,所有的large pool chunks四舍五入为_large_pool_min_alloc,默认是16k.此参数不应调节.它不会影响某些大块是否在大池中分配.相反,
如果配置了大池,会根据用途在大池中分配大块,如有必要会四舍五入为必需的大小.
如果你使用如下的一些oracle特征,请使用大池:
mts(多线程服务器)或oracle*xa
rman
并行查询选项pqo
process memory
除了sga之外,每个oracle进程也使用三个同样或类似的全局区域:
the process global area(pga)
the user global area(uga)
the call global area(cga)
许多dba不清楚pga与uga之间的区别.这个区别简单就似一个进程与一个会话一般.虽然进程与会话之间一般是
一对一的关系,它也可能更为复杂.最明显的例子就是mts配置,它就是多个会话对应进程的关系.这种配置,往往是
每个进程有一个pga,每个会话一个uga.pga包含任何时侯进程可能服务且与某个会话无关的一些信息,然而uga却包含
某个特定会话的信息.
the pga
驻存于进程私有或专有内存上,而非共享内存中.从某种意义上讲pga就是一个全局区域,它包含oracle服务器代码可以访问到的全局变量和数据结构.
但是,它不能在多个进程间共享.每个oracle服务器进程有一个自己的pga,它包含与进程相关的信息.由于其它进程不能访问它们,故pga中的结构不需要用latches.
pga包含进程正在使用一些os资源信息,以及进程的状态信息.
pga包含两个component组成区域areas,固定pga与可变pga,或者pga heap.固定pga serves a similar purpose to the fixed sga(我译为:固定sga起着和
固定sga类似或同样的用途).它在大小上固定,包含数以百计的原子变量,细小的数据结构,指定可变sga的指针.
可变pga是一个heap.它的大块对于x$ksmpp的进程process均是可见的visible,它的结构与x$ksmsp一样.pga heap包含
一些固定表的固定内存,这个固定内存与一些初始化参数有关.这些参数包括:db_files,log_files(oracle8.1之前),以及control_files.除此之外,pga heap基本
上全部专用于dedicated to它的subheaps,主要是uga(如何在应用的话)和cga.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9240380/viewspace-662429/
,如需转载,请注明出处,否则将追究法律责任。