Buffer cache学习(三)

Buffer cache学习(二)

2.6:现在再回过头,看看怎样查找BUFFER CACHE看看数据是否已经存在? 

(Y)  如果数据在BUFFER CACHE中存在的情况。 

1) 根据要查找的数据块的DBA等信息,通过上面给的HASH算法( Hash Bucket = MOD(Data 

Block Address, _DB_BLOCK_HASH_BUCKETS) ),得到该数据块所在的Hash Bucket。 

2)定位到对应的Hash Bucket上,在该Hash Bucket对应的Cache Buffers Chain中加上Cache Buffers Chains Latch,然后从Cache Buffers Chain对应的第一个Buffer Header开始扫描查找,直至之后一个。在这个扫描查找过程中,为防止对Cache Buffers Chain并发访问,将一直持有Cache Buffers Chains Latch。 在Cache Buffers Chain上查找的具体逻辑如下: 

1.比较Buffer Header上所记录的Block地址,不符合条件跳过此Buffer Header

 2.跳过status为cr的Buffer Header 

3.如果Buffer Header状态为reading则等待,直到状态改变后比较Buffer Header 记录的Block地址是否符合 

4.若发现Block地址符合的Buffer Header,查该Buffer Header是否位于正在使用的list上,如果是,则判断已存在的lock mode,与要求的lock mode是否兼容,如果兼容则返回该Buffer Header中记录的Buffer地址,将当前process id放入Buffer Header 所处的正在使用的list上 

5.如果lock mode不兼容,用Buffer Header所指向的Buffer中的内容构建一个xcurrent的Buffer 和一个cr状态的Buffer Header(指向新建立xcurrent状态的复制Buffer)

6.搜索完整个Hash Chain还未发现需要的Buffer Header,从disk读取datafile,读入到Buffer Cache中 相应的Buffer Header 挂在Hash Chain上 附: 

 

Buffer Header指向Buffer的6种状态:  

(可以参照v$bh的STATE) 

1.free =可以被重用的block 

2.xcurrent=已EXCLUSIVE方式获取的当前模式的block(insert,update,delete时产生),scurrent=可以与其他instance共享的当前模式block 

3.cr=一致读块,永远不会写入disk 

4.reading=正从disk读取出来的块

5.mreciver=正在进行介质恢复的block 

6.ircovery=正在进行instance recovery的block

3) 获得第2)步中查到的可以直接访问的Buffer Header或者构造一致性读后的Buffer 

Header中的Buffer地址到Buffer Memory来获得数据。  

 

2.7:

如果上面在Hash Chain中查找不到对应的Buffer Header的情况下,也就前面的问题的第二种情况: 

(N) 如果数据在BUFFER CACHE中不存在,则需要从数据文件中读取数据块到BUFFER CACHE中去。这个时候,需要查找在BUFFER CACHE中寻找足够的内存空间来读取相关的数据。 

再看看前面给的BUFFER CACHE示例图: 可以看到2条链(LRU和LRUW),这2条分别将Buffer Header连接起来,和Cache Buffers Chain类似。下面看看这2条链的作用: 

1) LRU表示Least Recently Used,也就是指最近最少使用的Buffer Header链表。LRU链表串连起来的Buffer Header都指向可用数据块(Free Buffer)。

2)  LRUW则表示Least Recently Used Write,也叫做Dirty List,也就是脏数据块链表,LRUW串起来的都是修改过但是还没有写入数据文件的内存数据块所对应的Buffer Header(Dirty Buffer)。

3) 一个数据块要么在lru要么lruw,不能同时存在

 

所以,当前面查找数据在BUFFER CACHE中不存在的时候(即在Hash Chain中查找不到对应的Buffer Header的情况下)就要扫描LRU List寻找Free的Buffer,在扫描过程将持有Cache Buffers Lru Chain Latch(其Latch数量由隐含参数_db_block_lru_latches决定)。扫描过程中会把已经被修改过的Buffer移动到LRUW列表上

总的在BUFFER CACHE中查找数据,可以简单的表示为下图


通常有2种情况或导致Latch出现竞争: 

1) 某一进程长时间的持有Latch,导致其他进程不能正常的得到Latch,只能等待。

2) 可能存在大量的Latch请求。

 

如果出现Cache Buffers Chains Latch竞用严重,根据前面的原理,那么可能有如下原因: 

1) 当多个会话重复访问一个或多个由同一个子Cache Buffers Chains Latch保护的块时热点

块(可以关注X$BH中的TCH字段)。 

2) 大量并发执行的低效SQL。低效的SQL通常需要获取大量的逻辑读,而得到一次逻辑IO就得获得一次Cache Buffers Chains Latch。 

3) Hash Bucket中存在长的Cache Buffers Chains,导致查询数据时候,长时间持有Latch。 

 

如果出现Cache Buffers Lru Chain Latch竞用严重,那么可能有如下原因:

 1) 可能BUFFER CACHE分配的空间不够,导致读数据到BUFFER CACHE的时候,不断的扫描LRU List。


热块产生原因不同,按照数据块类型---

1)表数据块

OLTP系统,对一些小表会有频繁的查询和修改,频繁访问数据块会变成热块,导致内存中latch争用。

如果表不太大,可以考虑把表数据分布到更多数据块上,但是会降低系统性能,即读取相同的数据需要读取更多地数据块。

2)索引数据块

一个表的主键是序列产生的,当RAC不同实例向表插入主键时,会出现索引块在不同实例被调用。

可以考虑反向索引,但是range scan不能很好的使用。

3)索引根数据块

当用户频繁访问根/枝的几个数据块,可以考虑分区,使这些根枝数据块分布到不同的分区上,减少数据块并行访问密度。

4)段头数据块

9i之前数据段由free list管理,10g自动段管理ASSMORACLE使用位图管理。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值