Oracle 塊清除說明

來源:互聯網
上載者:User
一. Block Cleanout 說明

文章的整理參考:http://www.orawh.com/60.html

block clean out 是指把一個塊中的資料從 dirty 變為 clean,等於告訴後面的人,這個塊裡面的資料是乾淨的,可以放心的使用,本質上是更改 block header 中的一個標誌位。

 

當commit 的時候,如果被commit 的資料區塊還在 data buffer 中也要被cleanout,因為 commit 的時候並不一定修改block header (delay block cleanout) 。

 

Clean out有2種: fast commitcleanout和delayed blockcleanout:

   oracle有一個modified block list結構,用來記錄每個transaction更改過的block,每個transaction大約可以記錄10%buffer cache這多的modified block。這部分block就是當發生commit的時候,oracle可以根據modified block list定位到那些塊並做fast commit cleanout。

如果一個transaction修改的塊超過10%buffer cache,那麼超過的塊就執行delayed block cleanout。當做fast commit cleanout時,oracle不會清理 Row lockslb標誌位,ITL lck標誌位。

       另一種情況是delayed block cleanout,當transaction還未commit或rollback時modified block已經被寫回磁碟,當發生commit時oracle並不會把block重新讀入做cleanout,這樣成本太高.而是把cleanout留到下一次對此塊的訪問(select,update)時完成。

當delayed cleanout時候如果undo segment header的transaction table slot還沒有被覆蓋,那麼可以找回該事務遞交的exact scn,如果slot已經被覆蓋(ITL被覆蓋),那麼將會使用undo segment header中的control scn來做為upper bound scn。

      

       當發生fast commit cleanout,系統將transaction提交時刻的scn作為commit scn,更新block上 itl和undo segment header的Transaction table的slot上的 scn,並修改block scn,三者是一致的。

       發生delayed block cleanout的時候,之前的transaction commit更新的只是undo segment header Transactiontable 上的slot scn,而並未做block上的更新,等待下次使用此block的時候,更新block scn和itl狀態。block scn和itl的更新又分2種情況:

       (1)當不產生slot重用的時候, delayedblock cleanout時,根據Transactiontable裡面的資訊,更新blockscn和itl上的Scn/Fsc為transaction曾經提交時候的scn。
       (2)當產生slot重用的時候,更新對應itl上scn為undo segment 上的control scn,而block scn 為delayed block cleanout發生時刻的scn。

 

二. Cleanout 測試2.1 Fast commit cleanout

--建立table並insertinto data

SYS@anqing2(rac2)> create table dvd(idnumber);

Table created.

SYS@anqing2(rac2)> insert into dvdvalues(1);

1 row created.

SYS@anqing2(rac2)> insert into dvdvalues(2);

1 row created.

SYS@anqing2(rac2)> commit;

Commit complete.

SYS@anqing2(rac2)>

 

--查看table 的block資訊

SYS@anqing2(rac2)> Selectdbms_rowid.rowid_block_number(rowid) block,dbms_rowid.rowid_relative_fno(rowid) fileno, ora_rowscn from dvd;

 

    BLOCK     FILENO ORA_ROWSCN

---------- ---------- ----------

   305914          1    7316063

   305914          1    7316063

 

--更新並提交資料

SYS@anqing2(rac2)> update dvd set id=77where id=1;

1 row updated.

SYS@anqing2(rac2)> commit;

Commit complete.

 

--Dump block

SYS@anqing2(rac2)> oradebug setmypid

Statement processed.

SYS@anqing2(rac2)> alter system dumpdatafile 1 block 305914;

System altered.

SYS@anqing2(rac2)> oradebugtracefile_name

/u01/app/oracle/admin/anqing/udump/anqing2_ora_31100.trc

 

Dump 檔案的ITL 資訊如下:

Itl          Xid                  Uba         Flag Lck        Scn/Fsc

0x01  0x0010.011.000003c6 0x01400038.00ae.2d  C---    0 scn 0x0000.006fa25f

