Oracle buffer状态深入剖析
生活随笔
收集整理的這篇文章主要介紹了
Oracle buffer状态深入剖析
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
這篇文章是參考甲骨論老相老師的教學視頻:
http://v.youku.com/v_show/id_XMzkyMjA4NDM2.html
所做學習筆記
1. 什么是buffer
之前提過很多次啦, 其實在oracle數(shù)據(jù)文件中最小的單位就是block, 而用戶讀取block數(shù)據(jù)時,oracle就會將block的數(shù)據(jù)放入緩存,那么緩存中對應block的單位就叫buffer了, block的大小與buffer大小是一樣的.
2. 關于buffer的動態(tài)數(shù)據(jù)字典x$dh
????????? Oracle有一個動態(tài)視圖x$dh, 里面有很多個數(shù)據(jù)行, 其中每個數(shù)據(jù)行對應buffer_cache里的每1個buffer..
????????? x$bh里有很多列, 這次我們重點講解幾個重要的字段啦:
SQL> desc x$bh
?Name?? ??? ??? ??? ??? ??? Null???? Type
?----------------------------------------- -------- ----------------------------
?ADDR?? ??? ??? ??? ??? ??? ???? RAW(8)
?INDX?? ??? ??? ??? ??? ??? ???? NUMBER
?INST_ID?? ??? ??? ??? ??? ???? NUMBER
?HLADDR ?? ??? ??? ??? ??? ???? RAW(8)
?BLSIZ?? ??? ??? ??? ??? ??? ???? NUMBER
?NXT_HASH?? ??? ??? ??? ??? ???? RAW(8)
?PRV_HASH?? ??? ??? ??? ??? ???? RAW(8)
?NXT_REPL?? ??? ??? ??? ??? ???? RAW(8)
?PRV_REPL?? ??? ??? ??? ??? ???? RAW(8)
?FLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?FLAG2?? ??? ??? ??? ??? ??? ???? NUMBER
?LOBID?? ??? ??? ??? ??? ??? ???? NUMBER
?RFLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?SFLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?LRU_FLAG?? ??? ??? ??? ??? ???? NUMBER
?TS#?? ??? ??? ??? ??? ??? ???? NUMBER
?FILE#?? ??? ??? ??? ??? ??? ???? NUMBER
?DBARFIL?? ??? ??? ??? ??? ???? NUMBER
?DBABLK ?? ??? ??? ??? ??? ???? NUMBER
?CLASS?? ??? ??? ??? ??? ??? ???? NUMBER
?STATE?? ??? ??? ??? ??? ??? ???? NUMBER
?MODE_HELD?? ??? ??? ??? ??? ???? NUMBER
?CHANGES?? ??? ??? ??? ??? ???? NUMBER
?CSTATE ?? ??? ??? ??? ??? ???? NUMBER
?LE_ADDR?? ??? ??? ??? ??? ???? RAW(8)
?DIRTY_QUEUE?? ??? ??? ??? ??? ???? NUMBER
?SET_DS ?? ??? ??? ??? ??? ???? RAW(8)
?OBJ?? ??? ??? ??? ??? ??? ???? NUMBER
?BA?? ??? ??? ??? ??? ??? ???? RAW(8)
?CR_SCN_BAS?? ??? ??? ??? ??? ???? NUMBER
?CR_SCN_WRP?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_USN?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_SLT?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_SQN?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_FIL?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_BLK?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_SEQ?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_REC?? ??? ??? ??? ??? ???? NUMBER
?CR_SFL ?? ??? ??? ??? ??? ???? NUMBER
?CR_CLS_BAS?? ??? ??? ??? ??? ???? NUMBER
?CR_CLS_WRP?? ??? ??? ??? ??? ???? NUMBER
?LRBA_SEQ?? ??? ??? ??? ??? ???? NUMBER
?LRBA_BNO?? ??? ??? ??? ??? ???? NUMBER
?HSCN_BAS?? ??? ??? ??? ??? ???? NUMBER
?HSCN_WRP?? ??? ??? ??? ??? ???? NUMBER
?HSUB_SCN?? ??? ??? ??? ??? ???? NUMBER
?US_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?US_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?WA_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?WA_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?OQ_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?OQ_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?AQ_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?AQ_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?OBJ_FLAG?? ??? ??? ??? ??? ???? NUMBER
?TCH?? ??? ??? ??? ??? ??? ???? NUMBER
?TIM?? ??? ??? ??? ??? ??? ???? NUMBER
?CR_RFCNT?? ??? ??? ??? ??? ???? NUMBER
?SHR_RFCNT?? ??? ??? ??? ??? ???? NUMBER
3. Buffer 的 state (就是上面的state 字段啦)
查看當前的狀態(tài), 如下圖 只有3個值..
每種值的意思如下面表
下面解釋這幾種狀態(tài)意思
3.1?? Free
????????? 就是未被使用過的buffer啦, 好容易理解~
3.2?? XCUR
???????? 字面意思就是當前實例獨享的當前模式塊, 其中重點要留意current的意思.
?????? 如上圖 當1個server process要讀取dbf文件中的1個block時,必然會將這個block數(shù)據(jù)放入buffer cache中, 那么buffer cache里那個對應buffer就被占用了, 狀態(tài)的就成了為current.
?????? CUR狀態(tài)的buffer肯定有1個dbf文件文中的中的block與其對應的.
??????
?????? 在單實例里, CUR狀態(tài)的buffer肯定就是XCUR,因為不可能被其他實例共享啦.
3.3 ? SCUR
????? 字面意思就是與其他實例共享的CUR狀態(tài)的buffer, 在RAC集群數(shù)據(jù)庫會出現(xiàn)這種block, 老相老師視頻里沒有深講,以后再補充了.
????? 個人猜測因為RAC是有個多個實例的, 也就代表有多個SGA, 也就是多個Buffer cache,? 既然其中1個buffer cache有了這個CUR的buffer,? 其他實例的Buffer cache就沒必要重復了, 可以共享給其他實例的server process訪問?
3.4 ? CR
?????? 當1個CUR buffer被其中1個server process修改, 但是并沒有提交. 如果下一個server process訪問這個buffer時,就會形成臟讀了.
?????? 為了避免這種情況, 下1個server process發(fā)現(xiàn)要訪問的CUR buffer已被其他server process修改后而未提交時,就會在buffer cache里申請多1個空間, 復制1個修改前的buffer 鏡像, 這個buffer 就叫做CR塊.
如下圖, 當buffer cache里的1個buffer被修改且未提交時, 下個buffer是不能訪問的.
?
?????? 這時Server process B會申請1個新的buffer空間, 復制要訪問的buffe到1個新的空間,? 但是還要把這個buffer修改后的數(shù)據(jù)還原回去.? 這時,重做日志就發(fā)揮作用了, 因為server process A修改數(shù)據(jù)后即使沒有提交, 但是一樣會產(chǎn)生重做日志的, server process B就會利用這些重做日志, 改動回滾, 就形成1個新的CR塊了. 如下圖:
??????
要注意如下幾點:
?????? 1. 上面提到1個CUR塊是與1個數(shù)據(jù)文件中的block一一對應的,? 而CR塊作為鏡像,是沒有dbf中的block與其對應..
?????? 2. 也就是說對與dbf文件中1個block來講,只會存在1個CUR塊.
?????? 3. Server process只能對CUR buffer作修改, 而不能修改CR塊.
????? 也就是說對于1個同1行數(shù)據(jù)不能有兩個session同時修改,?? 假如1行數(shù)據(jù)的值是x ,其中1個會話執(zhí)行x+y,? 另1個同時執(zhí)行x+z,這時會話1先提交, 那么值就變成x+y了.? 但是會話2再提交時, 值變成x+z了,? 所以最后丟失了y的數(shù)據(jù).
?
3.5 ? READ
????? 這個也很容易理解,? 就是正在讀取當中的狀態(tài)啦, 因為從dbf文件中1個block讀取數(shù)據(jù)到buffer cache里的1個buffer時, 會發(fā)生物理IO, 假如這個過程需要10毫秒, 那么在這10毫米中這個buffer狀態(tài)就是READ.
3.6 ? XREC
???? 這個buffer 處于介質(zhì)恢復狀態(tài)中.
3.7 ? IREC
???? 這個buffer 處于實例恢復狀態(tài)中.
????? 關于XREC和IREC狀態(tài)以后再詳細討論,? 在Oracle正常使用中是不會出現(xiàn)這兩種狀態(tài)的buffer的.
4. 做個例子啦
??? 步驟1:首先查看一下HR.CL_DEPT這張表, 有6行數(shù)據(jù)啦~
????
???? 步驟2:? 跟住清空buffer_cache里的數(shù)據(jù), 注意在生產(chǎn)中執(zhí)行這個動作很危險, 因為跟住就會有大量的物理IO了.
?
?????? 步驟3:? 執(zhí)行下面sql語句, 能查詢某個數(shù)據(jù)庫 對象的buffer占用狀態(tài):
select o.object_name,
?????? decode(state, 0, 'free', 1, 'xcur' , 2, 'scur', 3, 'cr',
???????????????????? 4, 'read', 5, 'mrec' , 6, 'irec', 7, 'write',
???????????????????? 8, 'pi') as state,
?????? count(1) blocks
from x$bh b, dba_objects o
where b.obj = o.data_object_id
? and o.object_name = 'CL_DEPT'
? and o.owner = 'HR'
group by o.object_name, state
order by blocks desc;
?執(zhí)行一下:
?
可以見到這個表還占用5個buffer ,但是狀態(tài)是free的, 所以這個5個buffer是沒有數(shù)據(jù)的.
那為什么會占住5個free呢, 是因為我們剛才select過一次, 即使執(zhí)行清空buffer cache,但是在CRC鏈區(qū)可能還存在buffer的頭部信息指向, 但是buffer數(shù)據(jù)就的確被清空了.
隔2分鐘再看一次:
發(fā)現(xiàn)只占用4個free了, 所以CRC鏈里的信息也會慢慢清除的.
?
步驟4: 進行select 操作, 然后再查看buffer狀態(tài)
首先select一下這個張表, 因為buffer里并沒有這張表的緩存,所以會發(fā)生物理IO啦:
這時查看buffer狀態(tài):
見到6個 xcur buffer了, 也說明有6個block的被寫入到buffer cache里面
步驟5: 用當前session (SYS 帳號)修改一條數(shù)據(jù), 但并不提交
步驟6: 用另1個session (scott 帳號)查看這張表, 看到的是修改前的數(shù)據(jù)
步驟7: 只所以會見到修改前的數(shù)據(jù), 是因為構(gòu)造了CR塊啦!
?
?
?步驟8: SYS這個session提交修改, 然后scott 在查看1次表, 見到修改后的數(shù)據(jù).
?
?
?步驟9: 再查看buffer 狀態(tài)
發(fā)現(xiàn)CR 塊并不會馬上消失哦
? ? ?
?
http://v.youku.com/v_show/id_XMzkyMjA4NDM2.html
所做學習筆記
1. 什么是buffer
之前提過很多次啦, 其實在oracle數(shù)據(jù)文件中最小的單位就是block, 而用戶讀取block數(shù)據(jù)時,oracle就會將block的數(shù)據(jù)放入緩存,那么緩存中對應block的單位就叫buffer了, block的大小與buffer大小是一樣的.
2. 關于buffer的動態(tài)數(shù)據(jù)字典x$dh
????????? Oracle有一個動態(tài)視圖x$dh, 里面有很多個數(shù)據(jù)行, 其中每個數(shù)據(jù)行對應buffer_cache里的每1個buffer..
????????? x$bh里有很多列, 這次我們重點講解幾個重要的字段啦:
SQL> desc x$bh
?Name?? ??? ??? ??? ??? ??? Null???? Type
?----------------------------------------- -------- ----------------------------
?ADDR?? ??? ??? ??? ??? ??? ???? RAW(8)
?INDX?? ??? ??? ??? ??? ??? ???? NUMBER
?INST_ID?? ??? ??? ??? ??? ???? NUMBER
?HLADDR ?? ??? ??? ??? ??? ???? RAW(8)
?BLSIZ?? ??? ??? ??? ??? ??? ???? NUMBER
?NXT_HASH?? ??? ??? ??? ??? ???? RAW(8)
?PRV_HASH?? ??? ??? ??? ??? ???? RAW(8)
?NXT_REPL?? ??? ??? ??? ??? ???? RAW(8)
?PRV_REPL?? ??? ??? ??? ??? ???? RAW(8)
?FLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?FLAG2?? ??? ??? ??? ??? ??? ???? NUMBER
?LOBID?? ??? ??? ??? ??? ??? ???? NUMBER
?RFLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?SFLAG?? ??? ??? ??? ??? ??? ???? NUMBER
?LRU_FLAG?? ??? ??? ??? ??? ???? NUMBER
?TS#?? ??? ??? ??? ??? ??? ???? NUMBER
?FILE#?? ??? ??? ??? ??? ??? ???? NUMBER
?DBARFIL?? ??? ??? ??? ??? ???? NUMBER
?DBABLK ?? ??? ??? ??? ??? ???? NUMBER
?CLASS?? ??? ??? ??? ??? ??? ???? NUMBER
?STATE?? ??? ??? ??? ??? ??? ???? NUMBER
?MODE_HELD?? ??? ??? ??? ??? ???? NUMBER
?CHANGES?? ??? ??? ??? ??? ???? NUMBER
?CSTATE ?? ??? ??? ??? ??? ???? NUMBER
?LE_ADDR?? ??? ??? ??? ??? ???? RAW(8)
?DIRTY_QUEUE?? ??? ??? ??? ??? ???? NUMBER
?SET_DS ?? ??? ??? ??? ??? ???? RAW(8)
?OBJ?? ??? ??? ??? ??? ??? ???? NUMBER
?BA?? ??? ??? ??? ??? ??? ???? RAW(8)
?CR_SCN_BAS?? ??? ??? ??? ??? ???? NUMBER
?CR_SCN_WRP?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_USN?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_SLT?? ??? ??? ??? ??? ???? NUMBER
?CR_XID_SQN?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_FIL?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_BLK?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_SEQ?? ??? ??? ??? ??? ???? NUMBER
?CR_UBA_REC?? ??? ??? ??? ??? ???? NUMBER
?CR_SFL ?? ??? ??? ??? ??? ???? NUMBER
?CR_CLS_BAS?? ??? ??? ??? ??? ???? NUMBER
?CR_CLS_WRP?? ??? ??? ??? ??? ???? NUMBER
?LRBA_SEQ?? ??? ??? ??? ??? ???? NUMBER
?LRBA_BNO?? ??? ??? ??? ??? ???? NUMBER
?HSCN_BAS?? ??? ??? ??? ??? ???? NUMBER
?HSCN_WRP?? ??? ??? ??? ??? ???? NUMBER
?HSUB_SCN?? ??? ??? ??? ??? ???? NUMBER
?US_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?US_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?WA_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?WA_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?OQ_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?OQ_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?AQ_NXT ?? ??? ??? ??? ??? ???? RAW(8)
?AQ_PRV ?? ??? ??? ??? ??? ???? RAW(8)
?OBJ_FLAG?? ??? ??? ??? ??? ???? NUMBER
?TCH?? ??? ??? ??? ??? ??? ???? NUMBER
?TIM?? ??? ??? ??? ??? ??? ???? NUMBER
?CR_RFCNT?? ??? ??? ??? ??? ???? NUMBER
?SHR_RFCNT?? ??? ??? ??? ??? ???? NUMBER
3. Buffer 的 state (就是上面的state 字段啦)
查看當前的狀態(tài), 如下圖 只有3個值..
每種值的意思如下面表
?? ? ? 0, FREE, no valid block image??
? ????? 1, XCUR, a current mode block, exclusive to this instance
? ?? ???2, SCUR, a current mode block, shared with other instances
? ?? ???3, CR,? ?a consistent read (stale) block image--表明此塊存在于回滾段中
????????4, READ, buffer is reserved for a block being read from disk
? ?? ???5, MREC, a block in media recovery mode
? ?? ???6, IREC, a block in instance (crash) recovery mode
下面解釋這幾種狀態(tài)意思
3.1?? Free
????????? 就是未被使用過的buffer啦, 好容易理解~
3.2?? XCUR
???????? 字面意思就是當前實例獨享的當前模式塊, 其中重點要留意current的意思.
?????? 如上圖 當1個server process要讀取dbf文件中的1個block時,必然會將這個block數(shù)據(jù)放入buffer cache中, 那么buffer cache里那個對應buffer就被占用了, 狀態(tài)的就成了為current.
?????? CUR狀態(tài)的buffer肯定有1個dbf文件文中的中的block與其對應的.
??????
?????? 在單實例里, CUR狀態(tài)的buffer肯定就是XCUR,因為不可能被其他實例共享啦.
3.3 ? SCUR
????? 字面意思就是與其他實例共享的CUR狀態(tài)的buffer, 在RAC集群數(shù)據(jù)庫會出現(xiàn)這種block, 老相老師視頻里沒有深講,以后再補充了.
????? 個人猜測因為RAC是有個多個實例的, 也就代表有多個SGA, 也就是多個Buffer cache,? 既然其中1個buffer cache有了這個CUR的buffer,? 其他實例的Buffer cache就沒必要重復了, 可以共享給其他實例的server process訪問?
3.4 ? CR
?????? 當1個CUR buffer被其中1個server process修改, 但是并沒有提交. 如果下一個server process訪問這個buffer時,就會形成臟讀了.
?????? 為了避免這種情況, 下1個server process發(fā)現(xiàn)要訪問的CUR buffer已被其他server process修改后而未提交時,就會在buffer cache里申請多1個空間, 復制1個修改前的buffer 鏡像, 這個buffer 就叫做CR塊.
如下圖, 當buffer cache里的1個buffer被修改且未提交時, 下個buffer是不能訪問的.
?
?????? 這時Server process B會申請1個新的buffer空間, 復制要訪問的buffe到1個新的空間,? 但是還要把這個buffer修改后的數(shù)據(jù)還原回去.? 這時,重做日志就發(fā)揮作用了, 因為server process A修改數(shù)據(jù)后即使沒有提交, 但是一樣會產(chǎn)生重做日志的, server process B就會利用這些重做日志, 改動回滾, 就形成1個新的CR塊了. 如下圖:
??????
要注意如下幾點:
?????? 1. 上面提到1個CUR塊是與1個數(shù)據(jù)文件中的block一一對應的,? 而CR塊作為鏡像,是沒有dbf中的block與其對應..
?????? 2. 也就是說對與dbf文件中1個block來講,只會存在1個CUR塊.
?????? 3. Server process只能對CUR buffer作修改, 而不能修改CR塊.
????? 也就是說對于1個同1行數(shù)據(jù)不能有兩個session同時修改,?? 假如1行數(shù)據(jù)的值是x ,其中1個會話執(zhí)行x+y,? 另1個同時執(zhí)行x+z,這時會話1先提交, 那么值就變成x+y了.? 但是會話2再提交時, 值變成x+z了,? 所以最后丟失了y的數(shù)據(jù).
?
3.5 ? READ
????? 這個也很容易理解,? 就是正在讀取當中的狀態(tài)啦, 因為從dbf文件中1個block讀取數(shù)據(jù)到buffer cache里的1個buffer時, 會發(fā)生物理IO, 假如這個過程需要10毫秒, 那么在這10毫米中這個buffer狀態(tài)就是READ.
3.6 ? XREC
???? 這個buffer 處于介質(zhì)恢復狀態(tài)中.
3.7 ? IREC
???? 這個buffer 處于實例恢復狀態(tài)中.
????? 關于XREC和IREC狀態(tài)以后再詳細討論,? 在Oracle正常使用中是不會出現(xiàn)這兩種狀態(tài)的buffer的.
4. 做個例子啦
??? 步驟1:首先查看一下HR.CL_DEPT這張表, 有6行數(shù)據(jù)啦~
????
???? 步驟2:? 跟住清空buffer_cache里的數(shù)據(jù), 注意在生產(chǎn)中執(zhí)行這個動作很危險, 因為跟住就會有大量的物理IO了.
?
?????? 步驟3:? 執(zhí)行下面sql語句, 能查詢某個數(shù)據(jù)庫 對象的buffer占用狀態(tài):
select o.object_name,
?????? decode(state, 0, 'free', 1, 'xcur' , 2, 'scur', 3, 'cr',
???????????????????? 4, 'read', 5, 'mrec' , 6, 'irec', 7, 'write',
???????????????????? 8, 'pi') as state,
?????? count(1) blocks
from x$bh b, dba_objects o
where b.obj = o.data_object_id
? and o.object_name = 'CL_DEPT'
? and o.owner = 'HR'
group by o.object_name, state
order by blocks desc;
?執(zhí)行一下:
?
可以見到這個表還占用5個buffer ,但是狀態(tài)是free的, 所以這個5個buffer是沒有數(shù)據(jù)的.
那為什么會占住5個free呢, 是因為我們剛才select過一次, 即使執(zhí)行清空buffer cache,但是在CRC鏈區(qū)可能還存在buffer的頭部信息指向, 但是buffer數(shù)據(jù)就的確被清空了.
隔2分鐘再看一次:
發(fā)現(xiàn)只占用4個free了, 所以CRC鏈里的信息也會慢慢清除的.
?
步驟4: 進行select 操作, 然后再查看buffer狀態(tài)
首先select一下這個張表, 因為buffer里并沒有這張表的緩存,所以會發(fā)生物理IO啦:
這時查看buffer狀態(tài):
見到6個 xcur buffer了, 也說明有6個block的被寫入到buffer cache里面
步驟5: 用當前session (SYS 帳號)修改一條數(shù)據(jù), 但并不提交
步驟6: 用另1個session (scott 帳號)查看這張表, 看到的是修改前的數(shù)據(jù)
步驟7: 只所以會見到修改前的數(shù)據(jù), 是因為構(gòu)造了CR塊啦!
?
?
?步驟8: SYS這個session提交修改, 然后scott 在查看1次表, 見到修改后的數(shù)據(jù).
?
?
?步驟9: 再查看buffer 狀態(tài)
發(fā)現(xiàn)CR 塊并不會馬上消失哦
? ? ?
?
總結(jié)
以上是生活随笔為你收集整理的Oracle buffer状态深入剖析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle Database_buff
- 下一篇: 转:linux svn常用命令