应用程序经常访问一个小型查找表,您注意到,所需的数据块正在从默认的缓冲区缓存中老化。
如何保证表的块永远不会老化?
A.配置KEEP缓冲池,用对应的storage子句修改表。
B.增加数据库缓冲区缓存大小。
C.配置RECYCLE buffer pool,用对应的storage子句修改表。
D.配置Automata共享内存管理。
E.配置自动内存管理
正确答案:A
模式对象以不同的使用模式进行引用;
因此,它们的缓存行为可能大不相同,多个缓冲池使得能够解决这些差异。
可以使用KEEP缓冲池来维护缓冲缓存中的对象,也可以使用RECYCLE缓冲池来防止对象占用缓存中不必要的空间。
当一个对象被分配到缓存时,该对象的所有块都会被放置在该缓存中。
Oracle为尚未分配给其中一个缓冲池的对象维护一个DEFAULT缓冲池。
Oracle中如何配置Keep pool & Recycle Pool?
默认情况下,Oracle只有一个缓冲池 - Buffer Cache,其可以满足基本数据缓存需求。但某些数据的访问模式可能与普通数据不同,对于访问非常频繁的数据和很少访问的数据(两种极端),Oracle可以支持配置两个独立的缓冲池来存放该类数据,特殊的缓冲池针对两种访问模式做了优化,以提升系统性能。
一、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建议的缓冲池设置或自己通过计算预估缓冲池大小。
1.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,那么物理读相应的会减少很多,对应的所用的内存也会增加,实际中可以根据内存的大小调整一个合适的值。
alter system set db_cache_size=1360m scope=both;
注意:在ASMM自动共享内存管理的系统中,该值为0,由系统自动分配值。
对于Keep Pool和Recycle Pool,你可以预估一个初始值,然后用同样的方式在运行中逐步调整。
1.2 设置Keep Pool
对于keep Pool除了使用v$db_cache_advice,还可以直接将要缓存的对象大小加起来,然后设置相应的值:
alter system set db_recycle_cache_size=32m scope=both;
1.3 设置Recycle Pool
Recycle Pool是用来缓存不经常访问的数据,特别是比较大的数据段,尽量保证在一个事务中,数据段不会被频繁的刷出Recycle Pool:
alter system set db_recycle_cache_size=32m scope=both;
1.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