[转载]Buffer cache的调整与优化

Buffer
Cache是SGA的重要组成部分,主要用于缓存数据块,其大小也直接影响系统的性能。当Buffer Cache过小的时候,将会造成更多的free buffer
waits事件。下面将具体描述Buffer Cache的作用、调整与优化。

一、SGA的所有组件

从动态视图v$sga_dynamic_components获取SGA的相关信息

SELECT component,
current_size, min_size FROM v$sga_dynamic_components;

COMPONENT                
CURRENT_SIZE   MIN_SIZE

------------------------- ------------ ----------

shared
pool                  
71303168   71303168

large
pool                    
4194304    4194304

java
pool                     
4194304    4194304

streams
pool                  
4194304    4194304

DEFAULT buffer
cache         113246208 
113246208

KEEP buffer
cache                   
0          0

RECYCLE buffer
cache                
0          0

DEFAULT 2K buffer
cache             
0          0

DEFAULT 4K buffer
cache             
0          0

DEFAULT 8K buffer
cache             
0          0

DEFAULT 16K buffer
cache            
0          0

DEFAULT 32K buffer
cache            
0          0

ASM Buffer
Cache                    
0          0

二、Buffer cache介绍


2.1.Buffer cache


Buffer cache类型包括以下:

default buffer cache

keep buffer cache

recycle buffer cache

nk buffer caches

与Buffer
cache打交道的后台进程为DBWn,与之对应的数据文件通常位于system 表空间,sysaux表空间,undo表空间,datafile 等。

Buffer
cache是SGA的一部分,其内容是由用户进程从数据文件读取出来的数据块,并且所有的用户共享这些数据块。通常,服务器进程为提高I/O性能,会一次性读多个数据块。对于Buffer
cache中的脏数据则由DBWn进程写入到数据文件。同样为提高性能,DBWn进程也会一次写多个数据块。Buffer
cache会拥有一个数据块的多个副本,当前块的最新副本仅有一份,而该数据块老的或旧的副本可能有多份,用于块的读一致性。Buffer
cache采用LRU算法来淘汰掉过时的数据块。    Buffer cache中存在检查点队列以及LRU链表。

2.2.Buffer cache的几个相关参数

Buffer cache能有由多个独立的且具有不同block size的缓冲池(buffer pool)组成。

DB_BLOCK_SIZE

参数决定了数据库主块的块大小,该块的大小通常被系统表(system,sysaux)空间和主要的Buffer cache(recycle,keep,default
buffer cache)所使用,决定主要的Buffer cache大小的几个参数:

db_cache_size

db_keep_cache_size

db_recycle_cache_size

2.3.Buffer cache中块的四种状态

(1)pinned

意味着多个会话在相同的时段写同一个数据块,其他的会话等待访问块。

(2)clean

优先要淘汰掉的数据块,即不是pinned状态,也不会被再次使用的块.该块可能和磁盘上的块处于同步状态,也可能是一个读一致性块

(3)free/unused

即Buffer cache中的块处于空闲状态或未使用状态,通常是由于实例刚刚启动。

(4)dirty

已发生变化的数据块,且没有进程再使用该块,则在aged out之前需要立即由DBWn
写入到数据文件。

服务器进程将数据块从数据文件填充到Buffer cache,当Buffer
cache中不再需要使用到数据块的副本时,而DBWn进程则将脏数据  写入到数据文件,用于将数据块由pinned 状态变为free 状态。

2.4.参数db_block_checksum

该参数设置为true,则一个指定的校验码被同时写入到数据块,用于防止磁盘,I/O系统损坏导致数据的丢失。

三、客户端服务器进程从Buffer cache获取数据的过程

1.服务器进程使用一个哈希函数来检查所需的数据块是否已经位于Buffer
cache。如果在Buffer
cache中找到所需的数据块,则该块根据使用的频率放置到LRU队列中特定的位置。此时的读数据块为逻辑读,且不在需要执行后续步骤。如果不在Buffer
cache中,则转到下一步。

2.服务器进程搜索LRU列表中是否存在可用的空闲空间存放新的数据块。在搜索LRU列表同时时,已经被修改的脏数据将被服务器进程放置到 检查点队列。

3.检查点队列长度超出预设大小的阙值或服务器进程搜索空闲块操作预设的次数(由隐藏参数_db_block_max_scan_pct所指定的值,表示已经扫描的buffer
header数量占整个LRU链表上的buffer header的总数量,在i中该限定值为40%),则服务器进程通过DBWn将脏数据从

Buffer cache写出到数据文件。

