配置和使用Buffer Cache 大很多类型的操作中,oracle使用buffer cache来存储从磁盘读取的数据块。Oracle通过使用buffer
cache来实现一些并行操作,诸如排序和并行读取。下面我们将讨论: ■ 有效的使用的buffer cache ■ 确定 Buffer Cache的大小 ■ 关于Buffer Cache 顾问统计 ■ 考虑其它的buffer 池 有效的使用的buffer cache 为了更有效的使用buffer cache,应用程序的SQL应该尽量避免不必要的资源消耗。为了确保达到这个
目的,请检查系统中运行最频繁且影响很多buffer的SQL是否调整为最优。 确定 Buffer Cache的大小 当你配置一个新的实例的时候,是不可能知道确切的buffer cache的大小的。典型的,是DBA作一个最
初估计,然后在运行期再判断当前的buffer cache大小是否合适。 buffer cache的顾问统计 一些统计信息可以诊断buffer cache的活动,包括: ■ V$DB_CACHE_ADVICE ■ Buffer cache 的命中率 -使用V$DB_CACHE_ADVICE 设置初始化参数DB_CACHE_ADVICE为ON,即可提供这个视图。这个视图模拟了各种buffer cache大小
下,命中率的丢失情况。 每种模拟的大小是一行,包含在这个大小下发生的物理I/O。DB_CACHE_ADVICE是可以动态设置,你
可以在某些特定工作负载开启用于收集信息又或者关闭。 下面的SQL显示了在不同buffer cache大小,返回的不同物理I/O情况 COLUMN size_for_estimate FORMAT 999,999,999,999 heading 'Cache Size (MB)' COLUMN buffers_for_estimate FORMAT 999,999,999 heading 'Buffers' COLUMN estd_physical_read_factor FORMAT 999.90 heading 'Estd Phys|Read Factor' COLUMN estd_physical_reads FORMAT 999,999,999 heading 'Estd Phys| Reads' SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor, estd_physical_reads FROM V$DB_CACHE_ADVICE WHERE name = 'DEFAULT' AND block_size = (SELECT value FROM V$PARAMETER WHERE name = 'db_block_size') AND advice_status = 'ON'; 下面的输出,说明了如果cache大小为212MB,对比当前的大小304MB,那么物理读会增加74%,这就
意味着把大小缩小为212M是不明智的。 然而把大小增加为334M,那么会渐少7%的物理读,而这个大小是在SGA_MAX_SIZE的范围内的。很明
显,这是一个明智的选择。 Estd Phys Estd Phys Cache Size (MB) Buffers Read Factor Reads ---------------- ------------ ----------- ------------ 182 22,812 2.50 25,668,196 212 26,614 1.74 17,850,847 243 30,416 1.33 13,720,149 273 34,218 1.13 11,583,180 304 38,020 1.00 10,282,475 Current Size 334 41,822 .93 9,515,878 364 45,624 .87 8,909,026 -计算buffer cache的命中率 运行下面的SQL SELECT NAME, VALUE FROM V$SYSSTAT WHERE NAME IN ('db block gets from cache', 'consistent gets from cache', 'physical reads cache'); 通过公式 1 - (('physical reads cache') / ('consistent gets from cache' + 'db block gets from cache') 可以得出buffer cache的命中率,如果偏低,你就考虑调整了。 consistent gets from cache:buffer cache的块的一致读的数量 db block gets from cache:buffer cache的当前块读取数量 physical reads cache:访问磁盘的物理读取数量 -关于Buffer Cache 顾问统计 有很多影响buffer cache大小估计的因素。比如前面讲过的V$DB_CACHE_ADVICE和命中率计算。但是
低的命中率并不是一定可以通过增加cache的大小来改善的,一个高命中率也不能完全说明当前的大小
是符合工作负载的。 为了更好理解命中率,你要考虑下文: ■ 反复扫描大表和索引能够提高命中率。检查访问buffer量大的频繁SQL,确保它已经最优化。如果可
能,避免这种重复的扫描,把它优化为一次读取。 ■避免扫描重复的数据,能否把他们缓存到客户端或者中间层。 ■一个漫长的大表扫描,数据块是不会缓存到LRU链表的头部的,反而在放在尾部,所以它比小表扫描
的cache要老化快得多。所以要适当的使用大表扫描。 ■在一些繁忙的OLTP系统中,很多记录只被访问一次或者不访问,那么就没有必要把它们长期的放在
内存中。 ■增加buffer cache大小常见的错误是,增加了却没有效果。由于你正在坐全表扫描或者其它无法利用
buffer cache的操作。 -增加buffer cache的内存分配 增加buffer cache的一个原则是,如果你的命中率低下,且应用的SQL已经优化后。 打开V$DB_CACHE_ADVICE的统计,通过一段时间的典型负载的运行,从而判断出合适的大小。 DB_CACHE_SIZE的大小是数据库标准块的大小。如果你要创建一个非标准块大小的表空间(诸如可传
输表空间),那你要配置适合的DB_CACHE_SIZE了,参数DB_nK_CACHE_SIZE,对应块大小为2, 4, 8, 16
或者32k的块大小。 -减小buffer cache的内存分配 查询V$DB_CACHE_ADVICE,查看当前的大小的物理读减少比例是否处在一个非常平滑的曲线上,那么
就可以考虑减小它。除非你内存紧张,否则大一点buffer cache没有什么坏处。 -考虑其它buffer pool KEEP pool 和 the RECYCLE pool. KEEP pool 可以消除不必要的IO,RECYCLE pool避免cache的对象过多。 -对大段随机的访问 在一个大的段里面进行大量的索引范围扫描会导致LRU老化过快的问题。在这里,”大“是和cahce的大
小对比得出的。对一个段超过其大小的10%的物理读,可以认为非常大。随机读取一个大段能够导致
其它段在cache里面数据老化过快。大段占用cache大部分的空间,但是却几乎没有任何益处。 频繁的访问并不影响大段的效率,因为它们的buffer一直都是活跃的,被存放在cache里面。但是上述
问题,会影响这些正常访问。解决这个问题,有三点: 1.如果是访问索引,那么检查是否是必要的。如果不是,调整SQL,去掉不必要的索引访问。 2.如果SQL已经优化了,那么吧大段移动到RECYCLE cache,那么它就不会影响到其它段。RECYCLE
cache应该比默认的buffer pool 小,它对buffers重新利用是非常迅速的。 3.另外,还可以把很小的热点段放在KEEP cache里。KEEP cache应该尽可能的小。应该把一些访问要求
响应时间短的查询段放在KEEP cache中。这样它肯定不会老化。 ORACLE RAC 实例 RAC也允许这些pool,每个节点的pool必须有相同的设置,大小可以不同。 使用其它pool 为对象定义它自己的buffer pool,使用BUFFER_POOL关键字在STORAGE字句中。这个字句可以在
CREATE和ALTER TABLE,CLUSTER和INDEX的命令中使用。指定了buffer pool后,所有的对块的读取,都
会被缓存在指定的pool中。 如果buffer pool 是为了一个分区表或索引定义的,那么每个分区都会继承表或者索引的定义,除非你
重写一个指定的buffer pool。改变buffer pool使用ALTER 命令。 See Also: Oracle Database SQL Reference for information on specifying BUFFER_POOL in the STORAGE clause 检查哪个块有大量的buffer在pool中 V$BH显示了当前数据对象ID被缓存到SGA的块。 方法1 COLUMN OBJECT_NAME FORMAT A40 COLUMN NUMBER_OF_BLOCKS FORMAT 999,999,999,999 SELECT o.OBJECT_NAME, COUNT(*) NUMBER_OF_BLOCKS FROM DBA_OBJECTS o, V$BH bh WHERE o.DATA_OBJECT_ID = bh.OBJD AND o.OWNER != 'SYS' GROUP BY o.OBJECT_NAME ORDER BY COUNT(*); OBJECT_NAME NUMBER_OF_BLOCKS ---------------------------------------- ---------------- OA_PREF_UNIQ_KEY 1 SYS_C002651 1 .. DS_PERSON 78 OM_EXT_HEADER 701 OM_SHELL 1,765 OM_HEADER 5,826 OM_INSTANCE 12,644 方法2 找出Oracle内部对象段 SELECT DATA_OBJECT_ID, OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_NAME = UPPER('segment_name'); 注意Oracle的不同对象,可以有相同的名字。 找出这些段在cache中的数量 SELECT COUNT(*) BUFFERS FROM V$BH WHERE OBJD = data_object_id_value; 找出实例中的buffer SELECT NAME, BLOCK_SIZE, SUM(BUFFERS) FROM V$BUFFER_POOL GROUP BY NAME, BLOCK_SIZE HAVING SUM(BUFFERS) > 0; 计算单个段的命中率 % cache used by segment_name = [buffers(Step2)/total buffers(Step3)] KEEP Pool 参数DB_KEEP_CACHE_SIZE设置KEEP pool的大小。 可以通过查询DBA_TABLES.BLOCKS 和 DBA_TABLES.EMPTY_BLOCKS来估计keep pool的大小。 100%的命中率不一定是最优的,通常减小keep pool仍然可以维持高命中率,只不过是把keep pool的
块移动到其它块。 RECYCLE Pool RECYCLE Pool非常适合于极少扫描的段。通过参数DB_RECYCLE_CACHE_SIZE设置大小。
原文:http://valen.blog.ccidnet.com/blog-htm-itemid-152057-do-showone-type-blog-uid-51502.html
|