例項演示oracle資料塊狀態檢視v$bh的用法一 獲取oracle物件所佔用的資料塊

Davis_itpub發表於2018-06-27

1,建立一個測試表,test,並且插入10000行資料;
    SQL>  create table test (id int);

    SQL> begin
      2  for i in 1..10000 loop
      3  insert into test values(i)
      4  end loop;
      5  end;
      6  /

    SQL> commit


2
,建立一個儲存過程SHOW_SPACE
   

檔案:

show_spaceprocedure.rar

大小:

0KB

下載:

下載

create or replace procedure show_space

       ( p_segname in varchar2,

  p_owner   in varchar2 default user,

  p_type    in varchar2 default 'TABLE',

  p_partition in varchar2 default NULL )

as

    l_total_blocks              number;

    l_total_bytes               number;

    l_unused_blocks             number;

    l_unused_bytes              number;

    l_LastUsedExtFileId         number;

    l_LastUsedExtBlockId        number;

    l_last_used_block           number;

    procedure p( p_label in varchar2, p_num in number )

    is

    begin

        dbms_output.put_line( rpad(p_label,40,'.') ||

                              p_num );

    end;

begin

    dbms_space.unused_space

    ( segment_owner     => p_owner,

      segment_name      => p_segname,

      segment_type      => p_type,

      partition_name    => p_partition,

      total_blocks      => l_total_blocks,

      total_bytes       => l_total_bytes,

      unused_blocks     => l_unused_blocks,

      unused_bytes      => l_unused_bytes,

      last_used_extent_file_id => l_LastUsedExtFileId,

      last_used_extent_block_id => l_LastUsedExtBlockId,

      last_used_block => l_last_used_block );

    p( 'Total Blocks', l_total_blocks );

    p( 'Total Bytes', l_total_bytes );

    p( 'Unused Blocks', l_unused_blocks );

    p( 'Unused Bytes', l_unused_bytes );

    p( 'Last Used Ext FileId', l_LastUsedExtFileId );

    p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );

    p( 'Last Used Block', l_last_used_block );

end;

/

3,檢查表test的空間使用情況:
    SQL> exec show_space('TEST');
    Total Blocks............................24
    Total Bytes.............................196608
    Unused Blocks...........................3
    Unused Bytes............................24576
    Last Used Ext FileId....................1
    Last Used Ext BlockId...................62177
    Last Used Block.........................5
   
   
由上可知,該表test共佔用了24個資料塊,196608位元組,檔案ID1

4
獲得表test在資料塊中的分佈情況:
  SQL> 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 order by b;

         F          B
---------- ----------
         1      62162
         1      62163
         1      62164
         1      62165
         1      62166
         1      62167
         1      62168
         1      62169
         1      62170
         1      62171
         1      62172
         1      62173
         1      62174
         1      62175
         1      62176
         1      62177

16 rows selected.
   
由此可見,表test中的資料共佔用了16個資料塊,但是前面第三步中,發現該表佔用了24個資料塊。這是正常的,因為oracle本身會使用8個資料塊來記錄段頭、點陣圖塊等額外的資訊。我們現在只需要瞭解到,表test共佔用了24個資料塊,其中16個是資料,8個是表資訊。

5
,檢查x$bhv$bh的更新:
  SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects
  3  where wner='SYS'  and object_name='TEST')
  4  order by dbablk;

     FILE#     DBABLK        TCH
---------- ---------- ----------
         1      62161          6
         1      62162          3
         1      62163          3
         1      62164          3
         1      62165          3
         1      62166          3
         1      62167          3
         1      62168          3
         1      62169          3
         1      62170          3
         1      62171          3
         1      62172          3
         1      62173          3
         1      62174          3
         1      62175          3
         1      62176          3
         1      62177          3
         1      62178          3
         1      62179          3
         1      62180          3
         1      62181          3

21 rows selected.

  SQL> select file#,block#,status from v$bh where bjd=
  2  (select data_object_id from dba_objects
  3  where wner='SYS'  and object_name='TEST')
  4  order by block#;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1      62161 xcur
         1      62162 xcur
         1      62163 xcur
         1      62164 xcur
         1      62165 xcur
         1      62166 xcur
         1      62167 xcur
         1      62168 xcur
         1      62169 xcur
         1      62170 xcur
         1      62171 xcur
         1      62172 xcur
         1      62173 xcur
         1      62174 xcur
         1      62175 xcur
         1      62176 xcur
         1      62177 xcur
         1      62178 xcur
         1      62179 xcur
         1      62180 xcur
         1      62181 xcur