4.当可用的空闲块被找到后,服务器进程从数据文件读入块到Database Buffer
cache并放置到LRU队列中。如果所得到的块不是一致性读块 ,则服务器进程从undo segment中重构一致性块。

Buffer cache与DBWn密切相关,下面给出DBWn触发的条件

脏缓冲列表达到指定的阙值大小

搜索LRU空闲队列达到预设的阙值次数

发生检查点事件

数据库关闭时

表空间实现热备份时

表空间离线

在段被删除时

更多有关体系结构请参考:Oracle实例和Oracle数据库(Oracle体系结构)

四、对buffer cache调优与命中率等


4.1.调整buffer cache调优规则

调优的目标:尽可能在Buffer cache中找到数据,降低等待可用空闲块的时间

调试方法:

(1)wait events

(2)cache hit
ration

(3)v$db_cache_advice
view

调整手段

(1)降低SQL命令对数据块的请求,如避免使用select * from 语句

(2)增加缓冲池的大小

(3)不同访问方式使用不同的缓冲池(buffer pools)

(4)缓存常用的表到内存

(5)并行读或排序操作不使用cache,直接从磁盘读入到PGA及内存

4.2.决定Buffer cache的几个指标

下面的查询中列出了涉及到buffer cache的几个重要指标数

SELECT NAME, VALUE

FROM   v$sysstat

WHERE  NAME IN (‘session logical reads‘,

‘physical reads‘,

‘physical reads direct‘,

‘physical reads direct (lob) ‘,

‘consistent gets‘,

‘db block gets‘,

‘free buffer inspected‘,

‘free buffer requested‘,

‘dirty buffers inspected‘,

‘pinned buffers inspected‘);

NAME                                  
VALUE

------------------------------ -------------

session logical
reads          
139150060175

db block
gets                     
274690511

consistent
gets                
139129962467

physical
reads                  
21335058151

free buffer
requested           
21085155516

dirty buffers
inspected              
156801

pinned buffers
inspected             
432841

free buffer
inspected                
968639

physical reads
direct               
4995527

    Session Logical Reads

所有的逻辑读的数据块的数量。

    Free Buffer
Inspected
指标

为寻找空闲buffer之前所检查块的总数量,即跳过块的数量。如果该值接近脏数据块的数量,则表明空闲块很少,该值应尽可能小于脏块的数量。

Free Buffer Waits:

当session在LRU
list上没有寻找到空闲可用数据块或者搜寻可用的内存数据块被暂停的时候,该发生该事件,此为等待DBWn将脏块写入到数据文件的等待数。除此之外,会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内 
存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。

    Buffer Busy Waits:

用户服务器进程已找到所需的数据块,但该块正被其它进程使用或多个进程同时要修改该块,此时需要等待的时间。

当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时,此时同样发生Buffer Busy Waits事件。

SELECT event

,total_waits

FROM v$system_event

WHERE event IN (‘free buffer waits‘,‘buffer busy waits‘);

EVENT                    
TOTAL_WAITS

------------------------- -----------

buffer busy
waits           
35216021

查询event事件名称

SELECT NAME

,parameter1

,parameter2

,parameter3

FROM v$event_name

WHERE NAME=‘buffer busy waits‘;

NAME            
 PARAMETER1          
PARAMETER2          
PARAMETER3

---------------------- --------------------
--------------------

buffer busy
waits        
 file#               
block#              
id

产生Buffer busy waits的几种情形

DATA BLOCK

数据块的竞争,该情形通常是基于表段和索引段上的竞争,下面的处理办法尽可能缩小SQL语句的查询字段,查询范围,如不使用select *
查询,将like子句改为直接赋值等检查索引的合理性。如使用了sequence生成的索引,其索引键通常位于相同的块,因此可以使用反向索引避免此问题使用自动段空间管理或增加空闲列表,以避免多个进程同时插入相同的块。       
查询视图v$session_wait来获得热点块的文件ID,块ID,通过这些信息来获得对象ID,进一步对该对象进行调整UNDO
Header   基于UNDO段头部的竞争,如果未使用自动撤销段管理模式,则需要增加更多的回滚段。

UNDO BLOCK

基于UNDO段块的竞争,如果未使用自动撤销段管理模式,则需为回滚段分配更大的尺寸。

产生Free Buffer waits的几种情形

DBWn进程来不及将数据写入到数据文件,导致需要等待被释放的空间I/O系统速度过于缓慢,确保数据库文件是否分布在不同的磁盘上,或增加更高性能的磁盘 
资源等待造成I/O系统过慢,如latch等待

确保数据库文件是否分布在不同的磁盘上,或增加更高性能的磁盘

Buffer cache太小,导致DBWn来不及将脏数据写入到数据文件需要增大buffer
cache的尺寸

Buffer
cache太大,而单一的DBWn进程需要多次才能将数据写入到文件,减少buffer
cache的尺寸,或增加更多的DBWn进程。

4.3.评估Cache的命中率

计算命中率的思想

1-(物理读的次数-总的请求次数)

计算命中率

SELECT ROUND(1 -
((physical.value - direct.value - lobs.value) / logical.value),3) *100 ||‘%‘

"Buffer Cache Hit Ratio"

FROM   v$sysstat physical,

v$sysstat direct,

v$sysstat lobs,

v$sysstat logical

WHERE  physical.name = ‘physical reads‘

AND direct.name = ‘physical reads direct‘

AND lobs.name = ‘physical reads direct (lob)‘

AND logical.name = ‘session logical reads‘;

physical reads

从Oracle级别来理解,从磁盘读数据块的次数,一次可以读多块,由参数db_file_multiblock_read_count来控制。此种读方式使用了db
cache.

形象示意:db_file ==> db_cache ==> pga

   physical reads
direct

有些数据块不会先从硬盘读入内存再从内存读入PGA再传给用户,而是绕过SGA直接从硬盘读入PGA。比如并行查询以及从临时表空

间读取数据。这部分数据块由于不缓存使得hit ratio不会被提高。其在计算hit
ratio时应当被扣除。

形象示意:db_file  ==> pga

通常,disk sort / hash , exp direct=Y
,都会有physical reads direct

[email protected]>  select name from v$statname where statistic# in
(54,55,56);

NAME

----------------------------------------------------------------

physical reads

physical reads
cache           
--使用buffer cache

physical reads
direct           --不使用buffer
cache

physical reads direct (lob)

对于大值对象,如LOB数据类型以及LOB段,Oracle可以绕过buffer
cache而直接使用PGA,其原理等同于physical reads direct

使用physical reads direct,physical reads direct
(lob)的优点:

对于一个大操作,需要请求大量数据块,假设又使用并行执行,且执行次数就那么一次,这个时候就适合使用direct方式,如果还是走buffer
cache则需要把buffer cache里已缓存的数据库都清空,注意physical write /direct 同理。

session logical reads

发出的总的请求次数,此处是指从database buffer
cache中请求块。对于一致性读,则这些缓冲包含来自回滚段的数据

下面是另一种不同的计算命中率的方法,通常用在10g和11g之中

SELECT NAME,

physical_reads,

db_block_gets,

consistent_gets,

ROUND((1 - (physical_reads / (db_block_gets + consistent_gets))) *
100) || ‘%‘ ratio

FROM   V$BUFFER_POOL_STATISTICS

WHERE  NAME = ‘DEFAULT‘;

SELECT (1 - (SUM(decode(NAME, ‘physical reads‘, VALUE, 0)) /

(SUM(DECODE(NAME, ‘db block gets‘, VALUE, 0)) +

SUM(DECODE(NAME, ‘consistent gets‘, VALUE, 0))))) * 100 "Hit
Ratio"

FROM   v$sysstat;

   consistent gets from cache

在回滚段Buffer中的数据构造一致性读数据块的总次数。其产生原因是由于其他会话对当前数据块进行操作,如update操作, 
但是由于我们的查询是在这些修改之前调用的,所以需要使用回滚段中的数据块的前映像进行查询,来保证数据的一致性。这样就产生了一致性读。

   db block gets     

在操作中提取的块数目,而不是在一致性读的情况下而产生的块数。

当前块(current,相对于cosistent读而言,current总是最新的块),从buffer
cache中请求的次数。当前块意思就是在操作中正好提取的块数目,而不是在一致性读的情况下而产生的块数。通常的情况下,一个查询提取的块是在查询开始的那个时间点上存在的数据块,当前块是在这个时刻存在的数据块,而不是在这个时间点之前或者之后的数据块数目。

  physical reads cache   

从磁盘读入到buffer cache中的总次数。

产生的主要原因是:在数据库高速缓存中不存在这些块, 全表扫描, 磁盘排序等

 

    db_block_gets +
consistent_gets
两者之和作为总的请求次数,在与physical_reads相比进而得到命中率

此方法与前面命中率计算的方法不一样,更简单直观。

4.4.影响命中率的因素


全表扫描(小标尚可,对于大表而言I/O性能更差。而且全表扫描总是被置于LRU的最尾端,随时被paged out)

不同数据定义和应用程序设计影响命中率

大表的随机访问(非顺序)

不均衡的cache hit

   
命中率需要考虑的问题:

