Oracle SHARED POOL的内部结构
Oracle SHARED POOL是SGA重要的组件之一。SHARED POOL作为一块共享内存区域,Oracle一直以“提高CURSOR的可用性”为目标在代码方面进行优化,并不断推陈出新。比如Oracle 11g新增了结果集缓存(Result Cache)这个新特性。这个新特性的含义就是将查询的结果集Cache起来,如果接下来有相同的查询请求就可以直接从结果集缓存获取结果,从而避免了重复查询。Oracle对SHARED POOL的优化力度一直很大,在不同的数据库版本中组成SHARED POOL的内存区域数量不一样。在Oracle 9.2.0.8中,其内存区域的数量只有38个,如下所示:
SQL> select count(*) from v$sgastat where pool='shared pool';COUNT(*)
----------38
在Oracle 10.2.0.5中,其内存区域的数量已经激增至619个,如下所示:
SQL> select count(*) from v$sgastat where pool='shared pool';COUNT(*)
----------619
在Oracle 11.2.0.3中,其内存区域的数量又增加至880个,如下所示:
SQL> select count(*) from v$sgastat where pool='shared pool';COUNT(*)
----------880
SHARED POOL从结构上可以大体分为如下几类:
PERMANENT AREA。用于保存PROCESSES、SESSIONES、SEGMENTED ARRAY、ENQUEUES、GES RESOURCE、TRANSACTIONS、TRANSACTIONS BRANCHES等内容。永久区域保存的内容其寿命和实例相同。注意,有些PERMANENT AREA资源不允许动态扩展,在实例启动期间就需要预先分配好槽位(占用一定的SHARED POOL内存),如PROCESS、SESSION、TRANSACTION等。有些PERMANENT AREA资源却是允许动态扩展的,如GES RESOURCE资源。但这些资源扩展后基本上不会释放。在早期版本中,资源扩展后容易占用较大内存而引起内存碎片(ORA-4031错误),而且这些资源无法通过ALTER SYSTEM FLUSH SHARED_POOL刷共享池内存清除。可以通过DUMP SHARED POOL在PERMANENT CHUNKS一栏来观察PERMANENT AREA的大小,也可以通过以下查询获取PERMANENT AREA区域的大小,如下所示:
select ksmchptr,ksmchsiz
from x$ksmsp
where ksmchcls=‘perm’;
LIBRARY CACHE。保存和管理SQL语句相关的全部对象(如SQL、表、视图、存储过程等)。在高并发的生产环境中该内存区域极易因争用而出现各种等待事件,所以它一直以来都是性能优化时关注的焦点。
ROW CACHE。也称为DICTIONARY CACHE。主要用于保存数据字典信息。实践表明,ROW CACHE很少出现问题,但如果出现问题,则往往是严重的性能问题。在涉及数据字典的更改(如DDL语句)或者大量并发进程同时获取ROW CACHE LATCH时,容易引起ROW CACHE的争用。
RESERVED AREA:保留区域。为了避免SHARED POOL内存不足而产生ORA-4031错误,Oracle将部分内存用作保留区域。具体数值由参数SHARED_POOL_RESERVED_SIZE设置,默认为参数SHARED_POOL_SIZE值的5%。
SHARED POOL利用堆(HEAP)的内存管理方式管理,在物理上由多个内存区(EXTENT)组成,内存区(EXTENT)又由多个不同大小的CHUNK组成。而CHUNK又有可重用和空闲之分,并且它们分别由LRU LIST、FREE LIST、RESERVED LIST串联起来