ITPub博客

首页 > 数据库 > Oracle > BUFFER CACHE

BUFFER CACHE

原创 Oracle 作者:litterbaby 时间:2007-04-01 11:11:38 0 删除 编辑

BUFFER CACHE

[@more@]

BUFFER CACHE

数据缓存区的目的是减少磁盘IO的数量,因为数据是驻留在磁盘上,而我们在访问处理数据的时候,需要将被经常性访问的数据缓存在内存中,因为访问内存要远比访问磁盘快的多,但是数据缓存区是有限的,不可能所有的数据都放到这里面,这就要求数据库能够使用一种算法优化,来确定那些数据能够长时间放置在数据缓存区中,那些就要抛出出缺。

数据缓存区的使用有以下的好处:

1、 能够提供更加快速的访问数据库块的一种访问方式。

2、 提供了一种处理同步块的改变请求的策略。

3、 保存数据库块的一致读的多版本(多版本一致性)。

4、 通过内部的结构维护数据缓存。

基础的概念:

Hash buckets是一个结构,维护这数据缓存头的列表,是有相关的rdba和类号来分类;

Hash chain是在一个hash bucket上的一个数据缓存头的列表。

LRU:是一种机制,用于确定在搜索空闲的缓存的时候,哪一个缓存能够被使用。

缺省的hash bucket数目是:DB_BLOCK_BUFFERS*2

通过设置参数_DB_BLOCK_HASH_BUCKETS能够重写hash bucket数目

每一个HASH BUCKET包含这一个缓存头的一个链,

每一个hash bucket有一个cache buffers chains latch来保护对这个链的同步访问。

这几个概念说这相对比较复杂,解释一下,这里还有一个缓存内存区域,这个是存放数据的物理位置,在上面有几个结构:

Hash bucket

Buffer header

其中Hash bucket的数目是通过参数设置的,之所以使用这个概念,主要是才查找缓存的数据的时候能够更快找到所需要的数据的地址。而在Hash bucket这个结构中有一个链,这个链是有Buffer header组成,在Buffer header这个结构上有指向存放数据具体位置的指针地址。在查找数据的时候,数据库通过hash算法确定是有哪一个Hash bucket来存放所需要的Buffer header,在通过Buffer header上的buffer address来确定具体数据存放的位置。

还有两个链,LRU和LRUW,这两个链也是通过Buffer header上的LRU chain的指针来实现的,每一个Buffer header只有一个LRU chain指针,这也就是为什么同一个块不能同时存放在LRU和LRUW的原因了。

在这里我们可以看到,这里组成了一个二维的一个网状的一个链网,这个联网相互交叉,在LRU和LRUW其实只是一个虚拟的一个链,是有Buffer header来实现,Hash bucket目的是实现数据地址的快速查找,但是LRU和LRUW是找到相应的各自的功能,Oracle就是通过这样的设计来实现一种物理结构实现两种不同的功能。

缓存池有三种:

缺省

Keep

Recycle

用法:

将大的数据段放置在recycle缓存中,将小的,经常使用的段放置在keep池中。

可以通过查看以下的视图来查看段级的统计(oracle9i2)

-v$segstat_name

-v$segstat

-v$segment_statistics

LRU:

通常LRU是有两个列表组成:

LRUW(LRU写列表,也称为葬列表),是为了维护当前脏的缓存。LRU就维护剩下的缓存了。

使用初始化参数DB_BLOCK_LRU_LATCHES来设置多LRU列表,这个参数只是用于多CPU机器上。每一个LRU列表是由一个cache buffers lru chain latch来进行保护。

每一个LRU是有一个LRU和LRUW组成,被称为working set。缓存是通过一种循环机制来指定working set的。在使用working set的时候,进程将尝试所有的latch直到找到一个请求的LRU latch。在多DBWR进程的情况下,每一个DBWR将管理各自的LRU集。

配置多DBWR是通过设置参数 DB_WRITE_PROCESSES来实现。

缺省的working set数目是有DBWRs×缓存池的最大数目确定的,这些latch能够在每一个池的working set中间分布。

使用缓存的用户:

数据块读是有一个前台的Oracle进程来实现的,这个进程读数据块到缓存中然后做标志来改变,也就是说,在从磁盘中读取数据块是由Oracle的服务器进程来进行操作的,和用户进程无关,也就是说这一部分是由Oracle自己来进行管理的。

而数据块写则是由后台Oracle进程(DBWR)来实现的。DMWR进程将已经被修改的数据块写入到磁盘中。

获取当前数据的步骤

1、 通过所要查找的RDBA地址,通过hash算法,得到一个hash值,而这个hash值是和hash bucket相对应,而每一个hash bucket后面连接一个hash链,然后在通过扫描这个hash链来找到相应的地址。

2、 在链上查找可以使用的缓存或者从磁盘上读。

在链上查找有以下的原则:

n 忽略和RDBA不相匹配的缓存块

n 等待reading buffer,然后返回

n 跳过CR(一致性读)的buffer

n 如果CUR(当前)buffer被一个兼容的模式把持着,就使用

n 如果所有的其他用户是CR状态,

n 如果在缓存中没有这个buffer,则从磁盘中读取

3、 将状态对象附加在缓存头上。

4、 返回数据存放区域的指针。

这里介绍的是如何从一个RDBA地址上找到当前数据缓存的位置。

Buffer管理

Buffer被hash是初始化到LRU-AUX列表上

写的优先级

写的优先级被分成三种:高,中,低

每一个写操作被赋予一个优先级:

Type of Write

Priority

Tablespace checkpoints

Low

User initiated checkpoints

Low

Cold dirty buffers (aging)

Medium

Incremental checkpoints

Medium

Media recovery checkpoints

Medium

Instance recovery checkpoints

High

Thread CKPT

High

Ping

High

Working set和DBWR

DBWR进程工作在指定的Working set,Working set工作是在一个循环机制上运行的。

DBWR进程写的几个原因:

n 需要空闲的空间

n Checkpoint

n Ping写

n 清除不常用的脏buffer

在Oracle8i之前,DBWR是由于超时或者由于前台调用才会被初始化,而且每一种是有不同的类型的。而在此之后,所有的请求都所是有单一的请求来实现。

DBWR是由前台进程调用,用于清除脏的buffer,扫描的深度

Checkpoint是用于保证记录在日值中的所有的数据块都被写入到磁盘中。检测点的结构:

Checkpoint SCN

Checkpoint RBA

分配给checkpoint的线程

Timestamp

线程位图使能

检测点和文件队列

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/222350/viewspace-907892/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    131
  • 访问量
    465725