在Orace BUFFER CACHE中,不仅包含了BLOCK BUFFER,还包含了BUFFER HEADER的控制结构。这种控制结构在内部文档中被命名为kcbbh。在Oracle 9i中,它占188个字节。但是知道它的结构体名字和字节大小对于性能优化的帮助并不大,所以我们几乎不用关注这个结构体(也无法改变这个结构体),但我们必须要知道BUFFER HEADER的一些相关知识点。 查看BUFFER HEADER主要有以下两种方法:
查询著名的内部视图X$BH(Buffer Headers)。这是大家最常使用的方法。
使用命令DUMP BUFFER CACHE。不同的DUMP LEVEL可以观察到不同的BUFFER HEADER内容,以下为DUMP BUFFER CACHE的语法:
ALTER SESSION SET EVENTS ‘immediate trace name buffers level n’;
1 buffer header
2 level 1 + block header
3 level 2 + block contents
4 level 1 + hash chain
5 level 2 + hash chain
6 level 3 + hash chain
8 level 4 + users/waiters
9 level 5 + users/waiters
10 level 6 + users/waiters
注意 当BUFFER CACHE中有很多数据块时,使用命令DUMP BUFFER CACHE可能会产生数GB大小的跟踪文件,默认情况下很容易导致ORACLE_BASE空间不足。此外在DUMP过程中还可能导致硬盘I/O的使用率达到100%,所以不建议在生产系统操作做类似的操作。一般情况下,推荐通过查询X$BH来观察系统中BUFFER HEADER的情况。
可以看到Oracle在BUFFER HEADER中保存了指向特定数据块的指针(BUFFER ADDRESS)。
在Oracle数据库中,组成数据文件的最小原子单位是数据块,在同一个数据库中可以有不同的BLOCK SIZE。与此类似,组成Oracle SGA的最小原子内存单位是GRANULE。一个GRANULE是一块连续的内存块。内部视图XKaTeX parse error: Unexpected character: '' at position 77: …数据库的GRANULE大小: ̲通过查看隐含参数_ksmg_g…SGAINFO获得。如下所示:
SQL> select * from v$sgainfo
2 where name=‘Granule Size’;
NAME BYTES RES
Granule Size 16777216 No
表8-1显示了不同GRANULE大小包含的数据块个数[ 该表摘自著名的Oracle专家Julian Dyke的《Sga internals》讲义。]。
表8-1 GRANULE大小
Block Size Buffers Per Granule
4mb 16mb
2048 1875 7503
4096 979 3916
8192 500 2002
16384 253 1012
32768 127 509
假设目前数据库的BLOCK SIZE大小为8KB,GRANULE大小为16MB,那么一个GRANULE可以包含16×1024×1024/(8192+188)=2002个BUFFER。
从Oracle 9i开始,Oracle允许存在不同数据块大小的BUFFER CACHE(分别用数据库参数DB_nK_CACHE_SIZE来设置),这也就意味着相同大小的GRANULE可以包含不同数量的数据块,但是对于DEFAULT BUFFER POOL、KEEP BUFFER POOL、RECYCLE BUFFER POOL,则只能使用默认的数据块大小。
提示 由于BUFFER CACHE的内存以BLOCK SIZE为单位,所以BUFFER CACHE不会出现大小无规律的内存碎片。