首页 > Oracle > Oracle buffer cache 理解之二。
2013
12-10

Oracle buffer cache 理解之二。

上一篇文章简单说了一下buffer cache的作用,这里简单回顾一下,oracle为了加快处理数据的速度,必须将读取过的数据缓存在内侧里,对这些缓存,oracle称之为db buffer cache,也就是通常我们所说的buffer cache,这个大小是有限制的,通过buffer_cache_size指定,实例一启动,就已经分配好空间。主要提供的功能:

1. 通过缓存数据块,减少IO

2. 通过构造CR块,提供读一致性功能

3. 提供lock,latch机制,从而多个进程可以并发访问同一个数据块

虽然在平时用着没感觉,但在oracle内部要实现这一功能还是需要很多管理过程的,其中最有名的两个就是:链表和hash算法。

所谓链表,就是一种数据结构,通过将对象串连在一起,构成链表结构。需要需要修改,删除,查找对象,都可以先从链表中去查找,就不用访问物理存储,在上一篇buffer cache说明中,也提到了LRU链表。

hash算法是为了进行快速查找定位的一种技术,读者可能就联想到了表之间的连接方式,其中有一种就是hash join,这里的hash算法也类似,就是根据要查找的值,然后对该值进行hash算法,等到该值所在的索引号,然后进入到该值应该存在的一列数值列表中,通过这个索引号去查找属于哪个列表,然后对该列表的值,一个一个进行比较,找到查找的值。这样就只需要扫描某个列表就可以了,不需要扫描所有的列表,效率就可以很多了。这里的索引号对应的数值列叫做hash bucket。

下面我们简单还看一下这个例子,比如我们的数值列表最多可以有10个元素,也就是10个bucket,每一个bucket最多可以保存20个数值,用简单的二维数组表示就是[10][20],假设hash算法是n MOD 10,这样数据就可以均匀的放在10个bucket里面,然后我们把1到100都通过这个hash算法放进bucket中,当查找53时,只要将53 MOD 10 = 3,就可以知道在3号bucket中去查找,也就是[3][20],3号bucket中有20个值,这样只需要和这20个值比较即可,这样就比扫描全部的bucket快了不少。

通过上面的简单例子,就很容易了解hash算法的效率了吧,当时实际的hash算法远不止上述所描述的。而buffer cache就是使用多个hash bucket来管理的,但实际上hash bucket只是逻辑上的一个概念而已,每一个bucket都是通过不同的hash chain体现出来的,这里就会出现一个latch,cache buffer chains latch就是用来管理并发操作的。在buffer cache中还有一个概念buffer header,当每一个数据块在被读入buffer cache的时候,都会先在构造一个buffer header,使其与数据块一一对应,在buffer header中包含如下主要信息:

1)该数据块在buffer cache中实际的内存地址。

2)该数据块的类型,包括data、segment header、undo header、undo block等等。

3)该buffer header所在的hash chain,是通过在buffer header里保存指向前一个buffer header的指针和指向后一个buffer header的指针的方式实现的。

4)该buffer header所在的LRU、LRUW、CKPTQ等链表(这些链表我们后面都会详细说明)。也是通过记录前后buffer header指针的方式实现。

5)当前该buffer header所对应的数据块的状态以及标记。

6)该buffer header被访问(touch)的次数。

7)正在等待该buffer header的进程列表(waiter list)和正在使用该buffer header的进程列表(user list)。

buffer cache中,默认的hash bucket数量有_db_block_hash_buckets觉得,各个版本缺省值不一致,这个show一下就可以看到当前版本的值。

这里对buffer cache又简单的说明了一下,在下一篇中将说明buffer cache怎样转储以及buffer转储文件的介绍。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL