HASH链表

HASH链表Oracle 内核技术揭密 吕海波学习笔记一 HASH 链表与逻辑读 oracle 要从高速缓冲区中拿到 5 号文件 1234 号块 buffer 的信息 就需要使用到 HASH 算法 BufferCache 高速缓冲区中包含多个 buffer 每一个 buffer 就记录一个数据块对应的缓冲信息 BufferHeader 每一个 BufferCache 都有一个 BufferHeader BH 它用来记录

Oracle内核技术揭密_吕海波  学习笔记

一,HASH链表与逻辑读

Bucket数量由隐藏参数_db_block_hash_buckets决定:

SQL> SELECT ksppinm, ksppstvl, ksppdesc FROM x$ksppi x, x$ksppcv y WHERE x.indx = y.indx AND ksppinm = '_db_block_hash_buckets'; KSPPINM KSPPSTVL KSPPDESC ---------------------- --------- ------------------------------------- _db_block_hash_buckets  Number of database block hash buckets

HASH链表
搜索buffer步骤如下:
1,进程根据要访问块的文件号和块号,计算HASH值得到到数字X。
2,根据HASH值X,定位到相应HASH Bucket,如BucketX。
3,搜索Bucket后的链表,查找哪个Buffer Header(BH)是目标BH。
4,找到目标BH后,从中取出Buffer的Buffer Address(BA)。
5,按BA访问Buffer












上述为oracle逻辑读的过程,如果搜索Bucket后的BH链表,没有找到包含目标块的BH,就说明目标块不在缓存中,只能物理读了。

二,catch buffer chain latch 与buffer pin 锁

 SGA是公共内存,因此在访问buffer时是需要锁保护机制的,oracle采用的锁机制是latch和mutex。

正常情况下一个bucket后面的catch buffer chain就需要一个catch buffer chain latch来保护,但latch也是占用空间的,于是oracle这里是一个CBC  latch负责多个bucket的锁管理。一个latch的大小为192字节:

SQL> select to_number(b.addr,'xxxxxxxxxxxxxxxxxxxxx')- to_number(a.addr,'xxxxxxxxxxxxxxxxxxxxx') from (select rownum rid,addr from v$latch_children where name='cache buffers chains' order by addr) a, (select rownum rid,addr from v$latch_children where name='cache buffers chains' order by addr) b where a.rid=b.rid+1 and rownum <=1; TO_NUMBER(B.ADDR,'XXXXXXXXXXXXXXXXXXXXX')-TO_NUMBER(A.ADDR,'XXXXXXXXXXXXXXXXXXXX -------------------------------------------------------------------------------- 192

HASH链表

当我们搜索CBC链表时,需要先获取CBC latch进行锁保护;当找到目标所在BH,访问buffer前要修改buffer pin进行锁保护,修改完buffer pin后就可以释放CBC latch ,后续的buffer访问只需要在buffer pin保护下进行即可;当访问完buffer需要释放buffer pin时,这时又需要CBC latch 来保护。CBC latch的功能就是保护CBC链的访问和buffer pin的修改。

buffer pin锁有多种模式,常见的为共享模式(S)和独占模式(X)。在没有加锁时buffer pin值为0。

CBC latch也有共享和独占两种模式,模式的选择取决于以下4个要素:

1)对象类型(唯一索引,非唯一索引等)

2)块类型(根块,叶块,表块等)

3)操作(读,修改)

4)访问路径

对于一般的逻辑读,我们在读取buffer信息前都需要修改buffer pin值,这时的CBC latch基本都是独占锁。步骤如下:

HASH链表

HASH链表

 HASH链表

 HASH链表

 当我们要访问索引的叶块时,需要频繁的访问它的根块和枝块,但对根块和枝块修改的频繁度又很低,这时没有必要使用独占模式的CBC latch。优化后的步骤如下:

HASH链表

 HASH链表

 HASH链表

