【丹臣】Shared Pool体系结构进化论

上一篇 / 下一篇  2008-04-24 09:33:59

ORACLE 7之前的版本,连接oracle的每一个会话都有一个服务器进程为它服务,这个服务器进程的作用是解析(parse),优化(opimize)客户端提交的PL/SQL或SQL代码.就算客户端向各个服务器进程提交的PL/SQL,SQL代码一样,各个服务器进程并不会share cursor,刚开始采用这种设计方式也并没有什么性能问题。但随着客户端数量的高速增长,以及在OLTP SQL语句执行频率高速增长的情况下,ORACLE 7版本的数据库的这种设计就开始出现了性能问题。当执行一样的SQL或PL/SQL代码时,如果执行计划或其它一些信息可以被所有的服务器进程所共享,而不用重新去产生,那么将可以节约大量的时间。当时oracle已开始意识到此问题,并开始着手进行改进,采用了如下的方法:
1.扩展SGA variable portion
2.提供一种方法来管理和访问SGA variable portion中的shared objects
3.ORACLE内存管理的增强

ORACLE 7时,正式提出共享池(shared pool)的概念;8,8i时,共享池的各种结构有了进一步的发展,,此时的共享池Shared Pool也有了更多的内容:包含共享SQL区和数据字典存储区。在shared pool设计方面,采用了如下的体系结构:

8i Shared Pool
从上图可以看出,整个共享池只有一个池,bucket的个数也非常的少,据说只有11个.采用这种设计方式,从性能上来讲,已经比oracle早期的版本在性能上有了比较大的飞越,毕竟各个服务器进程已经可以用共享SQL语句的执行计划等信息,而产生执行计划的数据字典信息也在共享池shared pool被缓存住了。这一切看似perfect了,但很快又遇到了新的问题:
1.由于共享池只有一个子池,那么对shared pool latch的争用相当的激烈
2.由于只有一个子池,再加上桶的个数少,那么单个bucket上的列表将会非常的长,搜索花的时间也比较多,进一步加剧了shared pool latch的争用
3.共享池内存碎片管理问题

在ORACLE 9i时,共享池有了进一步的改进,
1.共享池最多可以有七个子池,每个子池最小为128M;
2.增加了bucket桶的个数;
3.改进了共享池的内存空间管理方式

结构可以用如下图表示:

9i Shared Pool

library cache采用如下的搜索结构:

Sub Shared Pool Management

我们要搜索一个SQL或者PL/SQL对象是否在shared pool中,首先要获得library cache latch,如果找到,则在library cache handle上加NULL模式的锁,其次把library cahce object pin住,找到执行计划后,开始执行;如果所要搜索的对象不在library cahce中或者进行DDL操作时,librarary cahce中已存在的相关的SQL,PL/SQL失效,那么将会发生library cache load lock等待,此时即会发生在sub shared pool中搜索连续的空闲空间来储存硬解析产生新的执行计划,如果这个时候,没有连续的空闲空间,或者查找连续空闲空间的速度过慢,那么在一个高并发的OLTP的系统中,将会爆发大量的library cahce pin等待。由于共享子池的增多,再加上bucket数量的增加,使得单条双向链表较短,查找连续的空间会比较快,大大减少了shared pool latch的争用。正是由于ORACLE 9i在共享池处理技术上的巨大突破,使得oracle数据库的性能有了大幅度的提升,为oracle称霸全球数据库市场打下了坚实的基础。直到今天,全球大型的OLTP应用大部份都是建立在ORACLE 9I数据库之上的。

oracle 9i关于共享子池个数以及大小的控制(from Doc ID: Note:396940.1):

The number of subpools is calculated using a simple algorithm.
1. a subpool must be at least 128MB in 9i releases.
2. there can be one subpool for every four CPUs on the system, up to 7 subpools.
The number of subpools can be explicitly controlled using the init.ora parameter _kghdsidx_count.
There is no parameter to explicitly control the size of each subpool.

不管是oracle 8i,还是oracle 9i经常会碰到ORA-4031错误,关于4031经典错误,手册里是如下的描述:

ORA-04031 unable to allocate string bytes of shared memory (”string”,”string”,”string”,”string”)
Cause: More shared memory is needed than was allocated in the shared pool.
Action: If the shared pool is out of memory, either use the DBMS_SHARED_ POOL package to pin large packages, reduce your use of shared memory, or increase the amount of available shared memory by increasing the value of the initialization parameters SHARED_POOL_RESERVED_SIZE and SHARED_ POOL_SIZE. If the large pool is out of memory, increase the initialization parameter LARGE_POOL_SIZE.

导致此错误的原因是某个共享子池满了,无法在此共享子池中再分配一定大小的连续内存空间,经常采用的办法是增大共享池来解决这一类的问题。

在oracle 10g,整个共享池的体系结构并没有什么变化,只是单个共享子池大小从9i的128M变成至少为256M,我们不禁要问,oracle为什么要去修改此设置,增大了共享子池的最小值?我猜想,大概是基于如下的考虑:
1.128M的共享子池,容易发生空间满的情况,导致ORA-4031错误发生
2.256M的共享子池,单个共享子池的管理负担并不会加重,性能也没什么大的影响

从oracle shared pool在各个版本的数据库体系结构的不断变化,其设计思想的不断改进,我们是否能从中得到一些启发呢?偶就在这里先抛砖呢?在存放大数据量的表上采用分区表的组织形式,在分区表上创建并且使用local index来检索数据,与shared pool的结构上似乎有许多相似之处,至于其它的地方,期待您的见解

--EOF--


TAG:

引用 删除 junerjie   /   2008-05-04 17:22:00
您好,我是科博电脑技术服务公司的。我们公司供应电脑设备及电脑耗材,还包括电脑组装、升级、维修、局域网组建、监控安装等一些服务。我们有专业的技术人才为您上门服务,从中收取50元的服务费。如果有需要帮忙的地方,请与我联系!
                                            联系电话:010-82614906/5798
                                             E-mail :tangxiujun89@gmail.com
                                             Q    Q :549577912
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2008-05-17  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 5287
  • 日志数: 80
  • 建立时间: 2008-03-27
  • 更新时间: 2008-05-14

RSS订阅

Open Toolbar