oracle查看buffer内容,oracle实验记录 (buffer_cache分析(1))

buffer cache中获取block 过程

DML or select时候 oracle根据 SQL语句执行计划,找到block,构造一个 叫buffer descriptor的block描述内存的结构(主要含block 物理地址 ,type,object id),这个block存在 session的 pga中,oracle应用buffer descriptor记录的信息 运用hash算法,得到需要的block所在的hash bucket(确定block在哪条hash chain上),从 上面 挂的 第一个buffer header搜索到最后一个buffer header,

hash chain上 搜索逻辑 :

1.比较buffer header 上所记录的block地址,不符合条件SKIP 此buffer header

2.skip status为cr的buffer header

3.如果buffer header状态为 reading则等待,直到状态改变后比较buffer header 记录的block地址是否符合

4.若发现block地址符合的buffer header,查该buffer header是否位于正在使用的list上,如果是 则判断已存在的lock mode,与要求的lock mode是否兼容,如果兼容则返回该buffer header中记录的block地址,将当前process id放入buffer header 所处的正在使用的list上

5.如果lock mode不兼容,用buffer header所指向的block中的内容构建一个xcurrent的block 和一个cr状态的buffer header(指向新建立xcurrent状态的 复制block)

6.搜索完整个hash chain还未发现需要的buffer header,从disk读取datafile,读入到buffer cache中 相应的buffer header 挂在hash chain上

buffer cache指向block的状态分6种

1.free =可以被重用的block

2.xcurrent=已EXCLUSIVE方式获取的当前模式的block(insert,update,delete时产生),scurrent=可以与其他instance共享的当前模式block

3.cr=一致读块,永远不会写入disk

4.reading=正从disk读取出来的块

5.mreciver=正在进行介质恢复的block

6.ircovery=正在进行instance recovery的block

SQL> select distinct status from v$bh;

STATUS

-------

xcur

free

cr

buffer header

在buffer cache中,每一个block读入 buffer cache时,都会在buffer cache中构造一个buffer header(buffer header与block一一对应)

1.存放该block在buffer cache中实际存储地址

2.存放该block的类型(data,segment header,undo header,undo block等类型)

3.由于此buffer header 所在的hash chain,是通过在buffer header保存指向前一个buffer header的指针和指向后一个buffer header的指针方式实现,所以还存指针

4.存储lru,lruw,ckptq,fileq等队列,一样是通过记录前后buffer header指针方式实现

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

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

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

bucket 与cache buffers chains latch

oracle通过bucket管理buffer cache ,oracle用hash算法将不同的buffer分配到bucket中,当需要定位需要的buffer是否在buffer cache中时,用同样的hash 算法 到相应的bucket上 搜索对应的buffer header既可 bucket 中buffer header通过cache buffer chains连接(双向链表)

查 buffer 中 默认 hash bucket数量既有多条hash chain

SQL> set linesize 132

SQL> column name format a30

SQL> column value format a25

SQL> select

2    x.ksppinm  name,

3    y.ksppstvl  value,

4    y.ksppstdf  isdefault,

5    decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE')  ismod,

6    decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE')  isadj,x. KSPPDESC

7  from

8    sys.x$ksppi x,

9    sys.x$ksppcv y

10  where

11    x.inst_id = userenv('Instance') and

12    y.inst_id = userenv('Instance') and

13    x.indx = y.indx and

14    x.ksppinm like '%_&par%'

15  order by

16    translate(x.ksppinm, ' _', ' ')

17  /

输入 par 的值:  db_block_hash

原值   14:   x.ksppinm like '%_&par%'

新值   14:   x.ksppinm like '%_db_block_hash%'

NAME                           VALUE                     ISDEFAULT ISMOD      IS

ADJ

------------------------------ ------------------------- --------- ---------- --

---

KSPPDESC

--------------------------------------------------------------------------------

----------------------------------------------------

_db_block_hash_buckets         65536                     TRUE      FALSE      FA

LSE

oracle一直在优化hash buckets数目 因为 hash bucket 越多,存放的buffer header越分散(但bucket太多的话对空间,管理 都有压力) 对于cache buffer chain latch争用越少

查看buffer header结构

SQL> create table t1 (a char(2000), b char(2000), c char(2000));

表已创建。

SQL> insert into t1 values ('a','a','a');

已创建 1 行。

SQL> insert into t1 values ('b','b','b');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select header_file,header_block,owner from dba_segments where segment_name=

'T1';

HEADER_FILE HEADER_BLOCK OWNER

----------- ------------ ------------------------------

4         1115 XH