21 rows selected.

   
這裡可以看到,在v$bhx$bh中得到的資料塊,是從621616218121條記錄,但是在第四步中,我們知道資料是佔用了621626217716個資料庫,這裡,62161資料塊裡面存放的是段頭資訊,可以透過如下命令進行驗證:
  SQL> select header_file,header_block from dba_segments
  2  where wner='SYS' and segment_name='TEST';

    HEADER_FILE HEADER_BLOCK
    ----------- ------------
          1        62161

   
v$bh檢視中,我們可以看到這21個資料塊都是xcur狀態,表示這些資料塊都是排斥狀態,正在被使用,該欄位還有其他的型別,請參見資料塊的狀態型別

oracle緩衝塊(data block)狀態型別

    oracle的緩衝塊的管理機制一直沒有正式的釋出過,因此許多有經驗的oracle工程師都是透過經驗或者一下oracle文件中的註釋來推斷oracle的緩衝塊的管理機制的。

   
事實上,oralce使用v$bh檢視來記錄與資料緩衝(data buffer)相關的資訊,它詳細記錄了資料緩衝中每一個資料塊(data block)的狀態資訊。

   
v$bh檢視中的status欄位,記錄了資料塊的狀態,在非OPS、非RAC這樣的叢集環境中,資料塊的狀態會是下列幾種之一:xcurcrreadfree,使用者可以透過如下命令得到資料庫的狀態資訊:
    SQL> select unique status from v$bh;

   
其狀態的意義分別是:
    xcur
:(exclusive current)的意思,表示該資料塊處於排外模式;
    cr
:表示該資料塊是一個克隆(clone)的資料庫,可以執行共享的只讀操作;
    free
:表示這是一個限制的資料塊,oracle現在沒有使用它;
    read
:表示該資料塊正在從磁碟讀取資料;
    write
:表示資料庫正在往磁碟寫入資料;

   
在資料庫恢復過程中,該欄位還有另外兩個描述:mrecirec
    mrec
:(media recovery)表示資料塊處於介質恢復模式;
    irec
:(instance recovery)表示資料塊處於例項恢復模式;

   
RAC環境中,資料塊還有另外一種模式:
    scur
shared current),表示該資料庫正在和其他例項共享資料。
   

 


6
,清空資料快取:
    SQL> alter system flush buffer_cache;
Oracle9i裡,Oracle提供了一個內部事件,用以強制重新整理Buffer Cache,其語法為:

alter session set events 'immediate trace name flush_cache level 1';

或者:

alter session set events = 'immediate trace name flush_cache';

類似的也可以使用alter system系統級設定:

alter system set events = 'immediate trace name flush_cache';

Oracle10g中,Oracle提供一個新的特性,可以透過如下命令重新整理Buffer Cache:

alter system flush buffer_cache;

 


7
,重新檢查v$bhx$bh的內容:
  SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects
  3  where wner='SYS'  and object_name='TEST')
  4  order by dbablk;

     FILE#     DBABLK        TCH
---------- ---------- ----------
         1      62161          0
         1      62162          0
         1      62163          0
         1      62164          0
         1      62165          0
         1      62166          0
         1      62167          0
         1      62168          0
         1      62169          0
         1      62170          0
         1      62171          0
         1      62172          0
         1      62173          0
         1      62174          0
         1      62175          0
         1      62176          0
         1      62177          0
         1      62178          0
         1      62179          0
         1      62180          0
         1      62181          0

21 rows selected.

    SQL> select file#,block#,status from v$bh where bjd=
  2  (select data_object_id from dba_objects
  3  where wner='SYS'  and object_name='TEST')
  4  order by block#;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1      62161 free
         1      62162 free
         1      62163 free
         1      62164 free
         1      62165 free
         1      62166 free
         1      62167 free
         1      62168 free
         1      62169 free
         1      62170 free
         1      62171 free
         1      62172 free
         1      62173 free
         1      62174 free
         1      62175 free
         1      62176 free
         1      62177 free
         1      62178 free
         1      62179 free
         1      62180 free
         1      62181 free

21 rows selected.

   
這時候我們可以看到,x$bh中的tch欄位,已經由原來的3變成了0,同時v$bh檢視的資料塊狀態也變成了free,但是記錄的資料塊並沒有發生變化,還是在62161~62181這些資料塊中,這就是說,雖然資料已經被寫到了磁碟中,但是資料庫記錄的指標並沒有清空,僅僅是其狀態發生了改變。<SPAN

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

相關文章