Buffer cache 的原理

一、

1·)当一个服务器进程需要读数据到buffer cache中时,首先必须判断该数据在buffer 中是否存在,如果存在且可用,则获取该数据,根据lru算法在lru list上移动该block;如果buffer中不存在该数据,则需要从数据文件上获取

2)在读取数据之前,server进程需要扫描lru list 寻找free的buffer,扫描过程中server进程会把发现的所有已经被修改过的buffer移动到checkpoint queue上,这些dirty buffer随后可以被写出到数据文件。

3)如果checkpoint queue超过了阈值,server进程会通知dbwn去写出脏数据;这也是出发dbwr写的一个条件。

Select   kvittag,kvitval,kbvitdsc  from x$kvit  where  kvittag=’kcbldq’;

如果server进程扫描lru超过一个阈值仍然不能找到足够的free buffer ,将停止寻找,转而通知dbwn去写出脏数据,释放空间。

Select   kvittag,kvitval,kbvitdsc  from x$kvit  where  kvittag=’kcbfsp’;

同时由于增量检查点的引入,dbwn进程也会主动扫描lru list,将发现的dirty buffer 移动至checkpoint queue,这个扫描也受到一个内部 约束,

Select   kvittag,kvitval,kbvitdsc  from x$kvit  where  kvittag=’kcbdsp’;

4)找到足够的buffer之后,server进程就可以将buffer从数据文件读入buffer cache

5)如果读取的block不满足读一致性要求,则server进程需要通过当前block版本和回滚段构造前镜像返回给用户。

从oracle 8i开始lru list 和dirty list 引入了辅助的list,用于提高管理效率,当数据库初始化时,buffer首先存放在lru的辅助list上,当被使用后移动到lru 的主list上,这样当用户进程搜索free buffer时,首先从辅助list上搜索,当dbwr搜索dirty buffer时 会首先从lru 的主list上进行搜索,提高了搜索效率和数据库性能。

二、转储buffer cache 的内容(1-10级)

Alter  session  set  events ‘immediate  trace  name  buffers level  4’;

Level  1:仅包含buffer headers 的信息。

Level  2:包含buffer headers和buffer概要信息转储

Level 3:包含buffer headers和完整buffer内容转储。

三、cache buffer  lru chain 闩锁竞争与解决

当用户进程需要读数据到buffer cache时,或cache buffer根据lru算法进行管理时,就不可避免地要扫描lru list 获取可用buffer或更改buffer状态。在搜索的过程中必须获取latch,锁定lru的latch就是常见到的cache buffers  lru chain

解决该latch竞争的方法:

1)适当的增加buffer cache,这样既可以减少读数据到buffer cache的机会,减少扫描lru list 的竞争

2)可以适当增加lru latch 的数量,修改_db_block_lru_latches 参数可以实现,

3)通过多缓冲池技术,可以减少不希望的数据老化和全表扫描等操作对于default池的冲击,从而减少竞争。

四、cache  buffer  chain 闩锁竞争与解决

1、在lru和checkpoint queue这两个内存结构之外,buffer cache的管理还存在另外两个重要的数据结构:hash bucket 和 cache buffer chain

2、为了提高oracle 确定某个block在buffer中的位置,oracle引入了bucket的数据结构,oracle把管理的所有buffer通过一个内部的hash算法运算之后,存放到不同hash  bucket中,这样通过hash bucket进行分割之后,众多的buffer 被分布到一定数量的bucket之中,当用户需要在buffer中定位数据是否存在时,只需要通过同样的算法获得hash值,然后到相应的bucket中查找少量的buffer即可确定。每个buffer存放的bucket由buffer的数据块地址运算决定。

Bucket 内部,通过cache buffer chain (一个双向链表)将所有的buffer通过buffer header信息联系起来。

Buffer header 存放的是对应数据块的概要信息,包括数据文件号、块地址、状态等。要判断数据块在buffer中是否存在,通过检查buffer header即可确定。

3、bucket的数量受一个隐含参数的影响:

Db_block_hash_budkets

1)       从oracle 8i开始,bucket的数量比以前大大增加,通过增加的bucket的稀释使得每个bucket上的buffer数量大大减少。

2)       oracle 8i之前,_db_block_hash_laches的数量和bucket的数量是一致的,每个latch管理一个bucket;从oracle 8i开始每个latch管理多个bucket,由于每个bucket上的buffer数量大大降低,所以latch的性能反而得到了提高。

3)       每个bucket存在一条cache buffer chain

4)       Buffer header 上存在指向具体buffer的指针。

5)       了解了以上算法后,可以想象,如果大量进程对相同的block进程进行操作,那么必然引发cache buffer chain的竞争,也就是通常所说的热快竞争。

五、x$bh和 buffer header

每个buffer在x$BH中都存在一条记录。

X$BH中有一个重要字段TCH   ,TCH为touch的缩写,表示一个buffer的访问次数,buffer被访问的次数越多,说明该buffer越抢手,也就是可能存在热点块竞争的问题

查询当前数据库最繁忙的buffer

Select *

From (select addr,ts#,file#,dbarfil,dbablk,tch

From x$bh

Order by tch desc)

Where rownum<11;

结合dba_extents中的信息,可以查询到这些热点buffer都来自那些对象。

