您的位置:首页 > 数据库 > Oracle

ORACLE SGA之shared pool

2014-11-14 16:12 281 查看
ORACLE SGA之shared pool


1.shared pool的内存块组成
shared pool中主要的内存区域:free、library cache、row cache

为了确保共享池中共享数据的访问性能,共享池的每次内存分配都必须是连续的内存空间,经过一段时间的运行,共享池中会产生一些碎片,这些碎片分布在一些连续分配的空间之间。

2.共享池堆的内部结构

oracle的内存空间分配是采用堆管理(HEAP)的模式。比如SGA HEAP、PGA HEAP、HEAP TABLE等都是堆内存管理。每个堆包含一个堆句柄和一系列的内存扩展,每个扩展又包含一系列连续的chunk。内存申请者通过在堆上申请空间的模式来获得内存。

堆创建包含两个步骤:一是初始化堆的句柄,二是给堆分配空间。

从chunk中分配空间的基本顺序如下:

1)首先搜索freelist上是否存在可以释放的chunk(在该区域查找的时候首先根据需要分配空间的大小,找到相应的bucket,然后搜索整个链表,如果找到了大小相同的chunk,那么就直接分配使用。如果找不到合适的chunk,就会选择一个稍大的chunk,分配一个和所需空间大小一致的chunk,剩下的空间根据大小挂载到相应的bucket链表上)。

2)如果没找到,就查找是否有recreateable的chunk可以释放。释放已经使用的chunk,需要用到LRU链表。LRU链表根据使用的频繁程度,通过一个双向链来串联已经被分配的chunk。如果在LRU链上找到了可以释放的chunk,就通知HEAP MANAGER去释放,如果该chunk是被锁住的,首先要解锁,然后才能释放。HEAP MANAGER在释放内存时,会自动合并碎片。

3)如果此时还没有找到可以释放的chunk,就从父堆里分配空闲的空间。

4)如果父堆无法分配空间,就会报错。

3.free空间

是一个一个的内存块,使用链(chain)将空闲内存块链起来,(每个链上所挂载的内存块大小是不一样的)。如:硬解析一个sql语句,需要根据解析的sql语句和sql语句的执行计划,它所需要占用的实际内存空间,从相应的链上找空间存放。硬解析需要内存空间,根据实际大小的free内存空间中的链中找到相应大小内存块使用,会产生小内存块(内存碎片)。系统如果有大量硬解析的话。虽然free里面还有很多空间,但是所有的空间都是小的。并不能使用。

SQL> select * from v$sgastat where pool='shared pool' and name='free memory';

4.library cache空间

library cache里面有很多链,链下挂有很多chunk,但是chunk里面都写了内容(sql,sql执行计划)。

根据什么把不同的chunk写上内存后挂在不同链上:

把sql语句所有的字母转换成ASCII码值,就成了数字,对这些数字经过几次运算,就是链的编号,这个sql语句就挂到所对应的编号上。当再次执行sql语句的时候,就会从对应编号的链上去找对应的chunk。

SQL>select * from v$sgastat where name='library cache';

5.数据字典缓存(row cache)

数据字典缓存不是纯粹的数据字典表的缓存,数据字典缓存是经过组织的,用于数据库运行中sql解析、权限控制等用途的内部数据结构,是一种字典表的内存视图。如:在执行某个sql的时候,为了sql解析,需要访问一些字典表,从中获取一些数据,那么它会通过一些递归调用sql来完成这些事情。首先需要将数据块从系统表空间中读取到DB cache,然后从DB cache中获得sql所需要的行数据。为了减少递归sql的执行开销,这些行数据被缓存在共享池中,这个缓存就是数据字典缓存。

SQL> select * from v$sgastat where name='row cache';

6.执行一条之前为缓存的sql语句,查看链表中chunk数量的变化

SQL> select count(*) from x$ksmsp;

COUNT(*)

----------

36635

SQL> select count(*) from dba_indexes; --第一次执行发生硬解析,链上的chunk数量将有所增加

COUNT(*)

----------

2344

SQL> select count(*) from x$ksmsp;

COUNT(*)

----------

36650

SQL> alter system flush shared_pool; --将shared pool清空,之后第一次执行的所有DML语句都将是硬解析

7.shared pool中的保留池设置

如果共享池中碎片化变得十分严重,就会导致比较大的共享内存分配无法满足需求,oracle在共享池中设计了保留池.

保留池的设计目的是为了在共享池碎片化很严重的时候,还能够有一部分保留空间,用于较大的内存分配。可以通过参数shared_pool_reserved_size来设置保留池的大小(由于oracle的内存自动管理机制,一般情况下不需要手动设置)。

SQL> show parameter shared_pool_reserved_size;

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

shared_pool_reserved_size big integer 6081740

保留池的使用条件:

1)必须是在共享池的freelist中找不到足够大的chunk

2)分配的内存容量要大于shared_pool_reserved_min_alloc的设定值(从8i开始该参数变为隐含参数,即_shared_pool_reserved_min_alloc,默认值为4400B),只有大于该设定值的内存分配才被认为是大内存分配。

阅读(200) | 评论(0) | 转发(0) |

0
上一篇:剖析SQL语句的执行过程

下一篇:Linux下ORACLE11g的安装
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: