Oracle为了将物理IO最小化,把最近使用过的数据块保持在内存中。为了管理这些内存,oracle 使用如图的结构, Hash Chain的结构,Hash Chain位于共享池中,使用典型内存结构Bucket->Chain->Header结构进行管理。 Hash Chain结构的起点是Hash表,Hash表由多个hash bucket组成,块地址 是由file#+block#组成的,当扫描块时使用Hash函数 进行hash运算,使用hash值查找hash bucket,具有相同hash值的buffer haeder在hash bucket上以chain形式链接。 Buffer header有指向实际缓冲区的指针。注意:Hash Chain结构是在共享池中,而实际缓冲区信息存储在高速缓冲区中。 Hash Chain结构利用cache buffers chain Latch来保护。 当进程扫描特定的数据块时,必须获得相应数据块所在Hash Chain管理的cache buffers chain Latch。基本上 一个进程获得仅有的一个cache buffers chain Latch,一个cache buffers chain Latch管理多个Hash Chain。 当多个进程同时检索Buffer Cache时,获得cache buffers chain Latch的过程中发生争用,就会产生
cache buffers chain Latch等待事件。
进程扫描特定的数据块整个过程。
1、Oracle以每个块的文件号、块号和类型做HASH运算,得到HASH值。根据HASH值,到HASH表中取出指定块的内存地址
2、获取CBC Latch
3、根据HASH值,搜索CBC链表
4、根据DBA找到BH(Buffer Header)加Buffer Pin
5、加完Buffer Pin马上释放CBC Latch
6、访问Buffer开始fetch数据
7、获取CBC Latch
8、释放Buffer Pin
9、释放CBC Latch
create table t1(id int,name varchar2(10));
insert into t1 values(1,'xiaobo');
commit;
--获取t1表的第一行数据及ROWID,根据dbms_rowid包查出这行数据的文件号、块号
select rowid,
dbms_rowid.rowid_relative_fno(rowid) file#,
dbms_rowid.rowid_block_number(rowid) block#,
id,
name
6 from t1
7 ;
ROWID FILE# BLOCK# ID NAME
------------------ ---------- ---------- ---------- ----------
AAATv/AABAAArIJAAA 1 176649 1 xiaobo
--根据DBA获取CBC Latch的地址
select hladdr from x$bh where file#=1 and dbablk=176649;
SQL> select hladdr from x$bh where file#=1 and dbablk=176649;
HLADDR
----------------
0000000090E5ADF8
--根据CBC Latch的地址可以查出这个CBC Latch被获得的次数
select addr,name,gets from v$latch_children where addr='0000000090E5ADF8';
SQL> select addr,name,gets from v$latch_children where addr='0000000090E5ADF8';
ADDR
----------------
NAME GETS
---------------------------------------------------------------- ----------
0000000090E5ADF8
cache buffers chains 385767
--再次读取t1表的第一行数据,再次产生一次逻辑读
SQL>select id,name from t1 where rowid='AAATv/AABAAArIJAAA';
SQL> select id,name from t1 where rowid='AAATv/AABAAArIJAAA';
ID NAME
---------- ----------
1 xiaobo
--根据CBC Latch的地址可以查出这个CBC Latch被获得的次数
SQL> select addr,name,gets from v$latch_children where addr='0000000090E5ADF8';
ADDR
----------------
NAME GETS
---------------------------------------------------------------- ----------
0000000090E5ADF8
cache buffers chains 385772
Cache Buffer Chain Latch 实验
create table t_test as select * from dba_objects;
declare
c number;
begin
for i in 1 ..60000 loop
select count(*) into c from t_test ;
end loop;
end;
/
select x.ksppinm name,
y.ksppstvl value,
y.ksppstdf isdefault,
decode(bitand(y.ksppstvf, 7),
'MODIFIED',
'SYSTEM_MOD',
'FALSE') ismod,
decode(bitand(y.ksppstvf, 2), 2, 'TRUE', 'FALSE') isadj
from sys.x$ksppi x, sys.x$ksppcv y
where x.inst_id = userenv('Instance')
and y.inst_id = userenv('Instance')
and x.indx = y.indx
and x.ksppinm like '%db_block_hash%'
order by translate(x.ksppinm, ' _', ' ');
网友评论