Select   e.owner,e.segmet_name,e.segment_type

From dba_extents e,

(Select *

From (select addr,ts#,file#,dbarfil,dbablk,tch

From x$bh

Order by tch desc)

Where rownum<11)

Where  e.relative_fno=b.dbarfl

And e.block_id<=b.dbablk

And e.block_id+e.blocks>dbablk;

如果需要确定热点块对象,可以从v$latch_children中查询具体的子latch信息。

X$BH中还存在另外一个关键字段hladdr 即hash chain latch address,这个字段可以和v$latch_child.addr进行关联,这样就可以把具体的latch竞争和数据块关联起来。再结合dba_extents视图再结合v$sqlarea或者v$sqltext找到频繁操作这些对象的sql,然后对其进行优化,即可缓解或解决热点竞争的问题。

oracle buffer cache的基本原理的更多相关文章

  1. Oracle buffer cache

    Buffer Cache buffer cache 结构图 HASH链 ORACLE使用HASH算法,把buffer cache中每个buffer的buffer header串联起来,组成多条hash ...

  2. Oracle buffer cache与相关的latch等待事件

    buffer cache与相关的latch等待事件 1.buffer cache 2.latch:cache buffers lru chain 3.latch:cache buffers chain ...

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

    select size_for_estimate, buffers_for_estimate ,ESTD_PHYSICAL_READ_factor,ESTD_PHYSICAL_READS from v ...

  4. lnux内核的malloc实现(Oracle的cache buffer影子)

    lnux内核的malloc实现(Oracle的cache buffer影子) 本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/artic ...

  5. oracle查询buffer cache中undo大小

    1.Does undo buffer exists or changes will directly write to undo datafiles? Undo blocks are database ...

  6. ORACLE性能优化- Buffer cache 的调整与优化

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

  7. 深入浅出Oracle学习笔记:Buffer Cache 和Shared pool

    Buffer cache 和 share pool 是sga中最重要最复杂的部分. 一.Buffer Cache 通常数据的读取.修改都是通过buffer cache 来完成的.buffer cach ...

  8. 相克军_Oracle体系_随堂笔记005-Database buffer cache

    本章主要阐述SGA中的Database buffer cache. Buffer cache { 1.pin (读写瞬间的状态) 2.clean 3.dirty 4.unused } --Databa ...

  9. Buffer Cache

    Buffer Cache Buffer Cache是SGA区中专门用于存放从数据文件中读取的的数据块拷贝的区域.Oracle进程如果发现需要访问的数据块已经在buffer cache中,就直接读写内存 ...

随机推荐

  1. java实现搜索附近地点或人的功能

    前言 当前大多数app都有查找附近的功能, 简单的有查找周围的运动场馆, 复杂的有滴滴, 摩拜查找周围的车辆. 本文主要阐述查找附近地点的一般实现. 方案比较 方案1 (性能还不错) 数据库直接存经纬 ...

  2. 实例分割:MaskXRCnn 与Visual Genome数据集

    一.VG数据集 机器学习领域的突破突然让计算机获得了以未曾有的高精度识别图像中物体的能力--几乎达到了让人惊恐的程度.现在的问题是机器是否还能更上层楼,学会理解这些图片中所发生的事件. Visual ...

  3. CNN结构:色彩空间建模-色彩空间分析

    原文: 色彩空间基础 好一个NB的知乎专栏:色彩空间基础 第一章:色彩空间基础 关于色彩分析,引出了专门的数学基础.整个过程给出了完备的数学阐述,虽然没有试验数据,论述的相当精彩. 摘抄出一段:  上 ...

  4. Postfix 故障记录

    1.postfix 目录/var/mail/USER文件大小限制报错 解决方式: 编辑 /etc/postfix/main.cf 文件添加以下内容 mailbox_size_limit = 51200 ...

  5. linq排序之 根据文本 A-001-002-003 这种类型进行分割排序 空值放于最后

    调用 List<string> data = new List<string>() { "D-001-001-001","A-001-004-00 ...

  6. 图的连通性问题之连通和最小环——Floyd算法

    Floyd 判断连通性 d[i][j]仅表示i,j之间是否联通 ;k<=n;k++) ;i<=n;i++) ;j<=n;j++) dis[i][j]=dis[i][j]||(dis[ ...

  7. uva 540 (Team Queue UVA - 540)

    又是一道比较复杂的模拟题.题中有两种队列,一种是总队列,从前向后.其他的是各个团体的小队列,因为入队的人如果有队友的话,会优先进入团体队列. 所以我们先设置两个队列和一个map,设置map倒是可以不用 ...

  8. Vue源码学习(二)——生命周期

    官网对生命周期给出了一个比较完成的流程图,如下所示: 从图中我们可以看到我们的Vue创建的过程要经过以下的钩子函数: beforeCreate => created => beforeMo ...

  9. 发现:Click事件也能获取鼠标单击的坐标

    按照MSDN的说明以及平时的习惯,我们要获取鼠标单击时的相对坐标,都会使用MouseClick等事件,今天,偶然发现,原来Click事件也可以. /* 惊天地泣鬼神的考古业绩. * 原来Cilck事件 ...

  10. Python OS & sys模块

    os模块(* * * *) os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname" ...