Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104574298
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Oracle

2008-04-30 16:34:51

 

配置和使用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

阅读(375) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~