HASH链表

 HASH链表

 HASH链表

 

 可以看到在CBC latch 共享模式中搜索CBC链表和访问buffer,中间没有修改buffer pin,也没有释放CBC latch,这样CBC latch的加载时间比独占模式要长,但它缓解了独占模式下的争用。

在有唯一索引、唯一索引扫描情况时,根块、枝块、叶块、表块都是使用共享模式的CBC latch。也就是说当唯一索引使用‘where  id = ?’这样的等值条件查询时,就使用共享模式的CBC latch;当使用的是范围查询时,则和非唯一索引一样,只有根块、枝块共享模式的CBC latch,不修改buffer pin,而叶块、表块还是使用独占模式的CBC latch。可以理解为使用索引唯一访问路径时,所有块的访问都是共享模式的CBC latch;另外,rowid方式直接逻辑读表块时是使用独占模式的CBC latch。

除了唯一索引外,在多数情况下,读或者写表块,都是使用独占模式的CBC latch。

另外根块和枝块,只要不修改,就使用共享模式的CBC  latch。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229895.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:37
下一篇 2026年3月16日 下午3:37


相关推荐

  • Linux运维常见面试题汇总

    Linux运维常见面试题汇总Linux面试题一、填空题1. 在Linux 系统中,以文件方式访问设备。2.Linux 内核引导时,从文件/etc/fstab中读取要加载的文件系统。3.Linux 文件系统中每个文件用indoe节点来标识。4. 全部磁盘块由四个部分组成,分别为引导块 、专用块 、 i 节点表块 和 数据存储块 。5. 链接分为:硬链接 和 符号链接 。

    2022年6月13日
    21
  • 关于struts2的error filterStart问题的解决

    关于struts2的error filterStart问题的解决eclipse下部署好项目启动的时候出现errorfilterStart错误,参考了网上的资料,发现很多人遇到。有一篇帖子帮到了我。是关于这个问题的总结。根据那个帖子的提示,我认为是我的tomcat安装路径的问题。我的tomcat安装在了d:\programfiles下,后来我将tomcat移到了D盘根目录下重新部署启动,问题就没有了。至于为什么会这样,那个帖子上有一个解释,但是我不是太明白。

    2022年7月11日
    21
  • pycharm安装中文包为什么老是失败_安卓安装包格式

    pycharm安装中文包为什么老是失败_安卓安装包格式PyCharm版本:PyCharm2020.21.打开PyCharm进入File->Settings…2.找到Plugins并点击(挥着在搜索框输入Plugins并选择Plugins菜单)3.在Marketplace的搜索框输入chinese4.可以看到Chinese(Simplified)LanguagePackEAP安装包,点击Install安装5.等待安装完成,点击RestartIDE重启IDE窗口6.选择Re

    2022年8月28日
    2
  • uint16t在那个头文件_uint16

    uint16t在那个头文件_uint16最近看代码里面涉及到unit8_t等数据类型,显然不是C原始数据类型,看名字猜测应该是使用typedef定义的。这样做主要是为了代码维护和移植时比较方便,比如C中没有bool,于是在一个软件中,一些程序员使用int,一些程序员使用short,会比较混乱,最好就是用一个typedef来定义,如:typedefcharbool;按照posix标准,一般整形对应的*_t类型为

    2025年12月13日
    8
  • Java输入输出(标准)

    Java输入输出(标准)简述Java输入就需要自己构造类了。其中nextLine()这个方法,表示的是,一直读,读到有换行符之后就截至(不取换行符)代码importjava.util.*;publicclassTest{publicstaticvoidmain(String[]args){Scannerin=newScanner(System….

    2022年5月15日
    40
  • Python: sklearn库中数据预处理函数fit_transform()和transform()的区别

    Python: sklearn库中数据预处理函数fit_transform()和transform()的区别敲 Python 机器学习及实践 上的 code 的时候 对于数据预处理中涉及到的 fit transform 函数和 transform 函数之间的区别很模糊 查阅了很多资料 这里整理一下 涉及到这两个函数的代码如下 从 sklearn preprocessin 导入 StandardScal preprocessin 标

    2026年3月17日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号