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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12020513/viewspace-620667/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle實驗記錄 (buffer_cache分析(2)cbc latch)Oracle
- oracle實驗記錄(buffer_cache分析(4)dbwr,lgwr,ckpt)Oracle
- oracle實驗記錄(buffer_cache分析(3)cbc lru chain latch)OracleAI
- oracle實驗記錄 (oracle 分析shared pool(1))Oracle
- oracle實驗記錄 (oracle 詳細分析redo(1))Oracle
- oracle實驗記錄 手工 duplicate database(1)OracleDatabase
- oracle實驗記錄Rman duplicate database(1)OracleDatabase
- oracle實驗記錄 (oracle 分析shared pool(2))Oracle
- oracle實驗記錄 (oracle 詳細分析redo(2))Oracle
- oracle實驗記錄 (oracle 詳細分析redo(3))Oracle
- oracle實驗記錄 (oracle 詳細分析redo(4))Oracle
- oracle實驗記錄 (oracle 詳細分析redo(5))Oracle
- oracle實驗記錄 (storage儲存引數(1))Oracle
- oracle實驗記錄 (恢復-rman維護(1))Oracle
- oracle實驗記錄 (oracle 10G dataguard(1)手工搭建)Oracle
- oracle實驗記錄 (oracle 10G 詳細分析undo)Oracle
- oracle實驗記錄 (flashback)Oracle
- oracle實驗記錄 (OMF)Oracle
- oracle實驗記錄 (NET)Oracle
- oracle實驗記錄 (audit)Oracle
- oracle實驗記錄 (oracle reset parameter)Oracle
- oracle實驗記錄 (恢復-rman reset incatnation(1))Oracle
- oracle實驗記錄 (恢復read only tablespace(1))Oracle
- oracle實驗記錄 (分析oracle硬解析&軟解析&fast soft parse)OracleAST
- Oracle Data Redaction實驗記錄Oracle
- oracle實驗記錄 (block cleanout)OracleBloC
- oracle實驗記錄 (dump undo)Oracle
- oracle實驗記錄 (inlist card)Oracle
- oracle實驗記錄 (oracle 資料字典)Oracle
- oracle實驗記錄 (cursor_sharing(1)exact&force)Oracle
- oracle實驗記錄 (恢復-關於控制檔案(1))Oracle
- oracle實驗記錄 (oracle b*tree index訪問Cost計算(1))OracleIndex
- oracle實驗記錄 (分析oracle硬解析&軟解析&fast soft parse(2))OracleAST
- Oracle檔案改名實驗記錄Oracle
- oracle實驗記錄 (選擇率)Oracle
- oracle實驗記錄 (dump logfile)Oracle
- oracle實驗記錄 (事務控制)Oracle
- oracle實驗記錄 (函式index)Oracle函式Index