oracle block corrupt 壞塊

    總體上來講,oracle的壞塊可以分爲兩種情景:物理損壞和邏輯損壞。物理損壞是由於存儲等原因造成的,致使oracle在處理數據塊時發現塊的checksum不一致。邏輯損壞多是由於oracle的bug或者內存錯誤引起,通過檢測數據塊的checksum並不會發現什麼問題,但是在邏輯上這些塊已經發生了損壞。

oracle通過兩個參數來控制對物理損壞和邏輯損壞的檢測:

SQL> show parameter db_block_check

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_block_checking		     string	 FALSE
db_block_checksum		     string	 TRUE

     db_block_checking 是當block發生任何變化的時候進行邏輯上的完整性和正確性檢查。該參數能夠避免內存中數據塊的損壞。塊的檢查將對系統會有1%到10%的性能影響。取決於對db_block_checking參數的設置。頻繁的DML將使得塊檢查帶來更多的開銷。在系統負荷允許的情形下建議設置爲full。該參數對SYSTEM表空間始終是處於“打開”狀態,而不管該參數是否設置爲OFF。下面是該參數的設置參考。FALSE和TRUE是爲了老版本的兼容。

        Property             Description

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

        Parameter type         String

        Syntax                         DB_BLOCK_CHECKING = { FALSE| OFF| LOW | MEDIUM | TRUE| FULL}  -->OFF(=FALSE),FULL(=TRUE)

        Defaultvalue              FALSE

        Modifiable                  ALTER SYSTEM

        Basic                          No

      這裏有一點需要注意,即只有在對數據塊發生修改時,db_block_checking纔會發生作用。如

SQL> show parameter db_block_check

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_block_checking		     string	 FALSE
db_block_checksum		     string	 TRUE
SQL> alter system flush buffer_cache;

System altered.

SQL> select * from scott.s2;//查詢時沒有問題

T1	   T2
---------- --------------------
51809	   lllll
51888	   SC
51574	   PK_DEPT
51573	   DEPT
1575EMP,  5
51576	   PK_EMP
51578	   SALGRADE

7 rows selected.

SQL> update scott.s2 set t2='aaaa' where t1='51809';//修改也沒有問題

1 row updated.

SQL> commit;

Commit complete.

SQL> alter system flush buffer_cache;

System altered.

SQL> alter system set db_block_checking=true;

System altered.

SQL> select * from scott.s2;//查詢是沒有問題的

T1	   T2
---------- --------------------
51809	   aaaa
51888	   SC
51574	   PK_DEPT
51573	   DEPT
1575EMP,  5
51576	   PK_EMP
51578	   SALGRADE

7 rows selected.

SQL> update scott.s2 set t2='bbbb' where t1 = '51809';//修改時觸發了邏輯檢測
update scott.s2 set t2='bbbb' where t1 = '51809'
             *
ERROR at line 1:
ORA-00607: Internal error occurred while making a change to a data block
ORA-00600: internal error code, arguments: [kddummy_blkchk], [5], [20], [6113],
[], [], [], []


SQL> select * from scott.s2;//發現邏輯錯誤後,oracle將塊標記爲壞塊,此時數據塊無法訪問了
select * from scott.s2
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 5, block # 20)
ORA-01110: data file 5: '/home/app/oraten/oradata/oraten/tbs201.dbf'


db_block_checksum 用於DBWn和direct loader數據塊寫入到磁盤時,基於塊內的所有字節計算得出一個校驗值並將其寫入塊頭。在該參數設置爲typical和full時,當讀入時候重新計算校驗和寫出時候的校驗對比,如果不同則認爲是塊損壞。如果設置爲FULL模式,則基於update/delete應用程序語句級別的改變發生後,校驗值會被重新計算並寫入。同時對於日誌塊,在寫入之前,同樣會生產校驗值並寫入到塊頭。該參數主要是防止IO硬件和IO子系統的錯誤。如果設置爲OFF則只對系統表空間有效。下面是該參數的設置參考。FALSE和TRUE是爲了老版本的兼容。

        Property             Description

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

        Parameter type         String

        Syntax                         DB_BLOCK_CHECKSUM = { OFF| FALSE| TYPICAL | TRUE| FULL}  -->OFF(=FALSE),FULL(=TRUE)

        Defaultvalue              TYPICAL

       Modifiable                   ALTER SESSION,ALTER SYSTEM

        Basic                          No


對於性能上的差異而言,當設置兩個block參數設置爲true時,將需要更多的CPU資源來生成校驗值以及進行內存塊的驗證。同時,該操作容易引起redo copy latch的持有時間增加和引起這個latch的競爭。不管db_block_checking和db_block_checksum這兩個參數的值爲何值,SYSTEM表空間都會進行做checking和checksum,可以通過隱含參數_db_always_check_system_ts設置爲FALSE,但爲了SYSTEM表空間數據安全,不建議將這個隱含參數值設置爲FALSE。


我們已經知道,oracle 將壞塊分爲物理和邏輯損壞兩種,那麼當oracle發現物理或者邏輯損壞之後是如何標記數據塊從而使之後的操作知道該塊是損壞塊的那?

對於物理損壞,oracle不會進行任何的處理,在進行後續處理時oracle會重新計算checksum,只要發現checksum不一致則認爲該塊時物理損壞,並拋出01578錯誤。

對於邏輯損壞,當oracle第一次對數據塊進行邏輯檢測時,會拋出ora 600等錯誤,並修改數據塊中的標記位,當下次訪問該數據塊時,oracle檢測標誌位,如果發現標誌位以置爲邏輯損壞,則拋出ora 01578錯誤。當使用DBMS_REPAIR對壞塊進行修改時,如果時物理損壞不作任何處理,如果時邏輯損壞,修改數據塊的標誌位。


在數據塊中存在兩個位置表示數據塊爲邏輯損壞(不標示物理損壞),如下:

BBED> map /v
 File: /home/app/oraten/oradata/oraten/tbs201.dbf (5)
 Block: 20                                    Dba:0x01400014
------------------------------------------------------------
 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0       
    ub1 type_kcbh                           @0       
    ub1 frmt_kcbh                           @1       
    ub1 spare1_kcbh                         @2       
    ub1 spare2_kcbh                         @3       
    ub4 rdba_kcbh                           @4       
    ub4 bas_kcbh                            @8       
    ub2 wrp_kcbh                            @12      
    <strong>ub1 seq_kcbh                            @14  </strong>    
    ub1 flg_kcbh                            @15      
    ub2 chkval_kcbh                         @16      
    ub2 spare3_kcbh                         @18      

 struct ktbbh, 96 bytes                     @20      
    ub1 ktbbhtyp                            @20      
    union ktbbhsid, 4 bytes                 @24      
    struct ktbbhcsc, 8 bytes                @28      
    b2 ktbbhict                             @36      
    ub1 ktbbhflg                            @38      
    ub1 ktbbhfsl                            @39      
    ub4 ktbbhfnx                            @40      
    struct ktbbhitl[3], 72 bytes            @44      

 struct kdbh, 14 bytes                      @124     
    ub1 kdbhflag                            @124     
    b1 kdbhntab                             @125     
    b2 kdbhnrow                             @126     
    sb2 kdbhfrre                            @128     
    sb2 kdbhfsbo                            @130     
    sb2 kdbhfseo                            @132     
    b2 kdbhavsp                             @134     
    b2 kdbhtosp                             @136     

 struct kdbt[1], 4 bytes                    @138     
    b2 kdbtoffs                             @138     
    b2 kdbtnrow                             @140     

 sb2 kdbr[7]                                @142     

 ub1 freespace[7905]                        @156     

 ub1 rowdata[127]                           @8061    

<strong> ub4 tailchk                                @8188</strong>

BBED> set offset 14
	OFFSET         	14

BBED> dump /v count 12
 File: /home/app/oraten/oradata/oraten/tbs201.dbf (5)
 Block: 20      Offsets:   14 to   25  Dba:0x01400014
-------------------------------------------------------
 <strong>ff</strong>0425fe 00000100 0000fcca          l ..%.........

 <16 bytes per line>

BBED> set offset 8188
	OFFSET         	8188

BBED> dump /v count 12
 File: /home/app/oraten/oradata/oraten/tbs201.dbf (5)
 Block: 20      Offsets: 8188 to 8191  Dba:0x01400014
-------------------------------------------------------
 <strong>ff</strong>060000                            l ....
這裏的ff即標示數據塊位邏輯損壞塊,我們可以將其手工修改位01 或者 02 從而取消邏輯損壞標示。


對於已經標示爲邏輯損壞的數據塊,dbv等工具的檢測結果如下:

Total Blocks Examined         : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing   (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing   (Index): 0
Total Blocks Empty            : 0
Total Blocks Marked Corrupt   : 0
Total Blocks Influx           : 0

而對於沒有標示的邏輯損壞,dbv等工具檢測結果如下:

Total Blocks Examined         : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing   (Data) : 1
Total Blocks Processed (Index): 0
Total Blocks Failing   (Index): 0
Total Blocks Empty            : 0
Total Blocks Marked Corrupt   : 0
Total Blocks Influx           : 0


對於物理損壞,dbv檢測結果如下
DBVERIFY - Verification complete

Total Blocks Examined         : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing   (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing   (Index): 0
Total Blocks Empty            : 0
Total Blocks Marked Corrupt   : 1
Total Blocks Influx           : 0


對於dbms_repair包,如果是物理損壞,則REPAIR_TABLE的marked_corrupt列始終爲true,fix方法並不會發生作用。對於邏輯損壞,首先repair_table 的marked_corrupt列爲false,fix方法修正後,marked_corrupt修改爲true,此時數據塊的標誌位已發生修改。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章