技术开发 频道

buffer cache深度分析3:buffer cache的优化

【IT168技术文档】

接上一篇;
4. buffer cache的优化

4.1 buffer cache的设置优化

   buffer cache的设置随着oracle版本的升级而不断变化。8i下使用db_block_buffers来设置,该参数表示buffer cache中所能够包含的内存数据块的个数;9i以后使用db_cache_size来设置,该参数表示buffer cache的总共的容量,可以用字节、K、M为单位来进行设置。而到了10g以后则更加简单,甚至可以不用去单独设置buffer cache的大小。因为10g引入了ASMM(Automatic Shared Memory Management)这样一个可以进行自我调整的组件,该组件可以自动调整shared pool size、db cache size等SGA中的组件。只需要设置sga_target参数,则其他组件就能够根据系统的负载和历史信息自动的调整各个部分的大小。要启动ASMM,只需要设置statistics_level为typical或all。

   oracle8.0以前只能设置一种buffer cache,而从8.0以后,oracle提供了三种类型的buffer cache,分别是default、keep、recyle。keep和recycle是可选的,default必须存在。8i以前使用db_block_buffer设置default、buffer_pool_keep设置keep、buffer_pool_recycle设置recyle。而8i以后使用db_cache_size设置default、db_keep_cache_size设置keep、db_recycle_cache_size设置recycle。10g不能自动设置db_keep_cache_size和db_recycle_cache_size,必须手工设置。
同时,8i以前,这三种buffer cache是独立指定的,互不制约。而8i以后,这三种buffer cache是有相互制约关系的。如果指定了keep和recycle的buffer cache,则default类型的buffer cache的大小就是db_cache_size - buffer_pool_keep - buffer_pool_recycle。

    通常将经常访问的对象放入keep类型的buffer cache里,而将不常访问的大表放入recycle类型的buffer cache里。其他没有指定buffer cache类型的对象都将进入default类型的buffer cache里。为对象指定buffer cache类型的方法如下:

SQL> create table test (n number) storage (buffer_pool keep); SQL> alter table test storage (buffer_pool recycle);

  如果没有指定buffer_pool短语,则表示该对象进入default类型的buffer cache。

  这里要说明的是,从名字上看,很容易让人误以为这三种buffer cache提供了三种不同的管理内存数据块的机制。但事实上,它们之间在管理和内部机制上没有任何的区别。它们仅仅是为DBA们提供了一个选择,就是能够将数据库对象分成“非常热的”、“比较热的”和“不热的”这三种类型。因为数据库中总会存在一些“非常热”的对象,它们频繁的被访问。而如果某个时候系统偶尔做了一次大表的全表扫描,就有可能将这些对象清除出内存。为了防止这种情况的发生,我们可以设置keep类型的buffer cache,并将这种对象都移入keep buffer cache中。同样的,数据库中也总会有一些很大的表,可能每天为了生成一张报表,而只需要访问一次就可以了。但有可能就是这么一次访问,就将大部分的内存数据块清除出了buffer cache。为了避免这种情况的发生,可以设置recycle类型的buffer cache,并将这种偶尔访问的大表移入recycle buffer cache。

  毫无疑问,如果你要设置这三种类型的buffer cache,你需要自己研究并等于你的数据库中的对象进行分类,并计算这些对象的大小,从而才能够正确的把它们放入不同的buffer cache。但是,不管怎么说,设置这三种类型的buffer cache只能算是最低层次的优化,也就是说在你没有任何办法的情况下,可以考虑设置他们。但是如果你能够优化某条buffer gets非常高SQL使其buffer gets降低50%的话,就已经比设置多个buffer cache要好很多了。

    9i以后还提供了可以设置多种数据块尺寸(2、4、8、16 或 32k)的buffer cache,以便存放不同数据块尺寸的表空间中的对象。使用初始化参数:db_Nk_cache_size来指定不同数据块尺寸的buffer cache,这里的N就是2、4、8、16 或 32。创建数据库时,使用初始化参数:db_block_size所指定缺省的数据块尺寸用于system表空间。然后可以指定最多4个不同数据块尺寸的表空间,每种数据块尺寸的表空间必须对应一种不同尺寸的buffer cache,否则不能创建不同数据块尺寸的表空间。

