看到崔华的【怎样在windows上用DD配合ultraEdit修改数据】文章后进行试验时我发现了这个Checksum值为0的情况。这里是我的记录。我们都知道data block的offset位置是16-17是Checksum Value,它属于data block的Cache Layer,作用是oracle在通过DBWn常规写或者User Process直接路径加载时通过checksum value用来得知由底层磁盘是否损坏,那么这个Checksum Value可以为0吗?, 这个value如果为0,岂不是oracle会把它认为是个坏块儿?(跟checksum值是否为0没有任何关系),主要为了是防止IO硬件和IO子系统的错误。随后崔华在【数据块里的checksum值可能是0吗】又帮我验证了这个问题。
BBED里边能够看到的信息是
BBED> p kcbh
struct kcbh, 20 bytes @0
<-More->
ub2chkval_kcbh @16 0xddf1
<-More->
Dump里边能够看到的信息是
buffer tsn: 4 rdba: 0x0200000c (4/42772)
scn: 0x0000.000cd37a seq: 0x02 flg: 0x04 tail: 0x486e0602
frmt: 0x02 chkval: 0xddf1 type: 0x06=trans data
Checksum Value不为零的情况
BBED> set file 6
FILE# 6
BBED> set block 32
BLOCK# 32
BBED> dump
File:/u02/oradata/ETMCDB.dbf (6)
Block: 32 Offsets: 0 to 511 Dba:0x01800020
------------------------------------------------------------------------
06a20000 2000800152750900 00000106 084d0000 01000000 b9cd0000 dd740900
00000000 0200320019008001 08002900 48010000 d50d8000 f0000a00 01200000
52750900 0000000000000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100ffff1400 ec0fd80f d80f0000 0100ec0f 00000000 00000000
<-More->
00000000 0000000000000000 00000000 00000000 00000000 00000000 00000000
如何让不为零的checksumvalue变为零
Shutdownimmediate;后,随便找个offset,主要是找到一个值为0x0000的地方,因为根据checksum值的算法,如果数据块里有两个byte的值是0x0000,则算这个数据块的checksum值的时候,就相当于没有这两个byte。现在我在没改之前,块里记录的checksum值是0x084d,当我找到了一个值为0x0000的地方后,再把这个改为0x084d,那么根据checksum值的算法,这个块的checksum值就变成0了。不过不能直接修改offset为16、17的地方那里本身就是用来记录checksum值的。
所以就在70的地方再修改成0x084d。
BBED> set offset 70
OFFSET 70
BBED> dump
File: /u02/oradata/ETMCDB.dbf(6)
Block:32 Offsets: 64to 575 Dba:0x01000020
------------------------------------------------------------------------
00000000 00000000 00000000 00000000 00000000 00000000 0000000000000000
<-More->
BBED> modify /x 084d
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /dras20/testdb/drsys01.dbf (4)
Block:32 Offsets: 64to 575 Dba:0x01000020
------------------------------------------------------------------------
084d0000 00000000 00000000 00000000 00000000 00000000 0000000000000000
<-More->
BBED> sum apply
Check value for File 6, Block 32:
current = 0x0000, required = 0x0000
BBED> dump
File:/u02/oradata/ETMCDB.dbf (6)
Block: 32 Offsets: 0 to 511 Dba:0x01800020
------------------------------------------------------------------------
06a20000 2000800152750900 00000106 00000000 01000000 b9cd0000 dd740900
00000000 0200320019008001 08002900 48010000 d50d8000 f0000a00 01200000
52750900 0000000000000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100ffff1400 ec0fd80f d80f0000 0100ec0f 00000000 00000000
<-More->
00000000 0000000000000000 00000000 00000000 00000000 00000000 00000000
BBED>verify
SQL> Startup
做些查询都没有问题。看来Checksum Value为0是允许的这个是由Oracle算法决定的。
总结到这里又引出了一个问题,那么Oracle是如何标记坏块的哪?最近也综合看了几个案例稍后整理一下