探究隱含引數_fairness_threshold
首先說明_fairness_threshold引數僅在RAC環境下才有意義,讓我對這個引數引起關注是在某一次查詢v$cr_block_server時,發現該檢視有一個名為FAIRNESS_DOWN_CONVERTS的欄位,官方文件裡將其解釋為:Number of times an instance receiving a request has down-converted an X lock on a block because it was not modifying the block
該引數相關效能指標在AWR的"Global CR Served Stats"章節裡也有出現:
根據我的理解,將FAIRNESS_DOWN_CONVERTS的含義翻譯為:RAC環境下的例項A對某個block在buffer cache里加上了Exclusive鎖,但例項A此時並沒有在修改該block,例項B請求從例項A的buffer cache裡讀訪問這個block,例項A接收到請求後先將這個block上的Exclusive鎖降級轉換後再傳輸給例項B,降級轉換一次,FAIRNESS_DOWN_CONVERTS值就+1。
要完全理解上述概念,我們至少需要搞清楚以下幾個問題:
1、例項B為何要從例項A的buffer cache裡訪問這個block?
2、例項A既然沒有在修改這個block,為何會對block持有Exclusive鎖?
3、鎖降級轉換目的在於?是否每一次跨例項傳輸block前都需要先進行鎖降級轉換?
逐個問題進行解答:
1、例項B為何要從例項A的buffer cache裡訪問這個block?
RAC裡所有例項的buffer cache透過高速專網進行互聯,Cache Fusion機制將各例項的buffer cache在邏輯上聚合成一個整體,當某個例項要訪問的block已被其它例項訪問過且仍保留在那個例項的bffer cache裡時,只要block的內容能夠滿足請求例項的訪問要求,該block就會透過高速專網從持有例項的buffer cache傳輸到請求例項的buffer cache裡,避免了請求例項從磁碟進行讀取。這之中有一個重要前提必須滿足,那就是保證持有例項block的內容是適合傳輸給請求例項的。換而言之,例項A要讀取的block在例項B的buffer cache裡,但若例項B Buffer cache裡的內容是N久之前的版本,這時例項A就只能從磁碟讀取了,異或者例項C的Buffer Cache擁有該block的較新版本,那麼例項A就會捨棄例項B和磁碟而從例項C讀取。如何為例項A選擇最為合適的資料來源,確保其能快速得到準確的查詢結果?一切盡在Global Resource Directory,簡稱GRD,只在RAC裡才有的GRD其實就是SGA裡的一塊記憶體區域存放內容包括了Global enqueue resource和Global cache resources,每個例項buffer cache裡的block就屬於global cache resource,每個block都有自己的master node,master node上的GRD裡準確記錄了這個block版本生成時的SCN、各節點持有的block鎖型別等資訊,可以透過gv$ges_resource檢視檢視block的master node是那個,比如對於scott.t0820_1表所在的block 6/255,其master_node為例項1:
select dbms_rowid.rowid_relative_fno(rowid) rfno,dbms_rowid.rowid_block_number(rowid) blkno from scott.t0820_1;
RFNO BLKNO
---------- ----------
6 255
select to_char(6,'xxx'),to_char(255,'xxx') from dual;
TO_C TO_C
---- ----
6 ff
select inst_id,resource_name,ON_GRANT_Q,ON_CONVERT_Q,master_node from gv$ges_resource where resource_name like '[0xff][0x6],[BL]%';
INST_ID RESOURCE_NAME ON_GRANT_Q ON_CONVERT_Q MASTER_NODE
---------- ------------------------------ ---------- ------------ -----------
1 [0xff][0x6],[BL][ext 0x0,0x0] 1 0 0 <---master_node=0表示例項1
假設一個四節點的RAC環境,block 6/255 存在於例項2的buffer cache裡,也存在於例項4的buffer cache裡,當例項3要查詢這個block時,先根據特定的hash演算法找到block的master node也就是例項1,例項1訪問自己的GRD後得知例項2 buffer cache裡的block剛修改過其SCN號比例項4裡的要大,而比例項3查詢發起時的SCN要小,所以例項1通知node 2將block傳輸給例項3,大致過程如下圖所示:
① S例項3要查詢block 6/255的內容,經過一定的hash演算法得出block 6/255的master node是例項1,於是例項3向例項1發起查詢block 6/255,此時的Query SCN=107
② 例項1查詢GRD後得知例項2上存在的block 6/255版本比例項4更新,更適合作為結果傳遞給例項1,所以例項1通知例項2要求其將該block傳輸給例項3
③ 例項2將自己buffer cache裡的block 6/255傳輸給例項3
RAC環境的各個例項都會存放一部分GRD資訊,具體位置是在shared pool裡,可以使用下面的語句瞭解這部分的記憶體佔用情況:
SELECT name,bytes FROM v$sgastat WHERE name LIKE 'ges resource%' OR name LIKE 'ges enqueues';
NAME BYTES
-------------------------- ----------
ges resource pools 744
ges resource hash seq tab 16384
ges enqueues 11550936
ges resource 5708880
ges resource hash table 720896
2、例項A既然沒有在修改這個block,為何會對block持有Exclusive鎖?
和單例項資料一樣,多例項的RAC環境下對block的訪問也需要獲得各種鎖,單例項與多例項鎖的對應關係如下:
單例項 多例項
NULL KJUSERNL
RS KJUSERCR
RX KJUSERCW
S KJUSERPR
SRX KJUSERPW
X KJUSEREX
其中KJUSERPR表示Protected read,KJUSEREX表示One process holds exclusive lock,我們暫只關注這兩種鎖。
透過一個小實驗來了解一下KJUSERPR和KJUSEREX在什麼情況下會出現
例項1:
create table scott.t0820_1 (id number);
insert into scott.t0820_1 values(1);
commit;
select * from scott.t0820_1;
ID
----------
1
select distinct dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) blkno from scott.t0820_1;
FNO BLKNO
---------- ----------
6 255
alter system flush buffer_cache;
update scott.t0820_1 set id=2 where id=1;
commit;
set heading on
select inst_id,file#,block#,status from gv$bh where file#=6 and block#=255 and status!='free';
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 255 xcur
1 6 255 cr
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_8474.trc
alter system dump datafile 6 block 255;
在dump檔案susedb11_ora_8474.trc的尾端可以看到block 6/255在GRD裡的部分資訊:
GLOBAL CACHE ELEMENT DUMP (address: 0x8afaeaa8):
id1: 0xff id2: 0x6 pkey: OBJ#15976 block: (6/255)
lock: X rls: 0x0 acq: 0x0 latch: 4 <---注意這裡lock: X代表了block上鎖型別為KJUSEREX
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xadf5b3b0,0xadf5b3b0]
seq: 18 hist: 58 145:0 28 340 66 144:0 7 352 197 48 121 113 424
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02000001 state: XCURRENT tsn: 6 tsh: 2
addr: 0xadf5b278 obj: 15976 cls: DATA bscn: 0x0.186dfc
在update語句commit後我們看到buffer cache裡出現了block 6/255的兩個版本,標示為cr的是update之前的before-image,標示為xcur的正是修改後的最新版本,xcur表示exclusive current,說明該block剛被更新過,buffer cache和磁碟上的內容可能不一樣(checkpoint尚未發生)也有可能已經一樣了(已發生checkpoint)。從上面的這段實驗內容可以看出儘管update所在事務已經提交但例項1還是持有著block 6/255上的exclusive鎖,雖然沒有釋放,但並不會影響其它例項對於block 6/255的訪問,後面會有對這個問題的解釋。
alter system flush buffer_cache;
select * from scott.t0820_1;
ID
----------
2
select inst_id,file#,block#,status from gv$bh where file#=6 and block#=255 and status!='free';
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 255 scur
第二次flush buffer cache後緊接著作一次查詢,觀察到 block 6/255在buffer cache裡的型別變為了scur,scur表示shared current,說明該block在buffer cache和磁碟裡的內容一致。
再次dump後可以看到block上的鎖相應變成了Lock: S
alter system dump datafile 6 block 255;
GLOBAL CACHE ELEMENT DUMP (address: 0x8afaeaa8):
id1: 0xff id2: 0x6 pkey: OBJ#15976 block: (6/255)
lock: S rls: 0x0 acq: 0x0 latch: 4 <---lock: S
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh01: kdstgr'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xa9f1c290,0xa9f1c290]
seq: 28 hist: 66 144:0 7 352 197 48 121 113 424 180 58 145:0 28
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x00080000 state: SCURRENT tsn: 6 tsh: 1
addr: 0xa9f1c158 obj: 15976 cls: DATA bscn: 0x0.186dfc
這個小實驗說明,最後修改過某個block的例項即便事務已經提交仍會在這個block上留下Exclusive鎖,當然這個Exclusive鎖是可以轉換成其它型別的,比如在checkpoint後會被scur取代
3、鎖降級轉換目的在於?是否每一次跨例項傳輸block前都需要先進行鎖降級轉換?
鎖降級轉換指的是buffer cache中的block狀態從xcur轉換為scur,考慮一下這個場景:
例項3為block A的master node,例項1會話修改了block A,此事例項1對block A持有Exclusive鎖,在v$bh裡的buffer型別是xcur,之後例項2會話把select訪問Block A的請求遞交給例項3,例項3根據GRD裡的資源資訊發現例項1 buffer cache裡的block A的xcur版本能滿足例項2的查詢要求,於是通知例項1將其buffer cache裡的block A傳送給例項2,按照一般的思路,例項1在向例項2傳輸前需要將Exclusive鎖轉換成Share模式的鎖(因為例項2是select訪問),然後再傳輸給例項2。但考慮到既然例項1修改了block A,其再次修改Block A的可能性還是很大的,如果將Exclusive鎖轉換成Share鎖,後續例項1再次修改block A時又需要從Share轉回Exclusive,在維護GRD的層面還是會產生不少開銷的。所以例項1在首次將block A傳送給例項2時並不會將其持有Exclusive鎖釋放或者轉換成其它型別,而是基於xcur型別的block A版本構造出一個型別為cr的buffer(內容與xcur型別的buffer完全一樣),將這個cr block傳送到例項2的buffer cache裡,例項2訪問cr block時無需加任何的鎖,但oracle為了加以區分還是上了一個NULL型別的鎖,準確的說它是一個placeholder型別的lock,在GRD裡這個鎖的名字是KJUSERNL。這種處理方式顯然能夠保留例項1對block持有的Exclusive鎖。但為此產生的代價是:從xcur構造出cr型別的block也是會產生一定開銷的,這其中包括
(1) build cr block的時間
(2) build cr block過程中產生的redo寫入online redolog的時間
一種較為極端的情況是若例項2後面對同一個block連續發起多次select操作,會引發例項1多次構造cr block的動作。於是Oracle在保留Exclusive鎖與構造cr block間作了一個折衷,提供了隱含引數_fairness_threshold,當select訪問次數達到引數指定值的時候,例項1會將block上的Exclusive鎖降級轉換成Shared鎖,對應的buffer也會從xcur轉換成scur型別,當例項2第_fairness_threshold+1次訪問相同block的時候例項1會把scur型別的block傳輸到例項2,之後例項2再次訪問相同block就只要從本地Buffer cache獲取。
我們還是透過具體實驗來體會一下_fairness_threshold引數的作用,其中需要用到的rec.sql指令碼內容如下:
***************
* rec.sql指令碼內容
***************
set heading off
select '----gv$cr_block_server----' from dual;
set heading on
select inst_id,fairness_down_converts,fairness_clears,light_works from gv$cr_block_server order by inst_id;
set heading off
select '----gv$bh----' from dual;
set heading on
select inst_id,file#,block#,status from gv$bh where file#=6 and block#=231 and status!='free';
set heading off
select '----x$bh----' from dual;
set heading on
col object_name format a20
set linesize 80
select inst_id,dbarfil,dbablk,CR_SCN_BAS,DECODE(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi', 9,'memory',10,'mwrite',11,'donated', 12,'protected', 13,'securefile', 14,'siop',15,'recckpt', 16, 'flashfree', 17, 'flashcur', 18, 'flashna') state_name,tch from x$bh where dbarfil=6 and dbablk=231 and state!=0;
///////////////////////////////////
// 場景1:_fairness_threshold=2(預設值)
///////////////////////////////////
session說明:其中session 1 node X是真正參與測試的session,session 2 node X是專用來觀察相關檢視內容,獲取測試相關資訊的session
---session 1 node 1:修改其中一條記錄後commit;
alter system set optimizer_dynamic_sampling=0 scope=memory;
select * from scott.testfn_0730;
ID COL2
---------- ----
1 A
2 B
select distinct dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) blkno from scott.testfn_0730;
FNO BLKNO
---------- ----------
6 231
update scott.testfn_0730 set col2='a' where id=1;
commit;
---session 2 node 1: 查詢_fairness_threshold引數值,記錄buffer cache裡block的狀態,DOWN_CONVERTS次數,light_works次數
col ksppinm format a30
col ksppstvl format a20
col ksppdesc format a60
col ksppstcmnt format a20
set linesize 200
select x.inst_id,ksppinm,ksppity,ksppstvl,ksppdesc from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_fairness_threshold');
INST_ID KSPPINM KSPPITY KSPPSTVL KSPPDESC
---------- ------------------------------ ---------- -------------------- ------------------------------------------------------------
1 _fairness_threshold 3 2 number of times to CR serve before downgrading lock
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 4 0 0 <---node 1初始down_converts次數為4
2 4 0 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 xcur <---session 1 node 1 update之後在buffer cache裡留下了xcur、cr兩個block,其中cr是block修改前的映像,xcur是當前最新的block映像
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
1 6 231 0 xcur
1 6 231 1276027 cr <---1276027是cr生成時的scn
---session 1 node 2:第一次訪問testfn_0730表
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數,light_works次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 4 0 0 <---down_converts次數未發生變化
2 4 0 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 xcur
1 6 231 cr
2 6 231 cr <---node 2 buffer cache新增一型別為cr的block,正是由node 1以其xcur型block為基礎構造出來傳輸至node 2的
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
2 6 231 1276334 cr <---node 2上cr block scn=1276334代表了其從xcur構造而來那一刻的系統scn號
---session 2 node 1: data block dump on node 1
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_16988.trc
alter system dump datafile 6 block 231; <---dump block的內容,僅取出與GC有關的部分
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9b978):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: X rls: 0x0 acq: 0x0 latch: 6 <--- node1:lock: X 表示block上有Exclusive鎖
flags: 0x20 fair: 1 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xadf5d770,0xadf5d770]
seq: 11 hist: 113 424 180 58 145:0 118 66 144:0 192 352 32
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02200000 state: XCURRENT tsn: 6 tsh: 2
addr: 0xadf5d638 obj: 15930 cls: DATA bscn: 0x0.13787d
。。。省略部分內容
---session 2 node 2: data block dump on node 2
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb12/trace/susedb12_ora_18928.trc
alter system dump datafile 6 block 231; <---dump block的內容
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9df78):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: C rls: 0x0 acq: 0x0 latch: 6 <--- node2:lock: C 其中的C代表Consistent,表示這個block是處於consistent read目的而生成的,其不能被服用,所以block上的鎖型別為KJUSERNL,KJUSERNL是一個placeholder型別的鎖
flags: 0x21 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0x8af7e248,0xadffd5a8]
seq: 6 hist: 329 144:6 14 7 352 32
。。。省略部分內容
---session 1 node 2:第二次訪問testfn_0730表
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 4 0 0
2 4 0 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 xcur
1 6 231 cr
2 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
2 6 231 1276334 cr
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 5 0 0 <---node 1的down convert次數從4增加到了5,發生了一次鎖降級轉換
2 4 0 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 scur <---node 1的xcur降級成了scur
1 6 231 cr
2 6 231 cr
2 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
2 6 231 1277433 cr <---node 2上新增了一個SCN=1277433的cr,這個cr是在node 1上的xcur降級成scur之前構造出來的
2 6 231 1276334 cr <---這是第一次select後生成的cr
---session 2 node 1: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 6 0 0 <---node 1的down convert次數從5增加到了6,不清楚這次鎖降級轉換是由哪個block觸發的,但可以肯定與scott.testfn_0730表無關
2 22 1 0 <---node 2 down convert次數也從之前的4上升到22,也與scott.testfn_0730表無關,這裡我們不必關注
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 scur
1 6 231 cr
2 6 231 cr
2 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
1 6 231 0 scur
1 6 231 1276027 cr
---session 2 node 1: data block dump on node 1
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_19706.trc
alter system dump datafile 6 block 231; <---dump block的內容,僅選取與GC有關的部分
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9b978):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: S rls: 0x0 acq: 0x0 latch: 6 <---block dump結果容易看出node 1對block 6/231持有的鎖已從lock : X降級為lock : S
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xadf5d770,0xadf5d770]
seq: 14 hist: 45 4 54 113 424 180 58 145:0 118 66 144:0 192 352 32
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02200000 state: SCURRENT tsn: 6 tsh: 2
addr: 0xadf5d638 obj: 15930 cls: DATA bscn: 0x0.13787d
。。。省略部分內容
---session 2 node 2: data block dump on node 2
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb12/trace/susedb12_ora_20858.trc
alter system dump datafile 6 block 231; <---dump block的內容
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9df78):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: C rls: 0x0 acq: 0x0 latch: 6 <---node 2還是保持為lock: C,即KJUSERNL鎖
flags: 0x21 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0x8af954c8,0xadffd5a8]
seq: 11 hist: 329 144:6 14 7 352 329 144:6 14 7 352 32
。。。省略部分內容
---session 1 node 2:第三次訪問testfn_0730表,發現多出了型別為scur的buffer
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 7 0 0 <---比上一次增加了1
2 27 1 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 scur <---node 2新生成出了一個scur,這個scur是從node 1傳輸過來的(node 1上的scur剛從xcur降級而來),scur表示該block在記憶體中的內容與磁碟上的內容一致
2 6 231 cr
2 6 231 cr
1 6 231 scur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
2 6 231 0 scur
2 6 231 1277433 cr
2 6 231 1276334 cr
---session 2 node 1: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 7 0 0
2 27 1 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 scur
2 6 231 cr
2 6 231 cr
1 6 231 scur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME
---------- ---------- ---------- ---------- ----------
1 6 231 0 scur
1 6 231 1276027 cr
---session 2 node 1: data block dump on node 1
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_21738.trc
alter system dump datafile 6 block 231; <---dump block的內容,僅顯示與GC有關的部分
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9b978):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: S rls: 0x0 acq: 0x0 latch: 6 <---node1對block的鎖維持lock: S
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xadf5d770,0xadf5d770]
seq: 16 hist: 227 160 45 4 54 113 424 180 58 145:0 118 66 144:0 192
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02200000 lflg: 0x2 state: SCURRENT tsn: 6 tsh: 1
addr: 0xadf5d638 obj: 15930 cls: DATA bscn: 0x0.13787d
。。。省略部分內容
---session 2 node 2: data block dump on node 2
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb12/trace/susedb12_ora_22849.trc
alter system dump datafile 6 block 231; <---dump block的內容
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x89f9df78):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: S rls: 0x0 acq: 0x0 latch: 6 <---node 2上持有的鎖從lock: C變為了lock: S,因為node 2有了自己的scur block
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xabf5f310,0xabf5f310]
seq: 16 hist: 227 144:0 213 7 352 329 144:6 14 7 352 329
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x08080000 state: SCURRENT tsn: 6 tsh: 1
addr: 0xabf5f1d8 obj: 15930 cls: DATA bscn: 0x0.13787d
。。。省略部分內容
---session 1 node 2:第四次訪問testfn_0730表,從第四次開始往後每次都是訪問scur這個buffer
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
SQL> @rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 37 2 1
2 40 1 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 scur
1 6 231 cr
2 6 231 scur
2 6 231 cr
2 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 0 scur 3 <---scur的訪問次數一直在增加
2 6 231 1277433 cr 1
2 6 231 1276334 cr 1
---session 3 node 2:node 2上新開一個session訪問testfn_0730表,發現也都是訪問scur這個buffer,此時已不需要從遠端例項cache裡進行傳輸
select * from scott.testfn_0730;
SQL> @rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 44 2 1
2 40 1 0
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 scur <---node 1、node 2的buffer數量沒有再增加
1 6 231 cr
2 6 231 scur
2 6 231 cr
2 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 0 scur 4 <---tch數量的不斷上升表明node 2對block 6/231的訪問最後都落到了scur block上
2 6 231 1277433 cr 1
2 6 231 1276334 cr 1
小結一下:
_fairness_threshold=2時,當node 2第2次訪問node 1 buffer cache裡的block時,buffer cache裡該block的型別從xcur轉換成scur,v$cr_block_server.FAIRNESS_DOWN_CONVERTS計數器加1;node 1持有的鎖從Exclusive轉換為Share,node 2持有的鎖仍然是KJUSERNL;儘管如此,node 1仍然會構造出一個cr block傳送給node 2,我們能在node 2的buffer cache裡看到這個cr block;node 2第3次訪問block時,node 2 buffer cache裡才會新增一個從node 1傳輸而來的scur block,並且持有鎖的型別也從KJUSERNL變為了Share。如果block內容一直不被更改,從_fairness_threshold+2輪查詢開始node 2可在其本地的buffer cache裡直接訪問到該scur型別的block,不必從遠端的node 1節點獲得
下面看看_fairness_threshold=3的時候,是否遵循上述規律
///////////////////////////////
// 場景2:修改_fairness_threshold=3
///////////////////////////////
session說明:其中session 1 node X是真正參與測試的session,session 2 node X是專用來觀察相關檢視內容,獲取測試相關資訊的session
---session 1 node 1:修改其中一條記錄後commit;
alter system set optimizer_dynamic_sampling=0 scope=memory;
select * from scott.testfn_0730;
ID COL2
---------- ----
1 A
2 B
select distinct dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) blkno from scott.testfn_0730;
FNO BLKNO
---------- ----------
6 231
update scott.testfn_0730 set col2='a' where id=1;
commit;
---session 2 node 1: 查詢_fairness_threshold引數值,記錄buffer cache裡block的狀態,DOWN_CONVERTS次數,light_works次數
col ksppinm format a30
col ksppstvl format a20
col ksppdesc format a60
col ksppstcmnt format a20
set linesize 200
select x.inst_id,ksppinm,ksppity,ksppstvl,ksppdesc from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_fairness_threshold');
INST_ID KSPPINM KSPPITY KSPPSTVL KSPPDESC
---------- ------------------------------ ---------- -------------------- ------------------------------------------------------------
1 _fairness_threshold 3 3 number of times to CR serve before downgrading lock
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 28 4 0
2 53 1 8
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
1 6 231 xcur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
1 6 231 0 xcur 2
1 6 231 1800959 cr 2
---session 1 node 2:第一次訪問testfn_0730表
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數,light_works次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 29 4 0
2 53 1 8
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 cr <---node 2第一次訪問的是一個cr型別的block由node1構造後傳輸而來
1 6 231 xcur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 1800996 cr 1
---session 1 node 2:第二次訪問testfn_0730表
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 41 4 0
2 53 1 8
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 cr <---node 2第二次訪問後在buffer cache裡有了第二個cr型別的block
2 6 231 cr
1 6 231 xcur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 1801011 cr 1 <---CR_SCN_BAS=1801011對應的cr block是第二次查詢所構造出的CR
2 6 231 1800996 cr 1 <---CR_SCN_BAS=1800996對應的cr block是第一次查詢所構造出的CR
---session 1 node 2:第三次訪問testfn_0730表
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 42 4 0 <---因為達到了_fairness_threshold所指定的閥值觸發了down convert動作,所以FAIRNESS_DOWN_CONVERTS較上次查詢的41增加了1
2 53 1 8
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 cr
2 6 231 cr
2 6 231 cr
1 6 231 scur <---node 1 buffer cache中的xcur轉換成了scur
1 6 231 cr
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 1801037 cr 1 <---第三次查詢構造出的cr
2 6 231 1801011 cr 1
2 6 231 1800996 cr 1
---session 2 node 1: data block dump on node 1
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_11782.trc
alter system dump datafile 6 block 231; <---dump block的內容,僅取出與GC有關的部分
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x8cfd7568):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: SG rls: 0x0 acq: 0x0 latch: 6 <---lock:SG 表示node 1上已經降級成了Share鎖,G是global的意思
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.1ac5e4 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xabf051b0,0xabf051b0]
seq: 13 hist: 170 1 4 54 58 145:0 28 340 239 144:0 7 352 32
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02000001 state: SCURRENT tsn: 6 tsh: 2
addr: 0xabf05078 obj: 15930 cls: DATA bscn: 0x0.1b7b02 piscn: 0x0.1b7b4d
。。。省略部分內容
---session 2 node 2: data block dump on node 2
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb12/trace/susedb12_ora_10722.trc
alter system dump datafile 6 block 231; <---dump block的內容
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x8aff9088):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: C rls: 0x0 acq: 0x0 latch: 6 <---lock:C 表示node 2持有的還是KJUSERNL型別的鎖
flags: 0x21 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xb833b270,0x8afc13c8]
seq: 22 hist: 329 144:6 14 7 144:5 192 352 329 144:6 14 7
。。。省略部分內容
---session 1 node 2:第四次訪問testfn_0730表
select * from scott.testfn_0730;
ID COL2
---------- ----
1 a
2 B
---session 2 node 2: 記錄buffer cache裡block的狀態,DOWN_CONVERTS次數
@rec.sql
----gv$cr_block_server----
INST_ID FAIRNESS_DOWN_CONVERTS FAIRNESS_CLEARS LIGHT_WORKS
---------- ---------------------- --------------- -----------
1 46 4 0
2 53 1 8
----gv$bh----
INST_ID FILE# BLOCK# STATUS
---------- ---------- ---------- ----------
2 6 231 scur <---第四輪查詢過後node 2上不再生成新的cr,取而代之的是node 1傳輸過來的scur
2 6 231 cr
2 6 231 cr
2 6 231 cr
1 6 231 scur
1 6 231 cr
6 rows selected.
----x$bh----
INST_ID DBARFIL DBABLK CR_SCN_BAS STATE_NAME TCH
---------- ---------- ---------- ---------- ---------- ----------
2 6 231 0 scur 1
2 6 231 1801037 cr 1
2 6 231 1801011 cr 1
2 6 231 1800996 cr 1
---session 2 node 1: data block dump on node 1
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb11/trace/susedb11_ora_10588.trc
alter system dump datafile 6 block 231; <---dump block的內容,僅選取與GC有關的部分
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x8cfd7568):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: SG rls: 0x0 acq: 0x0 latch: 6 <---lock:SG node 1上仍然維持Share鎖
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.1ac5e4 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xabf051b0,0xabf051b0]
seq: 20 hist: 225 212 424 72 257 59 227 170 1 4 54 58 145:0 28 340
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x02200000 state: SCURRENT tsn: 6 tsh: 2
addr: 0xabf05078 obj: 15930 cls: DATA bscn: 0x0.1b7b02
。。。省略部分內容
---session 2 node 2: data block dump on node 2
select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/susedb1/susedb12/trace/susedb12_ora_11315.trc
alter system dump datafile 6 block 231; <---dump block的內容
。。。省略部分內容
GLOBAL CACHE ELEMENT DUMP (address: 0x8aff9088):
id1: 0xe7 id2: 0x6 pkey: OBJ#15930 block: (6/231)
lock: S rls: 0x0 acq: 0x0 latch: 6 <---lock:SG node 2從KJUSERNL類的鎖轉換成Share鎖
flags: 0x20 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
bscn: 0x0.0 bctx: (nil) write: 0 scan: 0x0
lcp: (nil) lnk: [NULL] lch: [0xabeefc70,0xabeefc70]
seq: 29 hist: 227 144:0 213 7 144:5 192 352 329 144:6 14 7
LIST OF BUFFERS LINKED TO THIS GLOBAL CACHE ELEMENT:
flg: 0x08080000 state: SCURRENT tsn: 6 tsh: 1
addr: 0xabeefb38 obj: 15930 cls: DATA bscn: 0x0.1b7b02
。。。省略部分內容
小結一下:
_fairness_threshold=3時,當node 2第3次訪問node 1 buffer cache裡的block時,node 1 buffer cache裡該block的型別從xcur轉換成scur,v$cr_block_server.FAIRNESS_DOWN_CONVERTS計數器加1;node 1持有的鎖從Exclusive轉換為Share,node 2持有的鎖仍然是KJUSERNL;此時,node 1仍然會構造出一個cr block傳送給node 2,我們能在node 2的buffer cache裡看到這個cr block;node 2第4次訪問block時,node 2 buffer cache裡才會新增一個從node 1傳輸而來的scur block,並且持有鎖的型別也從KJUSERNL變為了Share。如果block內容一直不被更改,從_fairness_threshold+2輪查詢開始node 2可在其本地的buffer cache裡直接訪問到該scur型別的block,不必從遠端的node 1節點獲得
總結:
_fairness_threshold的可以看出oracle研發過程中的精雕細琢,為了在鎖轉換產生的開銷與cr block構造產生的開銷之間找到平衡,提供_fairness_threshold引數的同時給了使用者一個靈活調節的手段,細節決定成敗,Oracle RAC無愧為業界優秀的資料庫叢集軟體
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-2124241/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 隱含引數Oracle
- ORACLE隱含引數Oracle
- oracle獲取隱含引數Oracle
- 隱含引數的查詢
- Oracle的隱含引數(zt)Oracle
- 獲取Oracle隱含引數資訊Oracle
- 獲取oracle的隱含引數Oracle
- oracle的一個隱含引數Oracle
- Oracle 中所有隱含的 引數Oracle
- Oracle隱含引數的查詢Oracle
- 常用指令碼:獲取隱含引數指令碼
- oracle 檢視隱含引數指令碼Oracle指令碼
- oracle 11g常用隱含引數Oracle
- [zt] 如何檢視Oracle 隱含引數Oracle
- oracle隱含引數的檢視與修改Oracle
- 【parameter】oracle的隱含引數的檢視Oracle
- Oracle 隱含引數 : _allow_resetlogs_corruptionOracle
- Oracle direct path read相關隱含引數Oracle
- Oracle 隱含引數 _disable_loggingOracle
- 隱含引數的查詢x$ksppi,x$ksppcv
- 【ASM學習】關於 ASM 的隱含引數ASM
- v$動態效能檢視和隱含引數
- 關於隱含引數_b_tree_bitmap_plans
- CBO,ORACLE,隱含引數,_sort_elimination_cost_ratio的含義Oracle
- 隱含引數_minimum_giga_scn的理解
- 使用隱含Trace引數診斷Oracle Data Pump故障Oracle
- 獲取_字首的oracle hidden parameter隱含引數Oracle
- [zt] Oracle10g 隱含引數 - LOG_PARALLELISMOracleParallel
- 使用隱含Trace引數診斷Oracle Data Pump(expdp)故障Oracle
- 查詢資料庫隱含引數的sql語句資料庫SQL
- Oracle引數-隱藏引數Oracle
- 【PARANETERS】Oracle異常恢復相關的隱含引數Oracle
- Oracle 11G 隱含引數“_controlfile_autobackup_delay”Oracle
- 【指令碼】隱含引數及註釋資訊的查詢方法指令碼
- [20190401]隱含引數_mutex_spin_count.txtMutex
- Oracle 11g中的_optimizer_null_aware_antijoin隱含引數OracleNull
- 使用隱含引數testMappingSpeed排查GoldenGate抽取慢的步驟APPGo
- SQL語句中直接修改隱含引數,避免影響整個DBSQL