SQL> create tablespace tbs_test_16k 2 datafile 'C:\oracle\oradata\ora92\tbs_test_16k.dbf' size 10M 3 blocksize 16k; create tablespace tbs_test_16k * ERROR 位于第 1 行: ORA-29339: 表空间块大小 16384 与配置的块大小不匹配 SQL> show parameter db_16k_cache_size NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_16k_cache_size big integer 0

  我们可以看到,由于16k数据块所对应的buffer cache没有指定,所以创建16k数据块的表空间会失
败。于是我们先设置db_16k_cache_size,然后再试着创建16k数据块的表空间。

SQL> alter system set db_16k_cache_size=10M; 系统已更改。 SQL> create tablespace tbs_test_16k 2 datafile 'C:\oracle\oradata\ora92\tbs_test_16k.dbf' size 10M 3 blocksize 16k; 表空间已创建。

  不同尺寸数据块的buffer cache的管理和内部机制与缺省数据块的buffer cache没有任何的分别。它最大的好处是,当使用可传输的表空间从其他数据库中将不同于当前缺省数据块尺寸的表空间传输过来的时候,可以不做很多处理的直接导入到当前数据库,只需要设置对应的数据块尺寸的buffer cache即可。同时,它对于调优OLTP和OLAP混合的数据库也有一定的用处。OLTP环境下,倾向于使用较小的数据块,而OLAP环境下,由于基本都是执行全表扫描,因此倾向于使用较大的数据块。这时,可以将OLAP的表转移到使用大数据块(比如32k)的表空间里去。而将OLTP的表放在中等大小的数据块(比如8k)的表空间里。
对于应该设置buffer cache为多大,oracle从9i开始通过设置初始化参数:db_cache_advice,从而提供了可以参照的建议值。oracle会监控default类型、keep类型和recycle类型的buffer cache的使用,以及其他五种不同数据库尺寸(2、4、8、16 或 32k)的buffer cache的使用。在典型负荷的时候,启用该参数,从而收集数据帮助用户确定非常好的的db_cache_size的大小。该参数有三个值:
   1) off:不收集数据。
   2) on:开始分配内存收集数据,有可能引发CPU和内存的负担,可能引起4031错。
   3) ready:不收集数据,但是收集数据的内存已经预先分配好了。通过把该参数值从off设置为ready,然后再设置为on,就可以避免出现4031错。

    oracle会根据当前所监控到的物理读的速率,从而估算出在不同大小尺寸的buffer cache下,所产生的可能的物理读的数量。oracle会将这些收集到的信息放入视图:v$db_cache_advice中。每种类型的buffer cache都会有相应的若干条记录来表示所建议的buffer cache的大小。比如下面,我们显示对于缺省类型的、缺省数据块尺寸的buffer cache的建议大小应该是多少。

SQL> SELECT size_for_estimate, buffers_for_estimate, 2 estd_physical_read_factor,estd_physical_reads 3 FROM v$db_cache_advice 4 WHERE NAME = 'DEFAULT' 5 AND block_size = (SELECT VALUE 6 FROM v$parameter 7 WHERE NAME = 'db_block_size') 8 / SIZE_FOR_ESTIMATE BUFFERS_FOR_ESTIMATE ESTD_PHYSICAL_READ_FACTOR ESTD_PHYSICAL_READS ----------------- -------------------- ------------------------- ------------------- 4 500 1.3869 40154 8 1000 1.3848 40093 12 1500 1.1861 34339 16 2000 1.1397 32996 20 2500 1 28952 24 3000 1 28952 28 3500 1 28952 32 4000 1 28952 36 4500 0.8671 25104 40 5000 0.8671 25104 44 5500 0.8671 25104 48 6000 0.7422 21488 52 6500 0.7422 21488 56 7000 0.7422 21488 60 7500 0.554 16040 64 8000 0.554 16040 68 8500 0.554 16040 72 9000 0.554 16040 76 9500 0.554 16040 80 10000 0.554 16040

    这里的字段estd_physical_read_factor表示在相应的buffer cache尺寸(由字段size_for_estimate表示)
 下,估计从硬盘里读取数据的次数除以在内存里读取数据的次数。如果没有发生物理读则该比值为空。在
 内存足够的前提下,这个比值应该是越低越好的。从上面的输出中,我们可以看到,如果将buffer cache
设置为60M,可以获得较好的性能,物理读也将会有一个显著的下降。但是设置为大于60M的话(比如
64M或68M),则不会降低物理读,反而浪费内存空间。所以从上面的查询结果中,我们可以知道,设置
为60M是比较合适的。


0
相关文章