物件有多少個資料塊緩衝在Data buffer中

tanxiaoke88發表於2009-10-25

物件有多少個資料塊緩衝在Da<wbr>ta buffer中

為了詳細說明具體的情況,先建立一個測試表,並且插入一定的記錄進去。

Piner@10gR2>create table test(a int);
Table created.
Piner@10gR2>begin
2 for i in 1..5000 loop
3 insert into test values(i);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
Piner@10gR2>commit;
Commit complete
如以上,先建立了一個叫test的表,並插入了5000條記錄,插入記錄後,用showspace儲存過程分析一下表的空間使用情況。關於這個儲存過程的具體程式碼,在本書的附錄B中可以獲得,因為這個儲存過程本身很通用,這裡就不多介紹這個儲存過程本身了。
Piner@10gR2>set serveroutput on
Piner@10gR2>exec show_space('TEST');
Total Blocks............................16
Total Bytes.............................131072
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................4
Last Used Ext BlockId...................17
Last Used Block.........................8
PL/SQL procedure successfully completed.
可以看到的是,這張TEST的表一共使用了16個塊,資料檔案id為4,我們再分析一下資料所在的Rowid。
Piner@10gR2>select f,b from (
2 select dbms_rowid.rowid_relative_fno(rowid) f,
3  dbms_rowid.rowid_block_number(rowid) b
4 from test) group by f,b;
            F             B
---------- ----------
4 12
4 20
4 13
4 21
4 14
4 16
4 22
4 15
8 rows selected.

可以看到,資料塊其實只佔用了8個塊,但是表合計佔用了16個資料塊,另外8個塊是什麼呢,它們是段頭,點陣圖塊等,是表中的額外開銷。至於這些塊的詳細資訊,在本書的表空間與資料分佈一章會有詳細介紹,現在只需要知道,該表有16個block,資料塊佔了8個。

注意:以上透過Rowid查詢使用了哪些資料塊,只適合沒有發生行遷移與行連結的情況下,如新建立的表,插入的小記錄是適合的。如果發生了行遷移與行連結,因為Rowid本身不發生變化,而資料塊的使用卻會發生變化。

那麼,現在分別查詢一下x$bh與v$bh,看看它們中間儲存了幾條記錄。

Piner@10gR2>select file#,dbablk,tch from x$bh where obj=
2 (select da<wbr>ta_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by dbablk;

FILE# DBABLK TCH
---------- ---------- ----------
4 9 2
4 10 2
4 11 5

4 12 2
4 13 2
4 14 2
4 15 2
4 16 2
4 17 2
4 18 2
4 19 2
4 20 2
4 21 2
4 22 2
4 23 2
4 24 2

16 rows selected.

Piner@10gR2>select file#,block#,status from v$bh where objd=
2 (select da<wbr>ta_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by block#;

FILE# BLOCK# STATUS
---------- ---------- -------
4 9 xcur
4 10 xcur
4 11 xcur
4 12 xcur
4 13 xcur
4 14 xcur
4 15 xcur
4 16 xcur
4 17 xcur
4 18 xcur
4 19 xcur
4 20 xcur
4 21 xcur
4 22 xcur
4 23 xcur
4 24 xcur

16 rows selected.

可以看到,這兩個查詢都返回了16條記錄,從塊9到塊24,中間包含了資料塊所在的8個塊。至於為什麼從塊9開始,在本書的後面也會有解釋,因為本地管理的資料檔案頭部,有8個保留塊。

看x$bh,返回了塊的觸控(touch count)資訊,表示了一個塊的熱點程度,現在最熱的是資料塊11,它並不是資料塊,而是段頭,透過如下查詢也可以證明:

Piner@10gR2>select header_file,header_block from dba_segments
  2  where owner='PINER' and segment_name='TEST';
HEADER_FILE HEADER_BLOCK
----------- ------------
4 11

看v$bh,返回了塊的狀態資訊,這裡是xcur,表示排斥狀態,被當前instance獨佔,也就是該塊正在被使用。常見的狀態還有scur,表示被instance共享;cr,表示一致性讀;free表示空閒狀態;read,表示正在從磁碟上讀取;write,表示正在被寫入。至於v$bh的這些狀態,也是從x$bh中透過decode函式根據欄位state解釋過來的,所以能看得更明白一些。

如果這個時候,手工清除一次Da<wbr>ta buffer,會發生什麼情況呢?

Piner@10gR2>alter system flush buffer_cache;
System altered.
Piner@10gR2>select file#,dbablk,tch from x$bh where obj=
2 (select da<wbr>ta_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by dbablk;
       FILE#       DBABLK          TCH
---------- ---------- ----------
4 9 0
4 10 0
4 11 0
4 12 0
4 13 0
4 14 0
4 15 0
4 16 0
4 17 0
4 18 0
4 19 0
4 20 0
4 21 0
4 22 0
4 23 0
4 24 0
16 rows selected.
Piner@10gR2>select file#,block#,status from v$bh where objd=
2 (select da<wbr>ta_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by block#;
       FILE#       BLOCK# STATUS
---------- ---------- -------
4 9 free
4 10 free
4 11 free
4 12 free
4 13 free
4 14 free
4 15 free
4 16 free
4 17 free
4 18 free
4 19 free
4 20 free
4 21 free
4 22 free
4 23 free
4 24 free
16 rows selected.

可以看到,x$bh中的塊的tch都恢復到0了,而v$bh中的狀態也都變成free了,但是記錄數並沒有發生變化,也就是說,資料塊雖然被刷到磁碟上去了,資料塊的記錄指標只不過是簡單地被清空而已。

http://holyane.blog.163.com/blog/static/4192717220099161104576/

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21340813/viewspace-1028127/,如需轉載,請註明出處,否則將追究法律責任。

相關文章