a.对相同的大表和索引的重复扫描容易造成命中率很高的假象。定期检查频繁使用且         
返回结果集很大的SQL语句,确保这些SQL语句使用了最优的执行计划。

b.避免返回查询相同的数据,尽可能将获得的结果集缓存的客户端程序或中间件。

c.大表的全表扫描问题,直接将其放置到LRU的尾端,容易aged out。

(小表通常指全表扫描时占用buffer
cache 20%或拥有个数据块)。

d.对较大OLTP系统而言,表中的很多行仅仅被访问次或很少的次数,基于此,这些块     不易长时间占住buffer
cache。

f.对于并行查询或排序等,持续增加buffer cache的大小并无实际意义,优化效果并     明显。

4.5.下列情形可以考虑增加buffer cache

一些等待事件已经被优化

不良的SQL语句已经被优化

操作系统级别无不良的内存页面置换

上次增加的buffer cache有效

基于上面的情形,且命中率很低,此时可以增加buffer cache

4.6.增加buffer cache 的步骤

首先将db_cache_advice置于ON 状态

检查动态性能视图v$db_cache_advice(需要考虑增加后不影响操作系统级别过多的内存页面置换)动态增加db_cache_size的值(生产数据库不建议关闭系统而使用动态调整alter
system set db_cache_size=nM;)

查看当前buffer cache的大小

SELECT
NAME,current_size,buffers FROM v$buffer_pool;

NAME                          
CURRENT_SIZE    BUFFERS

------------------------------ ------------ ----------

DEFAULT                               
3456     428760

4.7.减少buffer cache 的情形


在命中率很高的情形下,查询视图v$db_cache_advice,来权衡适度降低buffer cache
size是否会使得系统I/O显剧增加,如不是,且降低buffer cache size不会影响性能的情况下,则可以适度降低buffer cache
size的大小。

使用alter system set db_cache_size来调整。

4.8.使用advisor来调整buffer cache

buffer cache advisor 可以启用或禁用通过收集统计信息来预估buffer
cache的大小,然后根据预估的大小以及工作负荷来调整buffer cache的大小。buffer cache
advisor功能通过设置参数db_cache_advice 开启用或禁用,该参数仅能支持系统级别的修改。

其参数值为:OFF,ON,READY

OFF:禁用buffer cache
advisor特性,且不为advisor分配内存

READY:不收集数据,但是收集数据的内存已经预先分配好了.通过把参数值从off设置为ready,然后再设置为on,以避免出现错误。

ALTER SYSTEM SET
db_cache_advice = ON | READY | OFF ;

该参数设置的前提条件为STATISTICS_LEVEL参数必须要先设置为TYPICAL或者ALL

通过设置启用buffer cache advisor
功能后,可以查看视图v$db_cache_advice来获得不同负荷下的advisor。

以下是该视图的几个重要列

SIZE_FOR_ESTIMATE

BUFFERS_FOR_ESTIMATE

ESTD_PHYSICAL_READS

查看缺省的buffer cache的advice

SELECT size_for_estimate "Cache Size (MB)",

size_factor,

buffers_for_estimate    "Buffers",

estd_physical_read_factor est_read_factor,

estd_physical_reads     estd_phy_red

-- ,estd_physical_read_time est_phy_red_t   --此参数在i
中不可用

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 Size (MB) SIZE_FACTOR    Buffers EST_READ_FACTOR
ESTD_PHY_RED

--------------- ----------- ---------- --------------- ------------

352       .1019     
43670         15.8455  
6.1906E+10

704       .2037     
87340         58.5913  
2.2891E+11

1056      
.3056    
131010         31.6149  
1.2351E+11

1408      
.4074    
174680         21.5397  
8.4152E+10

1760      
.5093    
218350         14.6721  
5.7321E+10

2112      
.6111    
262020          8.3646  
3.2679E+10

2464       
.713    
305690          3.8134  
1.4898E+10

2816      
.8148    
349360          1.9615  
7663197796

3168      
.9167    
393030          1.2403  
4845534681

3456          
1    
428760              
1   3906820053

3520      1.0185    
436700          
.9675   3779821439

3872      1.1204    
480370          
.8359   3265831355

4224      1.2222    
524040          
.7512   2934896434

4576      1.3241    
567710          
.6957   2717876216

4928      1.4259    
611380          
.6565   2564852647

5280      1.5278    
655050          
.6272   2450487527

5632      1.6296    
698720          
.6045   2361720470

5984      1.7315    
742390          
.5859   2289177246

6336      1.8333    
786060          
.5726   2236962972

6688      1.9352    
829730          
.5619   2195121418

