• 博客访问: 446529
  • 博文数量: 193
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-18 15:56
个人简介

暂无介绍

文章分类
文章存档

2014年(1)

2013年(3)

2012年(59)

2011年(98)

2010年(32)

我的朋友

分类: Linux操作系统

2011-07-29 14:13:50

Buffer cache 的调整与优化(二)
分类: Oracle 性能优化 144人阅读 评论(0) 收藏 举报

--********************************

-- Buffer cache 的调整与优化()

--********************************

   

    Buffer cache 实际上细分为多个不同的Buffer cache,如keep poolrecycle pooldefault 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

        每个bufferx$bh中每条记录存在一一对应关系。

       

        注意:

            default buffer cache  = db_cache_size - db_keep_cache_size - db_recycle_cache_size - db_nk_cache_size

   

            sys@ORCL> select * from v$version where rownum < 2;

 

            BANNER

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

            Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

 

            sys@ORCL> select name,bytes/1024/1024 from v$sgainfo where name='Buffer Cache Size';

 

            NAME                      BYTES/1024/1024

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

            Buffer Cache Size                     192

                       

            sys@ORCL> select name,current_size,buffers,block_size  FROM v$buffer_pool;

 

            NAME            CURRENT_SIZE    BUFFERS BLOCK_SIZE

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

            DEFAULT                  192      23952       8192

 

            sys@ORCL> alter system set db_recycle_cache_size=16m;

 

            sys@ORCL> alter system set db_keep_cache_size=16m;

 

            sys@ORCL> 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

 

            sys@ORCL> alter system set db_16k_cache_size=4m;

 

            sys@ORCL> 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 poolkeep 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

                   

        首先使用包收集对象信息

            sys@ORCL> exec dbms_stats.gather_table_stats('SCOTT','BIG_KEEP');

            sys@ORCL> 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

        sys@ORCL> exec dbms_stats.gather_table_stats('SCOTT','BIG_RECYCLE');

   

        scott@ORCL> 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 ;  --注意,该参数值的大小应根据实际情况设置

       

        scott@ORCL> alter table big_recycle

          2  storage(buffer_pool recycle);

   

    使用视图v$cache

        SELECT owner#

               ,NAME

               ,COUNT(*) blocks

        FROM v$cache

        GROUP BY owner#,NAME;

 

        SELECT s.username     --跟踪recycle buffer poolI/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能够满足现有的需求,尽可能的避免使用过多的缓冲池带来管理的不便。

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

hwayw2011-08-01 09:45:03

Buffer cache 的调整与优化(二)这篇文章已被推荐到华北DBA圈子圈子中。

评论热议
请登录后评论。

登录 注册