0x02   0x0011.01c.000004a9  0x01400070.0111.26  --U-   1  fsc 0x0000.006fa357

 

       此時的操作就是fast commit cleanout,並且該操作不清除lck,lb標誌。

 

2.2 Delayed block cleanout

       當我們update 資料之後,並且沒有commit,此時我們flush buffer cache,將修改的資料區塊,flush 到硬碟,那麼此時發生的就是delay block cleanout。

 

SYS@anqing2(rac2)> update dvd set id=168where id=2;    

1 row updated.

SYS@anqing2(rac2)> Selectxidusn,xidslot,xidsqn from v$transaction;

   XIDUSN    XIDSLOT     XIDSQN

---------- ---------- ----------

       13         15        980

 

SYS@anqing2(rac2)> alter system flushbuffer_cache;

System altered.

--flush 會把我們之前修改的block 直接flush 到硬碟,雖然我們沒有commit。

 

SYS@anqing2(rac2)> commit;

Commit complete.

--此時我們commit了,正常情況下,會去修改block裡的相關SCN。 但是實際上此時Oracle 並沒有回去修改這些block,因為再次調用成本太大。 Oracle只更新了undosegment header slot。 當下次再次訪問這個block時,在根據undo segment 來更新block scn 和 itl 上的scn。 如果此時對應的undo segment 已經不存在,就會出發ORA-01555,快照過舊的錯誤。

 

--此時還沒有再次訪問之前的block,即沒有發生delayedblock clean,我們dump 一下資料區塊

SYS@anqing2(rac2)> alter system dumpdatafile 1 block 305914;

System altered.

 

Itl           Xid                  Uba         Flag Lck        Scn/Fsc

0x01  0x000d.00f.000003d4 0x0140002e.00aa.21  ----   
1  fsc 0x0000.00000000

0x02  0x0011.01c.000004a9 0x01400070.0111.26  --U-   
1  fsc 0x0000.006fa357

 

tab 0, row 0, @0x1f9a

tl: 6 fb: --H-FL-- lb: 0x2  cc: 1

col 0: [ 2]  c1 4e

tab 0, row 1, @0x1f8d

tl: 7 fb: --H-FL-- lb: 0x1  cc: 1

col 0: [ 3]  c2 02 45

--結果是fast commit cleanout

 

--訪問之前之前的block,產生delayedblock cleanout

SYS@anqing2(rac2)> select * from dvd;

 

        ID

----------

       77

      168

 

--在次dump block

SYS@anqing2(rac2)> alter system dumpdatafile 1 block 305914;

System altered.

 

Itl           Xid                  Uba         Flag Lck        Scn/Fsc

0x01  0x000d.00f.000003d4 0x0140002e.00aa.21  C---   
0 scn 0x0000.006fa4e6

0x02  0x0011.01c.000004a9 0x01400070.0111.26  C---   
0 scn 0x0000.006fa357

 

tab 0, row 0, @0x1f9a

tl: 6 fb: --H-FL-- lb: 0x0  cc: 1

col 0: [ 2]  c1 4e

tab 0, row 1, @0x1f8d

tl: 7 fb: --H-FL-- lb:0x0  cc: 1

col 0: [ 3]  c2 02 45

--做了delayed block cleanout之後,itl 變成了SCN。 此時lck,lb標誌為都被清零,scn也是從undo segment header transactiontable slot裡面得到。如果undosegment header 上的slot被覆蓋了,那麼會把undo segment 上的control scn拿來當作upper bound scn。

 

 

(1) fb :

K = Cluster Key(Flags may change meaning ifthis is set to show HASH cluster) 
C = Cluster table member 
H = Head piece of row 
D = Deleted row 
F = First data piece 
L = Last data piece 
P = First column continues from previous piece 
N = Last column continues in next piece

(2)lb : 和上面的 ITL 的lck相對應表示這行是否被 lock 了

 

