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

-- 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是为了老版本的兼容。

        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

 

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后会将其写入到数据文件。

   e. checking 则正好弥补了checksum的不足,它对数据块在内存提供一致性验证,确保每一个数据块的完整性。

   f. 更多关于Block checking,http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1094433279412