7040      
2.037    
873400          
.5521   2156817317

4.9.优化Buffer cache的常用参数及视图


表:

db_cache_size

db_cache_advice

db_keep_cache_size

db_recycle_cache_size

db_file_multiblock_read_count

statspace report

v$db_cache_advice(view)

视图

v$buffer_pool_statistics

v$buffer_pool

v$db_cache_advice

v$sysstat

v$sesstat

v$system_event

v$session_wait

v$bh

v$cache

Buffer cache 实际上细分为多个不同的Buffer cache,如keep
pool,recycle pool,default pool,下面描述不同buffer cache的使用。

有关Buffer cache 的总体描述,请参考:Buffer
cache 的调整与优化(一)

五、不同buffer pool的应用

一个buffer pool即对应于一个oracle
数据块,三种不同的pool实际上是针对在data buffer
cache中块的访问的程度不同在通常的惯例下采取的方法。即对最热块,次热快,以及冷块存放到不同的buffer pool中。实际上这几个不同的buffer
pool除了分配的大小不同之外,所采用的算法都是LRU算法,因此对块的缓存以及淘汰(aged out)算法实质一样。

任意一个不同的buffer
pool都将根据访问方式的不同而只缓存读取到的数据块,即如果是全表扫描,则缓存所有块,如果是索引快速扫描,则缓存索引的所有叶节点块。

keep buffer
cache            --对应keep
pool

recycle buffer
cache         --对应recycle pool

nk buffer
caches            
--对应db_nk_cache_size

default buffer
cache         --对应dafault pool

keep pool:

对于经常访问的小表将其常驻内存,即放置到keep
pool。其作用是保证这部分经常访问的数据能够常驻内存而不被替换出内存,从而提高访问这些数据的速度。这个池最好能够保持99%的命中率,也就是说要保证这个池的大小能够缓存放于这个池的大部分对象。

recycle pool:

对于不经常访问的大segment,就可以考虑将其放置到recycle
pool,以尽快将其淘汰出去。

dafault pool:

普通对象的缓冲池,那些没有在keep pool也没有在recycle
pool的对象将缓冲到这里。nk buffer caches

主要适用于不同平台传输表空间,或根据业务需要来使用非标准表空间之外的表空间。

如磁盘上数据文件的最小I/O单元叫block一样,buffer
cache的最小单元(或者说结构)叫buffer。每个buffer跟x$bh中每条记录存在一一对应关系。

注意:

default buffer cache  = db_cache_size -
db_keep_cache_size - db_recycle_cache_size - db_nk_cache_size

[email protected]> select * from v$version where rownum < 2;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

[email protected]> select name,bytes/1024/1024 from v$sgainfo where name=‘Buffer Cache
Size‘;

NAME                     
BYTES/1024/1024

------------------------- ---------------

Buffer Cache
Size                    
192

[email protected]> select name,current_size,buffers,block_size  FROM
v$buffer_pool;

NAME           
CURRENT_SIZE    BUFFERS BLOCK_SIZE

--------------- ------------ ---------- ----------

DEFAULT                 
192      23952      
8192

[email protected]> alter system set db_recycle_cache_size=16m;

[email protected]> alter system set db_keep_cache_size=16m;

[email protected]> select name,current_size,buffers,block_size  FROM
v$buffer_pool;

NAME           
CURRENT_SIZE    BUFFERS BLOCK_SIZE

--------------- ------------ ---------- ----------

KEEP                     
16       1996      
8192

RECYCLE                  
16       1996      
8192

DEFAULT                 
160      19960      
8192

[email protected]> alter system set db_16k_cache_size=4m;

[email protected]> select name,current_size,buffers,block_size  FROM
v$buffer_pool;

NAME           
CURRENT_SIZE    BUFFERS BLOCK_SIZE

--------------- ------------ ---------- ----------

KEEP                     
16       1996      
8192

RECYCLE                  
16       1996      
8192

DEFAULT                 
160      19960      
8192

DEFAULT                   
4        252     
16384

从上面的设置可以看出,任意一个buffer
pool大小的调整,不影响整个buffer_pool的大小。即任意buffer pool的增加,将使得default buffer
pool的减小,反之,任意buffer pool尺寸的减少,default buffer pool的尺寸将会增加。

其次,任意buffer pool的增加应考虑到Oracle
以及OS是否有足够的内存来进行分配。如果是使用了ASMM管理,则应考虑整个sga_target <
sga_max_size。

六、大表段、大索引段随机访问的问题

当使用LRU算法时,对于大表段,索引段的随机访问,容易导致其他的并非最频繁访问的热点块从cache中被aged out.此外,这些随机访问 
的数据块并不属于热块,也很容易随时被替换,通过下面的三种方法来避免该情况的产生:

1.如果受影响的对象是索引,则判断是否是精确的索引选择,如果不是,则调整SQL语句。

2.如果SQL语句已优化,则可以将被访问的大段存放到recycle cache中。

3.可以将一些小的热点块移入到keep buffer pool,keep buffer
pool能够最小化cache的丢失。

七、多个buffer pool的设置


db_cache_size

db_keep_cache_size

db_recycle_cache_size

db_nk_cache_size

以上的参数为动态参数,使用下面的方式来调整,可以基于内存调整,也可以将参数更改到spfile。

alter system set
db_keep_cache_size=nm scope = both | memory | spfile;

alter system set
db_16k_cache_size=nm;

alter system set
db_recycle_cache_size=nm;

闩由Oracle RDBMS来自动分配

进行了上述设置之后,可以基于这些不同的缓冲池来创建对象

create index
idx_obj    storage(buffer_pool keep);

alter table tb_obj
storage(buffer_pool recycle);

alter index idx_obj
storage(buffer_pool keep);

注:

四个池除了使用不同的名称且产生不同的作用之外,其内部算法实质是一样的,都是采用LRU算法。

一个segment只能放入到一个buffer
pool中.如果一个表或索引对象拥有多个segment,则不同的segment可以存放到不同的buffer pool.

如何决定什么样的segment存放到何种buffer
cache则根据业务需求来定。

如果没有指定buffer_pool短语,则表示该对象进入default类型的buffer
cache。

八、keep buffer pool的使用与优化

将常用的小表对象常驻内存

一般情况是对象的大小应当为少于default buffer pool
大小的10%。

根据下面的方法计算对象所占用块的总数,且该块的总数大小应当小于于keep buffer
pool的大小。

计算所有将要放入到keep buffer
cache对象的总块数得到一个近似值,然后将稍微大于该近似值的尺寸指定给keep buffer pool。

可以通过查询DBA_TABLES.BLOCKS
和DBA_TABLES.EMPTY_BLOCKS 获得块的信息或者通过V$BH查看segment所占用的buffer。

对于放入keep buffer pool中的表数据,如果对象块多于buffer
pool数量,则以buffer pool数量为准进行缓存,冷块将被新块置换。

注:如果位于keep buffer pool中的对象尺寸增大,将不会被填充到keep buffer
pool。

其次,如果有多个对象缓存到keep buffer pool,而keep buffer
pool不足以缓存这些对象,按LRU算法,先前位于keep buffer pool 的对象一样会被aged out。

首先使用包收集对象信息

[email protected]> exec dbms_stats.gather_table_stats(‘SCOTT‘,‘BIG_KEEP‘);

[email protected]> select
table_name,blocks,empty_blocks

2  from dba_tables where owner=‘SCOTT‘ and
table_name=‘BIG_KEEP‘;

TABLE_NAME                   
BLOCKS EMPTY_BLOCKS

------------------------- ---------- ------------

BIG_KEEP                        
180            0

设定keep buffer pool的大小

alter system set
db_keep_cache_size=16m scope = both ;

--注意,该参数值的大小应根据实际情况设置

将对象放置的keep buffer
pool

alter table big_keep
storage(buffer_pool keep);

九、recycle buffer pool的使用与优化


一旦事务被提交则这些块将从recycle buffer pool中被清除。

对象的大小应当为多于default buffer pool 大小的两倍recycle
buffer pool需要具有一个事务所需要的全部块。

下面将big_temp 置入到recycle buffer pool

[email protected]> exec
dbms_stats.gather_table_stats(‘SCOTT‘,‘BIG_RECYCLE‘);

[email protected]> select blocks,empty_blocks
from
dba_tables

2  where
table_name=‘BIG_RECYCLE‘ and
owner=‘SCOTT‘;

BLOCKS EMPTY_BLOCKS

----------
------------

1062           
0

alter system set
db_recycle_cache_size=16m scope = both ;

--注意,该参数值的大小应根据实际情况设置

[email protected]> alter table big_recycle
 storage(buffer_pool recycle);

使用视图v$cache,

SELECT owner#

,NAME

,COUNT(*) blocks

FROM v$cache

GROUP BY
owner#,NAME;

SELECT
s.username     --跟踪recycle buffer pool的I/O情况

,io.block_gets

,io.consistent_gets

,io.physical_reads

FROM v$sess_io
io,v$session s

WHERE
io.sid=s.sid;

十、获得buffer pool中的相关信息

