zoukankan      html  css  js  c++  java
  • Oracle buffer cache与相关的latch等待事件

    buffer cache与相关的latch等待事件 1.buffer cache 2.latch:cache buffers lru chain 3.latch:cache buffers chains 1.buffer cache 我的理解: buffer cache理解成4块结构: 三个列表+1个pool 三个列表指: lru (最近最少使用列表) dirty list (checkpoing qu

    buffer cache与相关的latch等待事件

    1.buffer cache
    2.latch:cache buffers lru chain
    3.latch:cache buffers chains


    1.buffer cache

    我的理解:
    buffer cache理解成4块结构: 三个列表+1个pool
    三个列表指:
        lru                        (最近最少使用列表)
        dirty list (checkpoing queue)
        hast bucket        (与latch:cache buffer chain相关)

    一个pool指:
       buffer pool = db_cache_size / db_block_size

    buffer pool:
    内存中,数据存放的位置,每个pool的大小就是db_block_size大小.
    比如,db_cache_size=800M,db_cache_size=8192,那么,buffer cache中包含的buffer pool 就有102400个(800*1024*1024/8192).

    lru:
    最近最少使用列表,一个顺序的清单,最上面为:MRU端(最常使用的对象),最下面为:LRU端(最不常用的对象)
    在数据库初使化时,所有的buffer都被hash到LRU列表上管理;
    当要从数据文件中读取数据时,首先要在LRU列表上查找free buffer,找到后才读取到buffer pool(即buffer cache)中.

    dirty list:
    脏数据列表,指向内存中需要写入数据文件的buffer pool的地址

    hash bucket:
    对于buffer pool,如果都通过一种结构管理,像从前面102400个pool中如果要找一个pool的话,性能会很低下.为了提高效率,oracle引入了 bucket结构,oracle将所有的buffer通过hash算法将buffer存放到不同的bucket上,用户需要定位buffer时,只用到 bucket中查找少量的buffer就可以找到.这样就提高了效率.


    buffer cache的原理:
    这个原理至关重要.

    当一个Server进程需要读取数据到buffer cache中时:

    1).首先要判断该数据是否存在于buffer中,如果存在,且可用.则获取数据,再根据LRU算法在LRU列表上移动该block;

    2).如果数据不存在于buffer中,Server进程就要扫描lru列表,查找可用的buffer空间(free buffer)以放数据到buffer中,
    在扫描lru list的过程中,如果碰到已经被修改过的buffer,就将它移动到dirty list(checkpoint queue)上(由于增量检查点的引入,DBWR进程也会主动扫描一定比例的LRU list,将发现的脏数据块移动到dirty lis);
    如果dirty list(checkpoint queue)达到了阈值,Server进程就会通知DBWn进程写出脏数据到数据文件(DBWR进程写的一个触发条件);
    如果Server进程扫描lru列表到一个阈值还没有找到足够的free buffer,这时,就停止对lru的扫描转而通知DBWR写出脏数据,释放内存空间;这时,进程处于free buffer wait等待.

    3).找到足够的buffer之后,Server进程就可以将数据从数据文件读入到buffer cache中;

    4).如果读取的block不满足"一致性"需求,则Server进程就需要通过当前block的版本从回滚段中读取该block的"一致性"镜像返回给用户(consistent gets).



    2.latch:cache buffers lru chain

    当用户读取数据到buffer cache中,或buffer cache根据LRU算法进行管理时,就不可避免的要扫描LRU列表以获取free buffer或更改buffer状态.
    buffer cache为众多并发进程提供并发访问,所以在搜索的过程中,必须获取latch锁定内存结构,以防止并发访问对内存中的数据造成损坏.
    这个用于锁定LRU的latch就是cache buffers lru chain.

    cache buffers lru chain锁存器的默认数量:
    DB_WRITER_PROCESSES <= 4        锁存器数= 4 * cpu数
    DB_WRITER_PROCESSES > 4        锁存器数= db_writer_processes * cpu数
    可以通过初始化参数_db_block_lru_latches来向上调整cache buffers lru chain锁存器的数量(不建议这么做,除非在oracle support的建议下)

    如果这个latch竞争激烈:
    (1) 适当增大buffer cache,这样可以减少读数据到buffer cache,减少扫描lru列表的次数

    (2) 适当增加lru latch数量,修改_db_block_lru_latches参数.不建议这么做.

    (3) 使用多缓冲池技术


    3.latch:cache buffers chains

    引起cache buffers chains争用的原因一:低效率的SQL语句

        多个并发低效的SQL语句同时执行,都设法获得相同的数据集,就造成cache buffers chains的争用.
        调整高buffer_gets的SQL语句可以缓解这类问题.(较小的逻辑读意味着较少的latch get操作,从而减少锁存器争用并改善性能。)

    引起cache buffers chains争用的原因二:热点块(最常见原因)
        判断是不是热块问题的常用方法检查latch free事件的p1raw参数值,如果p1raw是相同的锁存器地址,则表明是热块问题.

        select sid,event,p1raw,p2,p3,seconds_in_wait,wait_time,state
        from v$session_wait
        where event = 'latch free';


        如果要确定具体的热点块,就要查询v$latch_children,x$bh,dba_extents,根据子latch的信息确认热点块.
        v$latch_children.addr 与x$bh.hladdr相关联,可以确认子latch相关的块.
        再根据x$bh.dbarfil与dba_extents.relative_fno和x$bh.dbablk与dba_extents.block_id&&block_id+blocks关联,查到具体对象.


    1> 查看cache buffers chains子latch情况:

    SQL> select * from
    (select addr,child#,gets,misses,sleeps,immediate_gets igets,immediate_misses imisses,spin_gets
             from v$latch_children
            where name = 'cache buffers chains'
    order by sleeps desc
    )
    where rownum<11;


    ADDR         CHILD#       GETS     MISSES     SLEEPS      IGETS    IMISSES SPIN_GETS
    -------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
    69B625BC        739    1056438         65         41        645          0         46
    69A821BC          3    1115506         54         39        711          0         34
    69B0A9BC        451    1476125         96         30        573          0         83
    69A83EFC          9     207227        833         20        800          0        823
    69AA573C        119     167852        635         14        592          0        628
    69AB2DBC        163     860553         22         14        670          0         15
    69B8C19C        876    1283643       1125         12        224          0       1118
    69B03E7C        429     315851         53         11        413          0         47
    69B1C47C        509     590733         18         11        689          0         14
    69BADEBC        987     223777        208         11        529          0        201

    2> 联合x$bh视图查出相关块信息

    SQL> select b.addr,a.tch,a.ts#,a.dbarfil,a.dbablk,b.gets,b.misses,b.sleeps
    from
          (select *from
                  (select addr,ts#,file#,dbarfil,dbablk,tch,hladdr from x$bh order by tch desc)
           where rownum<11
          ) a,
          (select addr,gets,misses,sleeps from v$latch_children where name = 'cache buffers chains'
          ) b
    where a.hladdr = b.addr;


    ADDR            TCH        TS#    DBARFIL     DBABLK       GETS     MISSES     SLEEPS
    -------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
    69BB451C      17729          6          5    1277992     548061          0          0
    69B92CDC      17729          6          5    1277991     581254          0          0
    69B7149C      17729          6          5    1277990     534335          0          0
    69B4FC5C      17729          6          5    1277989     534914          0          0
    69B2E41C      17728          6          5    1277988    1087533          1          0
    69B0CBDC      17726          6          5    1277987     538605          0          0


    3> 联合dba_extents查出具体的数据对象

    select distinct owner,segment_name,segment_type
    from dba_extents a,
         (select * from (select addr,tch,ts#,file#,dbarfil,dbablk from x$bh order by tch desc)
           where rownum<11
         ) b
    where a.relative_fno = b.dbarfil
    and   a.block_id <= b.dbablk
    and   a.block_id + blocks > b.dbablk;


    4> 联合v$sqltext或v$sqlarea找出相关的SQL语句

    select /*+ rule */ hash_value,sql_text
    from v$sqltext
    where (hash_value,address) in
          (select a.hash_value,a.address
             from v$sqltext a,
                  (select distinct a.owner,a.segment_name,a.segment_type
                     from dba_extents a,
                          (select dbarfil,dbablk
                             from (select dbarfil,dbablk
                                     from x$bh
                                   order by tch desc
                                  )
                            where rownum<11
                          ) b
                    where a.relative_fno = b.dbarfil
                      and a.block_id <= b.dbablk
                      and a.block_id + a.blocks > b.dbablk
                   ) b
            where a.sql_text like '%'||b.segment_name||'%'
              and b.segment_type = 'TABLE'
           )
    order by hash_value,address,piece;

  • 相关阅读:
    tf.keras 用生成器读取图片数据+预处理
    pandas时间序列操作
    jupyter notebook 字体美化
    python响应式的数据可视化工具Dash
    python 地名地址解析(省、市、区县)
    将jupyter notebook嵌入博客园的博客
    Adaboost、GBDT、xgboost的原理基础
    数据预处理:分类变量实体嵌入做特征提取
    类不平衡问题的处理办法
    word2vec原理
  • 原文地址:https://www.cnblogs.com/hllnj2008/p/5129221.html
Copyright © 2011-2022 走看看