默认情况下,Oracle只有一个缓冲池 - Buffer Cache,其可以满足基本数据缓存需求。但某些数据的访问模式可能与普通数据不同,对于访问非常频繁的数据和很少访问的数据(两种极端),Oracle可以支持配置两个独立的缓冲池来存放该类数据,特殊的缓冲池针对两种访问模式做了优化,以提升系统性能。
目录
- 一、Oracle缓冲池简介
- 二、缓冲池设置
- 2.1 使用v$db_cache_advice预估缓冲池大小
- 2.2 设置Keep Pool
- 2.3 设置Recycle Pool
- 2.4 为对象指定缓冲池
一、Oracle缓冲池简介
Oracle在访问数据时需要预先将数据缓存到buffer cache中,我们期望每次需要读取数据时,数据已经在Buffer Cache中,这样可以完全避免物理I/O。但buffer cache的大小是有限的,不可能将所有数据都放到内存中。
每当访问新的数据时,Oracle会将其加载进buffer cache,如果这个对象非常大,那么意味着同样多的数据要被挤出(age out)去。但是这个对象又不需要频繁访问,那么将大量热数据挤出Buffer Cache会导致后续更多的物理I/O,造成性能下降。
为了解决这类问题,Oracle还可以配置2个额外缓冲池作为buffer cache的补充:
• Buffer Cache,缓存近期访问的数据,Oracle的默认缓冲池
• Keep Pool,缓存热点数据,独立缓冲池,需额外配置
• Recycle Pool,缓存不经常访问的数据,独立缓冲池,需额外配置
根据数据的访问频率我们即可将对象分配到不同的缓冲池中,避免大表扫描带来的影响。对于访问频繁的对象(热点),可以指定放在Keep Pool中,降低被刷出内存的概率。而不经常访问的对象,特别是大对象,可以单独缓存在Recycle Pool中,避免将大量数据挤出Buffer Pool。
二、缓冲池设置
缓冲池的大小设置没有固定公式,每个数据库的工作负载都不同,甚至同一数据库在不同时间段的负载都不同。你可以使用Oracle建议的缓冲池设置或自己通过计算预估缓冲池大小。
2.1 使用v$db_cache_advice预估缓冲池大小
如果不知道如何设置各个缓冲池的大小,可以利用v$db_cache_advice视图来辅助分析。Oracle会自动分析系统负载,然后给出一个预估的缓冲池大小和物理I/O的对应关系,你从结果中选出一个"性价比最高"的缓冲池设置。
首先,打开db_cache_advice参数,这是一个动态参数,无需重启数据库:
alter system set db_cache_advice=on;
第二步,等待系统在正常的工作负载下运行一段时间,然后查询v$db_cache_size视图:
select name 缓冲池,
size_for_estimate "缓冲池大小(MB)",
estd_physical_read_factor "预估物理读因子",
estd_physical_reads "预估物理读次数"
from v$db_cache_advice
where name ='DEFAULT' and advice_status='ON';
- "缓冲池"列default,代表的是默认缓冲池buffer cache
- 预估物理读因子为1的行代表是当前的buffer_cache设置,当前的buffer cache大小是800M
- 预估物理读因子为相对当前的设置的物理读的比例,示例中如果将buffer cache增加到1360M,那么物理读可以降低到现在的51%。但继续提升缓冲池大小物理I/O降低的效果则不再明显,因此当前工作负载最具性价比的buffer cache大小是1360M。
最后,根据建议值修改buffer cache大小,然后继续观察调整(由于虚拟机内存不够,这里调小了):
alter system set db_cache_size=720m scope=both;
上面的示例是Buffer Cache大小的调整,对于Keep Pool和Recycle Pool,你可以预估一个初始值,然后用同样的方式在运行中逐步调整。
2.2 设置Keep Pool
对于keep Pool除了使用v$db_cache_advice,还可以直接将要缓存的对象大小加起来,然后设置相应的值:
alter system set db_keep_cache_size=32m scope=both;
2.3 设置Recycle Pool
Recycle Pool是用来缓存不经常访问的数据,特别是比较大的数据段,尽量保证在一个事务中,数据段不会被频繁的刷出Recycle Pool:
alter system set db_recycle_cache_size=32m scope=both;
2.4 为对象指定缓冲池
配置好额外的缓冲池后即可以为数据对象分配缓冲池了,根据对象的访问模式,通过alter table/inde/cluster的storage子句指定对应的缓冲池(创建对象时也可以指定),该对象后续加载进内存时则会被放入相应的缓冲池:
alter table t1 storage(buffer_pool keep); -- 将表t1放入Keep Pool
alter table t1 storage(buffer_pool recycle); -- 将表t1放入 Recycle pool
alter table t1 storage(buffer_pool default); -- 将表t1放入 Buffer Cache