KEEP 池和RECYCLE 池的使用

KEEP 池和RECYCLE 池的使用
1 Oracle 的数据缓冲池
在Oracle 进行数据处理的过程中,代价最昂贵的就是物理I/O 操作了。同样的数据从内存中得到要比从磁
盘上读取快的多。因此,优化Oracle 的一个重要的目标就是尽可能的降低物理I/O 操作。
Oracle 的Buffer Cache 用于缓存从磁盘中读取的数据,当Oracle 需要查找某些信息的时候,首先会在Buffer
Cache 中寻找,如果找到了,则直接将结果返回。如果找不到,则需要对磁盘进行扫描,Oracle 将在从磁盘扫
描得到的结果返回的同时,会把这些数据在Buffer Cache 中也保留一份,如果下次需要访问相同的数据块的时
候,则不需要再次扫描磁盘,而是直接从Buffer Cache 中读取即可。
当Buffer Cache 存储空间已满,但是又有新的数据需要存放在Buffer Cache 中,这时Oracle 会将这部分新
的数据替换掉Buffer Cache 中的一部分数据。Oracle 通过LRU(Least Recent Used List)算法(最近最少使用算
法)来确定哪些数据要被清除出Buffer Cache。
Buffer Cache 中的内存由两个链表组成,Write List(写链表)和LRU 链表。写链表包含那些还没有被写到
磁盘上的脏的缓冲。LRU 链表包括空闲缓冲区、目前正在使用的Pinned Buffer 和还没有移到写链表中的脏缓冲
区(Dirty Buffer)。如果Oracle 访问了缓冲区中的数据,则会把这部分缓冲移到LRU 表的MRU 端(Most Recent
Used)。当Oracle 需要寻找空闲缓冲时,它会从LRU 链表的LRU 端开始寻找。在寻找过程中,如果发现了脏
的缓冲,就把它移到写链表中。当Oracle 找到一个空闲缓冲时,就会停止搜索,如果搜索缓冲数量超过了阈值
的限制还一直找不到空闲缓冲,则会停止搜索,启动DBWn 后端进程将一些脏的缓冲写到磁盘上。
如果用户执行的是全表扫描的操作,这些操作产生的数据缓冲不会放到LRU 端的MRU 端,而是放到LRU
端。因为Oracle 认为全表扫描得到的数据只是暂时的需要,这些数据以后被重用的机会很少,应该快速的清除
出缓冲区,把空间留给其他的更常用的数据。可以在表的级别上改变这种处理方式。在建表的时候指定Cache
语句会使得这张全表扫描得到的数据也放在LRU 链表的MRU 端。
由于Oracle 10g 版本启用了SGA 自动管理,所以没办法直接调整数据缓冲区的大小,所以只能在合理的范
围内调整SGA 的大小从而尽可能的间接的提升数据缓冲区的使用空间。
2 KEEP 池和RECYCLE 池
如果内存足够大,可以容纳所有的数据,则访问任何数据都可以从内存中直接获得,那么效率肯定是最高
的。但是在实际应用当中,经常是数据库的大小达到了几百个GB 甚至是几个TB,而Oralce 的可用内存只有几
个GB 大小。缓存中缓存的数据只能占到整个数据库数据的很小一部分,因此,这就要求必须合理的分配内存
的使用。
如果可使用的内存空间比较小,导致数据库缓冲区的命中率比较低,则可以通过配置KEEP 池和RECYCLE
池,把性质不同的表分离到不同的数据缓冲区,以提高命中率,降低此操作对正常访问的影响。
默认情况下,所有的表都是用default 池,它的大小就是缓冲区Buffer Cache 的大小,由初始化参数
db_cache_size 来决定。如果在建表或者修改表的时候指定STORAGE(BUFFER_POOL KEEP)或者STORAGE
(BUFFER_POOL RECYCLE)语句,就设置这张表使用KEEP 或者RECYCLE 缓冲区。这两个缓冲区的大小
分别由初始化参数db_keep_cache_size 和db_recycle_cache_size 来决定。
SQL> show parameter cache_size
NAME TYPE VALUE
---------------------- ----------- ------------------------------
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
2
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0 --属于SGA 自动管理组件,值为0.
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
SQL> alter system set db_keep_cache_size=12M scope=both;
系统已更改。
SQL> alter system set db_recycle_cache_size=8M scope=both;
系统已更改。
SQL> show parameter cache_size
NAME TYPE VALUE
---------------------- ----------- ------------------------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0 --属于SGA 自动管理组件,值为0.
db_keep_cache_size big integer 12M
db_recycle_cache_size big integer 8M
2.1 KEEP 池
KEEP 池用来缓存那些经常会被访问的表。KEEP 池使用缓冲区独立于DEFAULT 池,因此把最经常使用的
表缓存到单独的缓冲区中,使得数据库的其他操作,如执行大量批操作也不会影响到这些在KEEP 缓冲区中的
表,保证访问这些最常使用的表的数据时,都可以从内存中直接获得。
SQL> col name format a30
SQL> col value format a30
SQL> conn scott/scott
已连接。
SQL> create table test_default(col number(3)) storage(buffer_pool default);
表已创建。
SQL> create table test_keep(col number(3)) storage(buffer_pool keep);
表已创建。
SQL> create table test_recycle(col number(3)) storage(buffer_pool recycle);
表已创建。
SQL> insert into test_default values(1);
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
3
已创建 1 行。
SQL> insert into test_keep values(1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> set autotrace on stat
SQL> select * from test_default;
COL
----------
1
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select * from test_keep;
COL
----------
1
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> show sga
Total System Global Area 528482304 bytes
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
4
Fixed Size 1249944 bytes
Variable Size 150998376 bytes
Database Buffers 369098752 bytes
Redo Buffers 7135232 bytes
SQL> select 369098752/1024/1024 from dual;
369098752/1024/1024
-------------------
352
在上面的例子中,建立了两张表。Test_default 指定默认的default 池,test_keep 指定了keep 池。分别插入
了一条数据,然后打开自动跟踪,对这两张表进行查询,由于刚刚执行了INSERT 语句,这两条数据都存放在
各自的缓冲区中,因此查询的物理读(physical reads)为0,接着查看buffer cache 的值,发现大小为352M,SGA
为504M。
下面构造一个较大的批操作,插入的数据大于504M,将default 区域覆盖掉。
SQL> create table test_eat_memory
2 (col1 varchar2(4000),
3 col2 varchar2(4000),
4 col3 varchar2(4000),
5 col4 varchar2(4000),
6 col5 varchar2(4000),
7 col6 varchar2(4000),
8 col7 varchar2(4000),
9 col8 varchar2(4000),
10 col9 varchar2(4000),
11 col10 varchar2(4000))
12 storage(buffer_pool default);
表已创建。
SQL> insert into test_eat_memory
2 select
rpad('1',4000,'1'),rpad('2',4000,'2'),rpad('3',4000,'3'),rpad('4',4000,'4'),rpad
('5',4000,'5'),rpad('6',4000,'6'),rpad('7',4000,'7'),rpad('8',4000,'8'),rpad('9'
,4000,'9'),rpad('0',4000,'0
) from all_objects where rownum<=15000;
已创建15000 行。
统计信息
---------------------------------------------------------
10410 recursive calls
564195 db block gets
108584 consistent gets
620 physical reads
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
5
637527688 redo size --大约插入了638M 数据
678 bytes sent via SQL*Net to client
803 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
91 sorts (memory)
0 sorts (disk)
15000 rows processed
SQL> commit;
提交完成。
执行完批操作后,对两张表再次查询。
SQL> select * from test_default;
COL
----------
1
统计信息
----------------------------------------------------------
70 recursive calls
0 db block gets
13 consistent gets --这个结果值在10g-SGA 自动管理下,非常难实现。
12 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select * from test_keep;
COL
----------
1
统计信息
----------------------------------------------------------
70 recursive calls
0 db block gets
13 consistent gets
0 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
6
0 sorts (disk)
rows processed
SQL> show sga
Total System Global Area 528482304 bytes
Fixed Size 1249944 bytes
Variable Size 150998376 bytes
Database Buffers 369098752 bytes --default 区域没有变化
Redo Buffers 7135232 bytes
结果很明显。由于keep 和default 池彼此独立,对于test_keep 的查询的物理读仍然为0,而对
test_default 的查询则包含了12 个物理读。
上面的例子可以看出,使用keep 池可以保证那些指定keep 池的表不受其他表的影响。可以查询v$bh
视图来查找到经常被使用的表,根据表的使用频繁度来确定是否指定keep 池。
select o.object_name, count(*)
from dba_objects o, v$bh bh
where o.object_id = bh.OBJD
and o.owner != 'SYS'
group by o.object_name
having count(*) > 100
order by count(*) desc
确定好使用keep 池的表后,可以根据这些表的实际大小之和来计算缓冲区的大小。由于这个大小可以比
较准确的计算出来,因此可以对这些表使用cache,以保证即使采用全表扫描得到的数据也可以被缓冲。
通常情况下,并不追求keep 池的命中率达到100%,如果命中率为100%,则说明给keep 池的内存空间
过大,有部分内存被浪费。即使keep 池中缓存的都是些最经常访问的表,这些访问操作也不大可能访问到表
中所有的数据。因此,可以适当的减少keep 池的内存分配,使keep 池的命中率维持在接近100%的数值。将
这部分内存分配给其他的缓冲区,可以得到更高的效率。
可以采用下面的SQL 语句来计算KEEP 池的命中率。
select name,
physical_reads,
db_block_gets,
consistent_gets,
1 - (physical_reads / (db_block_gets + consistent_gets)) "hit ratio"
from v$buffer_pool_statistics
where name = 'KEEP';
2.2 RECYCLE 池
RECYCLE 池用来缓存那些不希望保存在内存中的表。例如很少进行扫描或者访问的表。如果应用程序以一
种随机的方式访问一张比较大的表,这些被缓冲的数据在被清除出内存之前,很少会有机会再次被访问。这些
数据存放在缓冲区当中,不仅会浪费内存空间,而且可能把其他的一些有可能被访问的数据清除出去。这些数
据没必要保存在缓冲区当中,可以通过使用RECYCLE 池来避免这些数据对其他数据的影响。
调整参数db_recycle_cache_size 的大小来设置recycle 池。一般来说,不需要给recycle 池很大
的内存空间,因为recycle 池中的数据没有什么被缓存的价值。设置较小的缓冲区可以将更多的内存留给keep
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
7
和default 池。但是,如果缓冲区太小的话,数据可能在事务结束之前就从内从中被清除了,这会导致额外
的性能问题。
SQL> truncate table test_eat_memory;
表被截断。
SQL> select * from test_default;
COL
----------
1
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter table test_eat_memory storage(buffer_pool recycle);
表已更改。
SQL> insert into test_eat_memory
2 select
rpad('1',4000,'1'),rpad('2',4000,'2'),rpad('3',4000,'3'),rpad('4',4000,'4'),rpad
('5',4000,'5'),rpad('6',4000,'6'),rpad('7',4000,'7'),rpad(
) from all_objects where rownum<=15000;
已创建15000 行。
统计信息
---------------------------------------------------------
10410 recursive calls
564195 db block gets
108584 consistent gets
620 physical reads
637527688 redo size --大约插入了638M 数据
678 bytes sent via SQL*Net to client
803 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
91 sorts (memory)
0 sorts (disk)
15000 rows processed
栢图数据库实验室 KEEP 池和RECYCLE 池的使用
8
SQL> commit;
提交完成。
SQL> select * from test_default;
COL
----------
1
统计信息
----------------------------------------------------------
70 recursive calls
0 db block gets
0 consistent gets
12 physical reads
0 redo size
407 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
rows processed
在这个例子中,将进行批操作的表改为recycle 池,在批操作执行完成后,发现test_default 表的数
据仍然可以在default 池中找到。这种方法屏蔽了批操作对系统的影响。
3 小结
对于大多数的系统而言,使用default 池就够了。但是如果内存空间相对较小,或者对系统中表的使用
情况有比较清晰的认识,则可以通过配置keep 池和recycle 池来细化内存的分配,提高数据缓冲区的命中率,
降低批操作对系统的影响。
虽然keep 池、recycle 池用来缓存不同类型的数据,但是他们的机制是相同的,他们采用的都是LRU
算法。如果keep 池分配的内存不足,那么也会有部分数据被清除出内存;如果recycle 池的内存分配足够,
也可以保证其中的数据全部缓存。从本质上讲,keep 池和recycle 池并没有什么区别,只是名字不同而已。
如果给keep 池或者recycle 池分配的内存大小不合适,不但不会提高性能,而且会造成性能的下降。以
keep 池为例,内存分配小了,这些经常被访问的、数据就会有部分被清除出内存,导致命中率降低。如果内
存分配过大,则导致default 池内存要相应的减少,default 池不仅包括用户部分数据,而且也包括数据字
典的缓冲。因此,default 池内存的不足,必然导致整个系统性能的下降。而且,由于真实环境中,所有的表
的大小都处于变化之中,因此,需要经常对不同缓冲区的命中率进行检查,并随时调整缓冲区的大小以满足数
据不断变化的需要

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/500314/viewspace-1068571/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/500314/viewspace-1068571/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值