没有合适的资源?快使用搜索试试~ 我知道了~
oracle_buffer_cache深入分析
需积分: 16 8 下载量 22 浏览量
2012-06-25
22:20:25
上传
评论
收藏 486KB PDF 举报
温馨提示
试读
21页
本文首先详细介绍了oracle中buffer cache的概念以及所包含的内存结构。然后结合各个后台进程(包括DBWRn、CKPT、LGWR等)深入介绍了oracle对于buffer cache的管理机制,并详细解释了oracle为什么会采用现在的管理机制,是为了解决什么问题。比如为何会引入touch次数、为何会引入增量检查点等等。最后全面介绍了有关buffer cache监控以及调优的实用方法。
资源推荐
资源详情
资源评论
本文首先详细介绍了 oracle 中 buffer cache 的概念以及所包含的内存结构。然后结合各个
后台进程(包括 DBWRn、CKPT、LGWR 等)深入介绍了 oracle 对于 buffer cache 的管理
机制,并详细解释了 oracle 为什么会采用现在的管理机制,是为了解决什么问题。比如为
何会引入 touch 次数、为何会引入增量检查点等等。最后全面介绍了有关 buffer cache 监控
以及调优的实用方法。
1. buffer cache 的概念
用最简单的语言来描述 oracle 数据库的本质,其实就是能够用磁盘上的一堆文件来存储数
据,并提供了各种各样的手段对这些数据进行管理。作为管理数据的最基本要求就是能够保
存和读取磁盘上的文件中的数据。众所周知,读取磁盘的速度相对来说是非常慢的,而内存
相对速度则要快的多。因此为了能够加快处理数据的速度,oracle 必须将读取过的数据缓存
在内存里。而 oracle 对这些缓存在内存里的数据起了个名字:数据高速缓存区(db buffer
cache),通常就叫做 buffer cache。按照 oracle 官方的说法,buffer cache 就是一块含有
许多数据块的内存区域,而这些数据块主要都是数据文件里的数据块内容的拷贝。通过初始
化参数:buffer_cache_size 来指定 buffer cache 的大小。oracle 实例一旦启动,该区域大
小就被分配好了。
buffer cache 所能提供的功能主要包括:
1) 通过缓存数据块,从而减少 I/O。
2) 通过构造 CR 块,从而提供读一致性功能。
3) 通过提供各种 lock、latch 机制,从而提供多个进程并发访问同一个数据块的功能。
2.buffer cache 的内存结构
2.1 buffer cache 概述
oracle 内部在实现其管理的过程中,有两个非常有名的名词:链表和 hash 算法。
链表是一种数据结构,通过将对象串连在一起,从而构成链表结构。这样,如果要修改、删
除、查找某个对象的话,都可以先到链表中去查找,而不必实际的访问物理介质。oracle
中最有名的链表大概就是 LRU 链表了,我们后面会介绍它。
而 hash 算法则是为了能够进行快速查找定位所使用一种技术。所谓 hash 算法,就是根
据要查找的值,对该值进行一定的 hash 算法后得出该值所在的索引号,然后进入到该值应
该存在的一列数值列表(可以理解为一个二维数组)里,通过该索引号去找它应该属于哪一
个列表。然后再进入所确定的列表里,对其中所含有的值,进行一个一个的比较,从而找到
该值。这样就避免了对整个数值列表进行扫描才能找到该值,这种全扫描的方式显然要比
hash 查找方式低效很多。其中,每个索引号对应的数值列在 oracle 里都叫做一个 hash
bucket。
我们来列举一个最简单的 hash 算法。假设我们的数值列表最多可以有 10 个元素,也就
是有 10个 hash buckets,每个元素最多可以包含 20个数值。则对应的二维数组就是 t[10][20]。
我们可以定义 hash 算法为 n MOD 10。通过这种算法,可以将所有进入的数据均匀放在 10
个 hash bucket 里面,hash bucket 编号从 0 到 9。比如,我们把 1 到 100 都通过这个 hash
函数均匀放到这 10 个 hash bucket 里,当查找 32 在哪里时,只要将 32 MOD 10 等于 2,
这样就知道可以到 2 号 hash bucket 里去找,也就是到 t[2][20]里去找,2 号 hash bucket
里有 10 个数值,逐个比较 2 号 hash bucket 里是否存在 32 就可以了。
buffer cache 就是使用多个 hash bucket 来管理的,其 hash 算法当然比我们前面列举的
要复杂多了。
我们先来看下面这个图一。这副图从逻辑上说明了整个 buffer cache 的结构是怎么样的。这
副图的右
上角列出了三个名词:hash bucket、buffer header 和 hash chain。
这里的 hash bucket 就是我们前面说明 hash 算法中提到的二维数组的第一维。它是通过
对 buffer header
里记录的数据块地址和数据块类型运用 hash 算法以后,得到的组号。
这里的 hash chain 就是属于同一个 hash bucket 的所有 buffer header 所串起来的链表。实
际上,hash
bucket 只是一个逻辑上的概念。每个 hash bucket 都是通过不同的 hash chain 而体现出来
的。每个 hash chain 都会由一个 cache buffers chains latch 来管理其并发操作。
而对于 buffer header 来说,每一个数据块在被读入 buffer cache 时,都会先在 buffer cache
中构造一个 buffer header,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 的数量或者说缺省有多少条 hash chain 链表,是由
一个隐藏参数:
_db_block_hash_buckets 决定的。置于该参数的取值,在我的测试中,8i 下,该参数缺省
为 db_block_buffers×2;但是到了 9i 以后,该参数似乎取的是小于且最接近于
db_block_buffers×2 的素数。
2.2 转储 buffer cache
就象实例中的其他内存结构一样,oracle 提供了可以将 buffer cache 转储到跟踪文件的方法。
方法如下:
ALTER SESSION SET EVENTS 'immediate trace name buffers level level';
这里的 level 有很多值,分别可以转储 buffer cache 中的不同的内容。level 的可选值包括:
1 只转储 buffer header
2 在 level 1 的基础上再转储数据块头
3 在 level 2 的基础上再转储数据块内容
4 转储 buffer header 和 hash chain
5 在 level 1 的基础上再转储数据块头和 hash chain
6 在 level 2 的基础上再转储数据块内容和 hash chain
8 转储 buffer header 和 hash chain 以及 users/waiters 链表
9 在 level 1 的基础上再转储数据块头、hash chain 以及 users/waiters 链表
10 在 level 2 的基础上再转储数据块内容、hash chain 以及 users/waiters 链表
我们创建一个简单的测试表,然后看看转储出来的 buffer header 是什么样子的。
SQL> create table buffer_test(id number);
SQL> select object_id from dba_objects where object_name='BUFFER_TEST';
OBJECT_ID
----------
7087
SQL> insert into buffer_test values(1);
SQL> commit;
这时我们知道 buffer_test 表的 object_id 是 7987,同时,该表中只有 2 个 block 具有数据。
1 个是 segment header,另一个就是实际存放了 1 这个值的数据块。接着我们把 buffer
header 转储出来:
SQL> ALTER SESSION SET EVENTS 'immediate trace name buffers level 1';
到 user_dump_dest 所定义的目录下,找到跟踪文件并打开,可以看到类似下面的信息,
这里我们列出前两个 buffer header 以及我们建立的 object_id 为 7087 的 buffer_test 表所对
应的 buffer header 的内容:
BH (0x637F0720) file#: 1 rdba: 0x004011ed (1/4589) class 1 ba: 0x63570000
…………………………………
hash: [64be8000,65a5eab4] lru: [637f06ac,637f0824]
LRU flags: moved_to_tail
ckptq: [NULL] fileq: [NULL]
…………………………………
BH (0x64BE8000) file#: 0 rdba: 0x00000000 (0/0) class 0 ba: 0x64800000
…………………………………
hash: [65a5eab4,637f0720] lru: [64be8104,65aa3f0c]
…………………………………
BH (0x63BEC0A0) file#: 6 rdba: 0x0180b00a (6/45066) class 1 ba: 0x638B0000
set: 3 dbwrid: 0 obj: 7087 objn: 7087
hash: [65a9ccd4,65a9ccd4] lru: [63bec1a4,63bec02c]
ckptq: [65abceb4,63bec66c] fileq: [65abcfbc,63becd10]
st: XCURRENT md: NULL rsop: 0x00000000 tch: 1
flags: buffer_dirty gotten_in_current_mode redo_since_read
LRBA: [0xe9.229.0] HSCN: [0x0000.00122967] HSUB: [1] RRBA: [0x0.0.0]
BH (0x63BECAE8) file#: 6 rdba: 0x0180b009 (6/45065) class 4 ba: 0x638CC000
set: 3 dbwrid: 0 obj: 7087 objn: 7087
hash: [65a9cbcc,65a9cbcc] lru: [63becbec,63beca74]
ckptq: [637fc250,63becdc4] fileq: [65ab8ad0,63becdcc]
st: XCURRENT md: NULL rsop: 0x00000000 tch: 2
flags: buffer_dirty gotten_in_current_mode redo_since_read
LRBA: [0xe9.21b.0] HSCN: [0x0000.00122965] HSUB: [1] RRBA: [0x0.0.0]
…………………………………
剩余20页未读,继续阅读
资源评论
damofeishawm
- 粉丝: 1
- 资源: 12
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功