在汪海的blog 上,他還測試了另一個結論:

       當delayed block cleanout 發生時,依賴與undo segment來保證,如果undo segment 被刪除了,那麼會Oracle 會使用system 資料表空間下的undo$ 基表來保證delayed block cleanout。

       關於這個測試過程,參考汪海的blog:http://www.orawh.com/60.html

 

 

三. Delayed block cleanout 與select redo 說明與測試

       一般來說,select 是不會產生redo的。 但如果發生了delayed block cleanout,那麼就會產生redo。 當然這隻是一種情況,開啟審計等,也會造成select 產生redo。

       在itpub上有2個相關的連結: 

       http://www.itpub.net/thread-1467473-1-2.html

       http://www.itpub.net/thread-728163-1-1.html

 

下面我們測試一下。

 

--先對dvd insert 一些測試資料

SYS@anqing2(rac2)> Declare

 2  I number;

 3  Begin

 4  For I in 1..100 loop

 5  Insert into dvd values(i);

End loop;

Commit;

End;

/

 6    7    8   9 

PL/SQL procedure successfully completed.

 

SYS@anqing2(rac2)> select count(*) fromdvd;

 

 COUNT(*)

----------

      102

 

--直接select

SYS@anqing2(rac2)> set timing on

SYS@anqing2(rac2)> set autot on stat

SYS@anqing2(rac2)> select count(*) fromdvd;

 

 COUNT(*)

----------

      102

 

Elapsed: 00:00:00.00

 

Statistics

----------------------------------------------------------

         0  recursive calls

         0  db block gets

         3  consistent gets

         0  physical reads

          0  redo size

       412  bytes sent via SQL*Net toclient

       400  bytes received via SQL*Netfrom client

         2  SQL*Net roundtrips to/fromclient

         0  sorts (memory)

         0  sorts (disk)

         1  rows processed

 

測試產生的redo 為0.

 

--製造delayedblock cleanout

SYS@anqing2(rac2)> update dvd set id=0where id>50;

52 rows updated.

Elapsed: 00:00:00.02

Statistics

----------------------------------------------------------

         5  recursive calls

        52  db block gets

         8  consistent gets

         0  physical reads

     14424  redo size

       667  bytes sent via SQL*Net toclient

       564  bytes received via SQL*Netfrom client

         3  SQL*Net roundtrips to/fromclient

         1  sorts (memory)

         0  sorts (disk)

        52  rows processed

 

SYS@anqing2(rac2)> alter system flush buffer_cache;

System altered.

Elapsed: 00:00:00.10

SYS@anqing2(rac2)> commit;

Commit complete.

Elapsed: 00:00:00.02

 

--再此select

SYS@anqing2(rac2)> select count(*) fromdvd;

 

 COUNT(*)

----------

      102

 

Elapsed: 00:00:00.02

 

Statistics

----------------------------------------------------------

         0  recursive calls

         0  db block gets

         4  consistent gets

         2  physical reads

        116  redo size

       412  bytes sent via SQL*Net toclient

       400  bytes received via SQL*Netfrom client

         2  SQL*Net roundtrips to/fromclient

         0  sorts (memory)

         0  sorts (disk)

         1  rows processed

 

 

--第三次select

SYS@anqing2(rac2)> select count(*) fromdvd;

 COUNT(*)

----------

      102

 

Elapsed: 00:00:00.00

 

Statistics

----------------------------------------------------------

         0  recursive calls

         0  db block gets

         3  consistent gets

         0  physical reads

         0  redo size

       412  bytes sent via SQL*Net toclient

       400  bytes received via SQL*Netfrom client

         2  SQL*Net roundtrips to/fromclient

         0  sorts (memory)

         0  sorts (disk)

         1  rows processed

 

       第二次select 因為delayed block cleanout的原因,需要做一些善後工作,所以產生了redo。 當第三次select 時,第二次select 已經把工作做完了,所以沒有產生redo。

 

       簡單的就是說: select 在delayed block cleanout 時也會產生redo。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.