SQL>  select file#,block# ,rowid from (select dbms_rowid.rowid_relative_fno(rowi

d) file#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from T1);

FILE#     BLOCK# ROWID

---------- ---------- ------------------

4       1117 AAAMm+AAEAAAARdAAA

4       1118 AAAMm+AAEAAAAReAAA

SQL> select object_id,data_object_id from user_objects where object_name='T1';

OBJECT_ID DATA_OBJECT_ID

---------- --------------

51646          51646

SQL> select file#,block#,status,class# from v$bh where bjd=51646;

FILE#     BLOCK# STATUS      CLASS#

---------- ---------- ------- ----------

4       1118 xcur             1

4       1113 xcur             8

4       1116 xcur             1

4       1119 xcur             1

4       1114 xcur             9

4       1117 xcur             1

4       1120 xcur             1

4       1115 xcur             4

SQL>

SQL> alter session set events 'immediate trace name buffers level 1';

会话已更改。

1.dump buffer header

2.1+block header

3.2+block内容

4.dump buffer header & hash chain

5.1+dump block header &hash chain (1+4)

6.2+dump block header &hash chain (2+4)

8.dump buffer header & hash chain+ user list+waiter list

9.1+dump block header & hash chain+ user list+waiter list

10.2+dump block内容+hash chain+ user list+waiter list

BH (15FEB49C) file#: 4 rdba: 0x0100045b (4/1115) class: 4 ba: 15CF6000

set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 239

dbwrid: 0 obj: 51646 objn: 51646 tsn: 4 afn: 4

hash: [2019a6a0,2019a6a0] lru: [15feb5a0,15feb440]

ckptq: [15feb364,183eb414] fileq: [15feb36c,183eb41c] objq: [1eb25148,15feb494]

st: XCURRENT md: NULL tch: 4

flags: buffer_dirty gotten_in_current_mode redo_since_read

LRBA: [0xb.22ea.0] HSCN: [0x0.d1044] HSUB: [1]

..................................

BH (15FEABAC) file#: 4 rdba: 0x01000460 (4/1120) class: 1 ba: 15CDC000

set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 239

dbwrid: 0 obj: 51646 objn: 51646 tsn: 4 afn: 4

hash: [201a8d38,201a8d38] lru: [15feacb0,163f3840]

ckptq: [1a3f8304,15feac84] fileq: [2025c878,15feac8c] objq: [15fead04,1eb25148]

st: XCURRENT md: NULL tch: 2

flags: buffer_dirty gotten_in_current_mode redo_since_read

LRBA: [0xb.2300.0] HSCN: [0x0.d1044] HSUB: [1]

...............................

在buffer cache中 一共可以找到 (select file#,block#,status from v$bh where bjd=51646;)对应的所有buffer header

分析:

hash: [2019a6a0,2019a6a0]  就是指向前一个buffer header的指针 和 指向后一个buffer header的指针,x$bh中 NXT_HASH

PRV_HASH,例中两个值相等表示这个hash chain上只有一个buffer header

lru: [15feb5a0,15feb440] x$bh中 nxt_repl,prv_repl,lru上的下一个buffer和 上一个buffer,ckptq,fileq都是buffer修改后 使用的队列

可以看出buffer header就是一个双向链表组成

class:表示buffer header对应block的类型,1=data block,2=sort block,3=save undo block,4=segment header,5=save undo header,6=free list,7=extent map,

8=1st level bmb;9=2nd level bmb;10=3rd level bmb;11=bitmap block;12=bitmap index block;13=unused;14=undo header;15=undo block。

对应v$bh中class#

rdba:buffer header对应的 块地址

SQL> variable file# number;

SQL> variable blk# number;

SQL> execute :file#:=dbms_utility.data_block_address_file(to_number('1000460','x

xxxxxx'));

PL/SQL 过程已成功完成。

SQL> execute :blk#:=dbms_utility.data_block_address_block(to_number('1000460','x

xxxxxxx'));

PL/SQL 过程已成功完成。

SQL> print file#

FILE#

----------

4

SQL> print block#

SP2-0552: 未声明绑定变量 "BLOCK#"。

SQL> print blk#

BLK#

----------

1120

另外可以 rdba: 0x01000460 ,100前3位代表file#,0460代表block#

SQL> select to_number('100','xxxx') file#,to_number('0460','xxxxxx') block# f

dual;

FILE#     BLOCK#

---------- ----------

256       1120

整体buffer header内容 对应 x$bh,v$bh

你可能感兴趣的:(oracle查看buffer内容,oracle实验记录 (buffer_cache分析(1)))