select會訪問buffer cache裡哪種型別的data block,XCUR還是CR?
當我們以select一張表的時候,如果data block沒有在buffer cache裡,這個block就會被server process從磁碟讀取到buffer cache;如果能在buffer cache裡找到那麼直接訪問即可;v$bh.status表示了buffer cache裡block的型別,常見的有以下幾種
cr
free
pi <---RAC環境下才有
read
scur <---RAC環境下才有
write
xcur
在我的印象中Select操作總是與consistent這個關鍵字聯絡在一起,而DML操作總與current有關,因此select總是會訪問buffer cache裡cr型別的block。
其實不然:
當data block上尚有未完成的transaction時,如果新開一個session去select這個data block就會使用cr block,如果在原本的transaction裡去select就會使用xcur block
當data block上沒有未完成的transaction時,select這個data block就會使用xcur block
<--------x$bh裡的關鍵欄位含義-------->
x$bh.tch:block被訪問的次數
x$bh.flag:block是否為髒塊,同時還表示了其它一些資訊
x$bh.state:block的型別
###建立測試表connect scott/773946
create table t0427_1 as select * from all_users;
select distinct dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from t0427_1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
22065 4
###資料庫所使用的undo tablespace及對應的undo datafile
SQL> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string undotbs3
col name format a50
set linesize 130
select name,file# from v$datafile_header where tablespace_name='UNDOTBS3'
NAME FILE#
-------------------------------------------------- ----------
/oradata06/testaaaaa/undotbs3.dbf 10
###這裡我們開啟三個session,session 1用於執行DML和select、session 2執行select、session 3用來監控
---session 3: 起初buffer cache裡沒有block 4/22065
SQL> select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
no rows selected
---session 1:執行update,記錄Transaction使用到的undo資訊
update t0427_1 set username='XXX' where username='XDB';
select UBAFIL,UBABLK from v$transaction;
UBAFIL UBABLK
---------- ----------
10 59589
---session 3:update後觀察buffer cache裡的data block和undo block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 xcur 2 Y
4 22065 cr 1 N
在update真正執行之前先把要修改的block複製出一份cr的副本
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=10 and dbablk=59589;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
10 59589 xcur 2 Y
---session 2:執行第一輪select
select * from t0427_1 where username='XDB';
USERNAME USER_ID CREATED
------------------------------ ---------- -----------------
XDB 59 20150629 16:00:05
---session 3: 第一輪後觀察data block和undo block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 xcur 2 Y
4 22065 cr 1 N
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=10 and dbablk=59589;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
10 59589 xcur 3 Y
可以看到對於data block:4/22065 新增了一個cr block,對於undo block:10/59589 tch從2增加為3,表示其被訪問過1次了;這裡大概的作一下解釋:session 2訪問4/22065時發現buffer cache裡已經有這個block的兩個copy,一個xcur,一個cr,在我們看來最簡單的方法莫過於把cr block直接拿過來使用,但是oracle並不這麼認為,隱含引數_db_block_max_cr_dba預設值為6,決定了同一個data block最多能有6個型別為cr的副本,所以oracle會新生成一個block 4/22065的cr copy,我們還注意到undo block 10/59589也被訪問了一次,因此生成cr copy的過程:oracle將data block 4/22065的xcur copy再複製一份出來,然後透過這份新複製出來的xcur副本頭部的Transaction資訊(Uba、SCN等)找到包含before-image的undo block 10/59589,進行rollback,最終形成一份嶄新的cr copy
---session 2:執行第二輪select :
select * from t0427_1 where username='XDB';
USERNAME USER_ID CREATED
------------------------------ ---------- -----------------
XDB 59 20150629 16:00:05
---session 3: 第二輪後觀察data block和undo block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 2 Y
4 22065 cr 1 N
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=10 and dbablk=59589;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
10 59589 xcur 4 Y
第二輪執行完後,data block:4/22065 的cr copy數量從2增加為3,undo block 10/59589 tch從3增加為4
---session 2:執行第三輪select:
select * from t0427_1 where username='XDB';
USERNAME USER_ID CREATED
------------------------------ ---------- -----------------
XDB 59 20150629 16:00:05
---session 3 :第三輪後觀察data block和undo block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 2 Y
4 22065 cr 1 N
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=10 and dbablk=59589;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
10 59589 xcur 5 Y
第三輪執行完後,data block:4/22065 的cr copy數量從3增加為4,undo block 10/59589 tch從4增加為5
可見,在沒有達到_db_block_max_cr_dba指定值的情況下cr copy數會持續增加
---session 1:執行select操作查詢自己尚未commit的修改結果
select * from t0427_1 where username='XXX';
USERNAME USER_ID CREATED
------------------------------ ---------- -----------------
XXX 59 20150629 16:00:05
---session 3 :觀察data block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 3 Y <---增加了1
4 22065 cr 1 N
至此,我們發現session 1執行update時會訪問xcur型別的block,在select自己沒有commit的修改結果是訪問的也是xcur型別的block;而當session 1沒有commit的情況下,session 2自始至終select的都是CR型別的block。
現在我們讓session 1 commit
---session 1:commit之前的修改
commit;
---session 2:繼續select表t0427_1
select * from t0427_1 where username='XDB';
no rows selected
---session 3:由於session 1 commit了,只觀察data block
select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 4 Y
4 22065 cr 1 N
因為session 1 commit了,所以4/22065這個block內容的一致性得到了保證,session 2最後的這次select訪問的就是xcur型別的block;
過不久發生了incremental checkpoint
SQL> select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 4 N <---Dirty從Y變為N
4 22065 cr 1 N
---session 2:再一次select表t0427_1
select * from t0427_1 where username='XDB';
no rows selected
---session 3:這次訪問的還是xcur型別對應的那個block
SQL> select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 cr 1 N
4 22065 xcur 5 N
4 22065 cr 1 N
---session 3: flush buffer_cache
alter system flush buffer_cache;
SQL> select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
---session 2:select t0427_1表
select * from t0427_1 where username='XXX';
USERNAME USER_ID CREATED
------------------------------ ---------- -----------------
XXX 59 20150629 16:00:05
SQL> select file#, dbablk, 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') status,tch,decode(bitand(flag,1), 0, 'N', 'Y') dirty from x$bh where file#=4 and dbablk=22065;
FILE# DBABLK STATUS TCH D
---------- ---------- ---------- ---------- -
4 22065 xcur 1 N <---仍然是xcur
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
4 22065 free 0 N
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-2089994/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Cache 和 Buffer 的區別在哪裡?
- cr塊和latch buffer cache chainAI
- 透過Buffer cache瞭解data block在DML操作下的狀態演變BloC
- data buffer cache的一點總結。
- data buffer cache的一點總結 -- 轉
- buffer與cache的區別
- Buffer和Cache的區別
- Buffer 與 Cache 的區別
- Cache 和 Buffer的區別
- Linux Buffer/Cache 的區別Linux
- buffer 與cache 的區別2
- Block的型別BloC型別
- linux cache與buffer的區別Linux
- 專家 vs 多面手:你是哪種型別的開發者?型別
- 關於ORACLE裡的buffer cache 的命中率Oracle
- 到底哪種型別的錯誤資訊會阻止business transaction的儲存型別
- js 判斷是手機訪問,還是pc訪問JS
- 深入理解Block之Block的型別BloC型別
- 從Data Buffer中讀資料是單塊讀,還是多塊讀?
- How To Identify a Hot Block Within The Database Buffer Cache. [ID 163424.1]IDEBloCDatabase
- Oracle10g data buffer cache的記憶體結構Oracle記憶體
- 《演算法改變世界》:看看你是哪種型別的人?演算法型別
- Block內部訪問例項變數會出現的問題BloC變數
- QZ面試被問select......for update會鎖表還是鎖行lor面試
- Ask Hoegh(5)——buffer cache和buffer有什麼區別?
- Cache 和 Buffer 有什麼區別?
- ASM Buffer Cache是用來做什麼的!ASM
- PHP識別電腦還是手機訪問網站PHP網站
- [BUG反饋]資料快取型別改為Redis後DATA_CACHE_TIME的問題快取型別Redis
- 12種型別黑客 你遇見過哪種?型別黑客
- 判斷javaScript變數是Ojbect型別還是Array型別JavaScript變數型別
- page cache與buffer cache的關係
- Buffer Cache 原理
- cache buffer chainAI
- Linux free中buffer與cache區別Linux
- cache 訪問頻率的思考
- 資料中心代理有哪幾種型別?型別
- 美國伺服器有哪幾種型別?伺服器型別