我在"利用dd修改checksum值的过程"一文中详细描述了如何用dd修改一个指定block的checksum值的过程,现在我用BBED把这个改坏了的checksum值再改回来,如下的是详细的修改过程:
上述文章里我用dd改完后,从alert log里确实可以看到checksum值不对了:
Corrupt block relative dba: 0x2140000b (file 133, block 11)
Bad check value found during buffer read
Data in bad block -
type: 6 format: 2 rdba: 0x2140000b
last change scn: 0x0008.a9d
consistency value in tail: 0xa5ea0601
check value in block header: 0xb
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
Reread of rdba: 0x2140000b (file 133, block 11) found same corrupted data
SQL_astca>select id from dras.t1;
ID
----------
1
3
4
5
6
7
8
7 rows selected.
SQL_astca>BEGIN
2 DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
3 SCHEMA_NAME => 'DRAS',
4 OBJECT_NAME => 'T1',
5 OBJECT_TYPE => dbms_repair.table_object,
6 FLAGS => dbms_repair.NOSKIP_FLAG);
7 END;
8 /
PL/SQL procedure successfully completed.
SQL_astca>select id from dras.t1;
ERROR:
ORA-01578: ORACLE data block corrupted (file # 133, block # 11)
ORA-01110: data file 133: '/dras20/astca/test01.dbf'
no rows selected
SQL_astca>DECLARE num_fix INT;
2 BEGIN
3 num_fix := 0;
4 DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
5 SCHEMA_NAME => 'DRAS',
6 OBJECT_NAME=> 'T1',
7 OBJECT_TYPE => dbms_repair.table_object,
8 REPAIR_TABLE_NAME => 'REPAIR_TABLE',
9 FIX_COUNT=> num_fix);
10 DBMS_OUTPUT.PUT_LINE('num fix: ' || to_char(num_fix));
11 END;
12 /
num fix: 0
PL/SQL procedure successfully completed.
SQL_astca>select id from dras.t1;
ERROR:
ORA-01578: ORACLE data block corrupted (file # 133, block # 11)
ORA-01110: data file 133: '/dras20/astca/test01.dbf'
no rows selected
这里可以看到用DBMS_REPAIR.FIX_CORRUPT_BLOCKS是不能修正一个block的checksum值错误的。
SQL_astca>shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL_astca>exit
Disconnected from Oracle9i Enterprise Edition Release
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release
好,现在我们来用BBED修改这个block的checksum值:
$ pwd
/cadrasu01/app/oracle/product/
$ make -f ins_rdbms.mk $ORACLE_HOME/bin/bbed
make: 1254-002 Cannot find a rule to create target /cadrasu01/app/oracle/product/
Stop.
$ make -f ins_rdbms.mk BBED=$ORACLE_HOME/bin/bbed $ORACLE_HOME/bin/bbed
Linking BBED utility (bbed)
rm -f /cadrasu01/app/oracle/product/
ld -b64 -o /cadrasu01/app/oracle/product/
then echo "-bI:/cadrasu01/app/oracle/product/
$ pwd
/cadrasu01/app/oracle/product/
$ cat filelist.txt
1 /dras11/oradata/astca/system01.dbf 524288000
125 /dras21/astca/system02.dbf 1048576000
133 /dras20/astca/test01.dbf 1048576
$ cat par.bbd
blocksize=8192
listfile=filelist.txt
mode=edit
bbed默认password是blockedit
$ bbed parfile=par.bbd
Password:
BBED: Release
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> set file 133
FILE# 133
BBED> set block 11
BLOCK# 11
BBED> set offset 16
OFFSET 16
BBED> show
FILE# 133
BLOCK# 11
OFFSET 16
DBA 0x2140000b (557842443 133,11)
FILENAME /dras20/astca/test01.dbf
BIFILE bifile.bbd
LISTFILE filelist.txt
BLOCKSIZE 8192
MODE Edit
EDIT Unrecoverable
IBASE Dec
OBASE Dec
WIDTH 80
COUNT 512
LOGFILE log.bbd
SPOOL No
BBED> modify /x 0xC7
File: /dras20/astca/test01.dbf (133)
Block: 11 Offsets: 16 to 527 Dba:0x2140000b
------------------------------------------------------------------------
c
0001b6e8
00000000 00000000 00000000 00010001 ffff0014 0821080d 080d0000 00010821
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
BBED> sum apply
Check value for File 133, Block 11:
current = 0xc
BBED> exit
$ sqlplus '/ as sysdba';
SQL*Plus: Release
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.
SQL_astca>startup
ORACLE instance started.
Total System Global Area 824150304 bytes
Fixed Size 743712 bytes
Variable Size 285212672 bytes
Database Buffers 536870912 bytes
Redo Buffers 1323008 bytes
Database mounted.
Database opened.
SQL_astca>select id from dras.t1;
ID
----------
1
2
3
4
5
6
7
8
8 rows selected.
这里我们可以看到,checksum值已经被我们成功的改回来了!id为2的那条记录现在可以显示出来了!
sum apply 不就可以重新计算checksum 么?
为何还需要modify 这步呢?
你说的没错,sum apply的时候oracle会重新计算出正确的checksum值并写回去,我这里modify只是出于演示的目的。
关于checksum值的计算,你可以参考我写的另外一篇文章:
http://dbsnake.com/2009/06/compute-checksum.html