视图v$bh(基于视图x$bh)显示当前位于SGA中所有块的详细信息。决定哪个段位于哪个缓冲区,所占住的块的个数等。

1.查询buffer
cache中不同对象占住块的个数(可以根据查询将不经常访问的大对象置于到recycle pool)

SELECT o.owner,
object_name, object_type, COUNT(1) buffers  --这个查询获得到经常访问的对象,可以将其放到recycle
pool中

FROM  
SYS.x$bh, dba_objects o

WHERE  (tch = 1
OR (tch = 0 AND lru_flag < 8))

AND obj = o. object_id

AND o.owner NOT IN (‘SYSTEM‘, ‘SYS‘)

GROUP  BY
o.owner, object_name, object_type

ORDER  BY
buffers;

SELECT o.owner,
object_name, object_type, COUNT(1) buffers  
--这个查询获得到经常访问的对象,可以将其放到keep pool中

FROM  
SYS.x$bh, dba_objects o

WHERE  tch >
10

AND lru_flag = 8

AND obj = o.object_id

AND o.owner NOT IN (‘SYSTEM‘, ‘SYS‘)

GROUP  BY
o.owner, object_name, object_type

ORDER  BY
buffers;

2.查询单个对象占住buffer cache中块的总个数

SELECT COUNT(*)

FROM v$bh

WHERE objd=(

SELECT
data_object_id

FROM
Dba_Objects

WHERE
object_name=UPPER(‘big_table‘)

AND owner=‘SCOTT‘

AND  status != ‘free‘);

COUNT(*)

----------

4235

3.获得所有不同的buffer pool 当前分配块的总个数

SELECT NAME

,block_size

,SUM(buffers)

FROM v$buffer_pool

GROUP BY
NAME,block_size

HAVING
SUM(buffers)>0;

NAME       BLOCK_SIZE SUM(BUFFERS)

---------- ----------
------------

DEFAULT         
8192         8958

KEEP            
8192         1996

DEFAULT        
16384          252

RECYCLE         
8192         1996

4.获得单个对象占用buffer cache的比率

SELECT round(obj_cnt/totalcache_cnt*100,3)

FROM

(SELECT COUNT(*) AS obj_cnt

FROM v$bh

WHERE objd=(

SELECT data_object_id

FROM Dba_Objects

WHERE object_name=UPPER(‘big_table‘)

AND owner=‘SCOTT‘))a,

(SELECT NAME

,block_size

,SUM(buffers) AS totalcache_cnt

,COUNT(*)

FROM v$buffer_pool

WHERE NAME=‘DEFAULT‘

GROUP BY NAME,block_size

HAVING SUM(buffers)>0)
b;

ROUND(OBJ_CNT/TOTALCACHE_CNT*100,3)

-----------------------------------

.015

七、查询不同的buffer pool的命中率(buffer cache hit ratio)

