天天看點

db_block_checking與db_block_checksum

--************************************

-- db_block_checking 與 db_block_checksum

    db_block_checking與db_block_checksum兩個參數都是對block進行檢查,然而兩者很容易混淆。事實上,兩個參數中前者是對塊做邏

輯性檢查,後者則是做實體性檢查。兩者各司其職,并不沖突。下面分别給出具體描述。

1.db_block_checking

        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

2.db_block_checksum

        db_block_checksum 用于DBWn和direct loader資料塊寫入到磁盤時,基于塊内的所有位元組計算得出一個校驗值并将其寫入塊頭。

   在該參數設定為typical和full時,當讀入時候重新計算校驗和寫出時候的校驗對比,如果不同則認為是塊損壞。如果設定為FULL模式

   ,則基于update/delete應用程式語句級别的改變發生後,校驗值會被重新計算并寫入。同時對于日志塊,在寫入之前,同樣會生産校

   驗值并寫入到塊頭。該參數主要是防止IO硬體和IO子系統的錯誤。如果設定為OFF則隻對系統表空間有效。下面是該參數的設定參考。

   FALSE和TRUE是為了老版本的相容。

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

        Defaultvalue              TYPICAL

       Modifiable                   ALTER SESSION,ALTER SYSTEM

        Basic                          No

3.存在的問題

   如果db_block_checking = off,非系統表空間中資料在邏輯上可能已經損壞,但是 db_block_checksum 卻是無法檢查出來的(負責物

   理層面的校驗),原樣寫到磁盤原樣讀到記憶體,因為它隻校驗塊在寫出後和讀入之間是否發生變化而不檢查寫出前是否存在邏輯上的正确。

   有些情況下,比如索引塊損壞,造成通過索引無法獲得資料,但是讀索引塊的時候并沒有出1578錯誤,有可能是這個原因。

   SQL>ho oerr ora 1578

   01578,00000,"ORACLE data block corrupted (file # %s, block # %s)"

   // *Cause:  Thedatablockindicated was corrupted, mostly due tosoftware

   //          errors.

   // *Action: Try torestorethesegmentcontaining theblockindicated. This

   //          may involve dropping thesegmentandrecreating it. Ifthere

   //          isa tracefile,report theerrorsinit toyour ORACLE

   //          representative

4.db_block_checking和db_block_checksum這兩個參數對性能的影響

   下面的例子中做一個測試來檢視該參數對性能的影響。實際上,環境的不同将使得測試結果會大相庭徑。

      a. 建立測試對象        
SQL>select *  from v$version where rownum<2;

        BANNER
        ----------------------------------------------------------------------
        Oracle Database 11g Enterprise Edition Release 11.2.0.1.0- Production       

        SQL>show parameter db_block_che

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

        SQL>show user;

        USER is "SCOTT"

        SQL>create table test (col int) tablespace users nologging;  -->由于空間壓力在此不記錄日志

        Table created.      
    b. 修改兩個參數為FALSE       
SQL>alter system set db_block_checksum=FALSE;

       System  altered.

       SQL>set timing on;      
     c. 對測試表test中三次分别插入100,000行資料        
SQL> begin                                   -->第一次插入資料
         2  fori in1..1000000
         3  loop
         4    insert into test values(i);
         5  end loop;
         6  end;
         7  /

         PL/SQL procedure successfully completed.

         Elapsed: 00:00:59.57     

         SQL>commit;                           

         SQL>alter system check point;          

         SQL>@insert_test.sql                         -->第二次插入資料

         PL/SQL procedure successfully completed.

         Elapsed: 00:00:59.13

         SQL>commit;

         SQL>alter system check point;

         SQL>@insert_test.sql                        -->第三次插入資料

         PL/SQL procedure successfully completed.

         Elapsed: 00:00:56.87

         SQL>commit;

         SQL>alter system check point;      

從上面的結果可以看出插入100百萬條記錄所需的最長時間為56.87秒,最短的時間為59.13,平均時間為58.5233。

    d. 修改兩個參數為TRUE       
SQL>alter system set db_block_checksum=TRUE;

        SQL>alter system set db_block_checking=TRUE;

        SQL>show parameter db_block_ch

        NAME                                 TYPE        VALUE

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

        db_block_checking                    string      TRUE

        db_block_checksum                    string      TRUE      
    e. 再次測試表test中三次分别插入100,000行資料     
SQL>@insert_test.sql                    -->第一次插入資料

        PL/SQL procedure successfully completed.

        Elapsed: 00:02:58.01

        SQL>commit;

        SQL>alter system check point;

        SQL>@insert_test.sql                    -->第二次插入資料

        PL/SQL procedure successfully completed.

        Elapsed: 00:03:01.66

        SQL>commit;

        SQL>alter system checkpoint;            -->第三次插入資料

        SQL>@insert_test.sql

        PL/SQL procedure successfully completed.

        Elapsed: 00:02:49.15

        SQL>commit;

        SQL>alter system checkpoint;      

從上面的結果可以看出插入100百萬條記錄所需的最長時間為03:01.66秒,最短的時間為02:49.15,平均時間為02:57秒左右。

5.總結

   a. 對結果進行對比,可以看出當将兩個block參數設定為true時,其速度比為false時慢了近30%,不過此對比根據實際環境應有所不同。

   b. 對于性能上的差異而言,當設定兩個block參數設定為true時,将需要更多的CPU資源來生成校驗值以及進行記憶體塊的驗證。同時,

        該操作容易引起redo copy latch的持有時間增加和引起這個latch的競争。

   c. 不管db_block_checking和db_block_checksum這兩個參數的值為何值,SYSTEM表空間都會進行做checking和checksum,可以通過隐含

        參數_db_always_check_system_ts設定為FALSE,但為了SYSTEM表空間資料安全,不建議将這個隐含參數值設定為FALSE。

   d. checksum 通過校驗結構夠保證寫入到資料檔案與從資料檔案讀取的塊前後兩者是一緻的。通常對于偵測由于IO操作(磁盤損壞,硬

        件損壞)引發的壞塊。但它并不偵測在記憶體中已經出錯的資料塊。不管錯誤與否,DBWn後會将其寫入到資料檔案。