数据块Checksum值为0的情况
时间:2010-11-19 来源:xxd
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
Checksum Value为零的情况
BBED> dump
File: /u02/oradata/test01.dbf (8)
Block: 13 Offsets: 0 to 511 Dba:0x0200000d
------------------------------------------------------------------------
06a20000 0d000002 db6d3000 0000010200000000 01000000 83d90000 d16d3000
00000000 02003200 09000002 05000300 b3050000 260f8000 40033300 01200000
db6d3000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100 ffff1400 19080508 05080000 01001908 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
SQL> selectid,rowid,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid)from t1;
ID ROWIDDBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)||'_'||DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
---------- ---------------------------------------------------------------------------------------------------
4 AAANmDAAIAAAAANAAA 8_13
如何让不为零的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 /x084d
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是如何标记坏块的哪?最近也综合看了几个案例稍后整理一下
http://www.laoxiong.net/how_to_mark_corruption_block_and_recovery.html Oracle怎样标记坏块及一次数据恢复
http://www.laoxiong.net/ora_8103_erro.html 记一次ORA-8103错误的处理
http://dbsnake.com/2009/02/ddchecksum.html 利用dd修改checksum值的过程
http://dbsnake.com/2009/02/bbedchecksum.html 利用BBED修改checksum值的过程