低ratio并不能表明增加cache
size可以提高性能。高ratio有时反而会让你误认为cache
size已经足够大而满足要求了。比如:重复的扫描一些大表或索引。然后大表的全表扫描往往都是物理读,会人为的降低hit
ratio。因此在不同高峰时段,多次采集数据非常有必要(或使用StatsPack。

Db_cache_size
是针对默认的db_block_size的,对于非标准的block,要特别指定DB_nK_CACHE_SIZE 参数。

SELECT NAME,

block_size,

physical_reads,

db_block_gets,

consistent_gets,

(1 -(physical_reads / (DECODE(db_block_gets, 0, 1, db_block_gets)
+

DECODE(consistent_gets, 0, 1, consistent_gets)))) * 100  "Hit
Ratio"

FROM  
V$BUFFER_POOL_STATISTICS

ORDER  BY
NAME;

NAME       BLOCK_SIZE PHYSICAL_READS DB_BLOCK_GETS
CONSISTENT_GETS Hit Ratio

---------- ----------
-------------- ------------- --------------- ---------

DEFAULT        
16384            
63            
5            
128    52.632

DEFAULT         
8192         
21013       
230479         
879158    98.106

KEEP            
8192             
0            
0              
0   100.000

RECYCLE         
8192           
106            
0            
434    75.632

十一、总结


尽管使用不同的缓冲池从某种程度上来说可以大大提高数据库系统的I/O,给予了DBA更多的选择性。然而,多个缓冲池(buffer
pool)增加了管理的复杂度,其次由于不同的缓冲池不能够共享,在某种程度上来说,势必造成buffer cache大小的浪费。因此,如果default
buffer pool能够满足现有的需求,尽可能的避免使用过多的缓冲池带来管理的不便。

[转载]Buffer cache的调整与优化,布布扣,bubuko.com

时间: 2024-10-03 22:32:43

[转载]Buffer cache的调整与优化的相关文章

Buffer cache 的调整与优化

Buffer cache 的调整与优化 -============================== -- Buffer cache 的调整与优化(一) --============================== Buffer Cache是SGA的重要组成部分,主要用于缓存数据块,其大小也直接影响系统的性能.当Buffer Cache过小的时候,将会造成更多的free buffer waits事件. 下面将具体描述Buffer Cache的作用,调整与优化. 一.SGA的所有组件 从动态

BUFFER CACHE之调整buffer cache的大小

Buffer Cache存放真正数据的缓冲区,shared Pool里面存放的是sql指令(LC中一次编译,多次运行,加快处理性能,cache hit ratio要高),而buffer cache里面存放真正的查询结果.Buffer Cache:由彼此独立的三个子cache(subcaches,也叫主buffer cache:keep,recycle,default)组成支持多种数据块的多缓冲池.注意system表空间只能用主数据块 Step1: 查看各个组件size(看buffer cache

调优4(buffer cache 调整)

第四章. buffer cache 调整 1.buffer cache 功能 buffer cache: 用于存放从datafile 里读出的数据块的镜像,并共享这些数据块,采用LRU算法 buffer cache 数据块状态: pending:数据块正在使用,状态未决dirty: 被修改过的块,还未写入到datafilefree: 已经从cache里写入到datafile的块,可以被覆盖 LRU LIST :链接从datafile里读出的块的头部信息,一般用于free 状态的块Checkpoi

Oracle优化 -- 关于Database Buffer Cache相关参数DB_CACHE_SIZE的优化设置

select size_for_estimate, buffers_for_estimate ,ESTD_PHYSICAL_READ_factor,ESTD_PHYSICAL_READS from v$db_cache_advice    2      where block_size='8192' and advice_status='ON'; 中,size_for_estimate表示预计的数据库高速缓冲区的大小(即:db_cache_size的值).ESTD_PHYSICAL_READS表

buffer cache —— buffer busy waits/read by other session

oracle提供非常精确.有效的row level lock机制,多个用户同时修改数据时,为了保护数据,以块为单位挂起锁的情况不会发生.但这不太正确.以块为单位的锁虽然不存在,但正因为oracle I/O以块为单位组成,所以块单位锁是必要的.假设row1.row2两个行位于同一个块内,两名用户(用户1.用户2)各自对row1.row2执行update,逻辑上两个被更新行之间不存在需要相互保护的数据.因为oracle提供row level lock机制,所以修改互相不用的行完全不成问题.但是若两个

buffer cache 和shared pool 详解(之三,shared pool原理)

[深入解析--eygle] 学习笔记 1.2 shared pool原理 Shared Pool是Oracle SGA设置中最复杂也是最重要的一部分内容,Oracle通过Shared Pool来实现SQL共享.减少代码硬解析等,从而提高数据库的性能.在某些版本中,如果设置不当,Shared Pool可能会极大影响数据库的正常运行. 在Oracle 7之前,Shared Pool并不存在,每个Oracle连接都有一个独立的Server进程与之相关联,Server进程负责解析和优化所有SQL和PL/

buffer cache 和shared pool详解(之五,问题诊断总结)

[深入解析--eygle] 学习笔记 1.2.7 诊断和解决ORA-04031 错误 Shared  Pool的主要问题在根本上只有一个,就是碎片过多带来的性能影响. 1.2.7.1 什么是ORA-04031错误 当尝试在共享池分配大块的连续内存失败(很多时候是由于碎片过多,而并非真是内存不足)时,Oracle首先清除共享池中当前没使用的所有对象,使空闲内存块合并.如果仍然没有足够大的单块内存可以满足需要,就会产生ORA-04031错误. 如下一段伪代码来描述04031错误的产生: Scan f

Linux中的Buffer Cache和Page Cache

http://wenku.baidu.com/view/dd677d2fcfc789eb172dc868.html http://bbs.chinaunix.net/thread-3759086-1-1.html http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4189715&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline 了解下

内存列式存储 vs Buffer Cache

Oracle DB 12c的In-Memory选项(DBIM)将表中列的所有行的数据载入内存,为何不能像Buffer Cache那样只把频繁访问的数据块置入内存中呢? 内存列式存储和Buffer Cache的访问模式 原因是两者支持的访问模式不同,对于Buffer Cache,支持的是OLTP应用,访问模式为non-uniform access patterns,也就是说表中的某些行访问比其它行频繁,因此才能通过只缓存10%的数据,就可以涵盖95%的数据访问.可以假设缓存10%的数据就可以得到2