偷学自大神Roger的博客,自己再做实验:
http://www.killdb.com/2013/01/29/archivelog-%E6%A8%A1%E5%BC%8F%E4%B8%8B%EF%BC%8Cdatafileheader%E6%8D%9F%E5%9D%8F%EF%BC%8C%E5%A6%82%E4%BD%95%E6%81%A2%E5%A4%8D%EF%BC%9F.html
Archivelog 模式下,datafile header损坏,如何恢复?
这里我来模拟下如果是datafile header block损坏的情况下,如何去手工恢复?
—先模拟文件头损坏的情况
BBED> info all
File# Name Size(blks)
----- ---- ----------
1 /oradata/node3/system01.dbf 96000
2 /oradata/node3/sysaux01.dbf 69120
3 /oradata/node3/undotbs01.dbf 6400
4 /oradata/node3/users01.dbf 640
5 /oradata/node3/example01.dbf 44240
6 /oradata/node3/test1.dbf 25600
复制一个块覆盖file 6 的block 1
BBED> copy file 4 block 5 to file 6 block 1
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 0 to 511 Dba:0x01800001
------------------------------------------------------------------------
1ea20000 05000001 163f0000 00000104 90c10000 04000000 80800f00 00000000
......
<32 bytes per line>
BBED> sum apply
Check value for File 6, Block 1:
current = 0xc190, required = 0xc190
BBED> set file 6 block 1
FILE# 6
BLOCK# 1
BBED> verify
DBVERIFY - Verification starting
FILE = /oradata/node3/test1.dbf
BLOCK = 1
Block 1 is corrupt
Corrupt block relative dba: 0x01000001 (file 0, block 1)
Bad header found during verification
Data in bad block:
type: 30 format: 2 rdba: 0x01000005
last change scn: 0x0000.00003f16 seq: 0x1 flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x3f161e01
check value in block header: 0xc190
computed block checksum: 0x0
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 1
Total Blocks Influx : 0
Message 531 not found; product=RDBMS; facility=BBED
此时启动数据库,你会遇到类似如下错误:
SQL> startup
ORACLE instance started.
Total System Global Area 839282688 bytes
Fixed Size 2257880 bytes
Variable Size 545262632 bytes
Database Buffers 289406976 bytes
Redo Buffers 2355200 bytes
Database mounted.
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt
SQL> recover datafile 6;
ORA-00283: recovery session canceled due to errors
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt
部分情况下,这种情况下是可以recover的。如果说文件头block彻底损坏完了。是不能直接进行修复的。
如果你有备份,那么你可以从备份里面将该datafile restore 出来,然后再去进行recover。
这种情况下归档全可以尝试重新创建 datafile
SQL> alter database create datafile 6 as '/oradata/node3/test1.dbf';
alter database create datafile 6 as '/oradata/node3/test1.dbf'
*
ERROR at line 1:
ORA-01178: file 6 created before last CREATE CONTROLFILE, cannot recreate
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
针对这种情况下,创建datafile后,其scn是非常老的,如果你需要进行recover,那么需要从该scn开始至今的所有archivelog。
在这样的情况下起手就可以手工去修复数据文件头,如果是损坏很严重,那么你可以偷懒,从其他datfile copy过去,然后再修改。
+++++++++++ 如下是整个修复的过程,我这里来简单演示一下。
BBED> copy file 4 block 1 to file 6 block 1
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 0 to 511 Dba:0x01800001
------------------------------------------------------------------------
0ba20000 01000001 00000000 00000104 81520000 00000000 0004200b f2cdfb78
4e4f4445 33000000 c00c0000 80020000 00200000 04000300 00000000 00000000
......
<32 bytes per line>
BBED> map /v
File: /oradata/node3/test1.dbf (6)
Block: 1 Dba:0x01800001
------------------------------------------------------------
Data File Header
struct kcvfh, 860 bytes @0
struct kcvfhbfh, 20 bytes @0
struct kcvfhhdr, 76 bytes @20
ub4 kcvfhrdb @96
struct kcvfhcrs, 8 bytes @100
ub4 kcvfhcrt @108
ub4 kcvfhrlc @112
struct kcvfhrls, 8 bytes @116
ub4 kcvfhbti @124
struct kcvfhbsc, 8 bytes @128
ub2 kcvfhbth @136
ub2 kcvfhsta @138
struct kcvfhckp, 36 bytes @484
ub4 kcvfhcpc @140
ub4 kcvfhrts @144
ub4 kcvfhccc @148
struct kcvfhbcp, 36 bytes @152
ub4 kcvfhbhz @312
struct kcvfhxcd, 16 bytes @316
sword kcvfhtsn @332
ub2 kcvfhtln @336
text kcvfhtnm[30] @338
ub4 kcvfhrfn @368
struct kcvfhrfs, 8 bytes @372
ub4 kcvfhrft @380
struct kcvfhafs, 8 bytes @384
ub4 kcvfhbbc @392
ub4 kcvfhncb @396
ub4 kcvfhmcb @400
ub4 kcvfhlcb @404
ub4 kcvfhbcs @408
ub2 kcvfhofb @412
ub2 kcvfhnfb @414
ub4 kcvfhprc @416
struct kcvfhprs, 8 bytes @420
struct kcvfhprfs, 8 bytes @428
ub4 kcvfhtrt @444
ub4 tailchk @8188
这里有个关键性的问题是,我们需要修改哪些地方?
++++++ 第一修改的地方:rdba_kcbh
BBED> p kcvfhbfh
struct kcvfhbfh, 20 bytes @0
ub1 type_kcbh @0 0x0b
ub1 frmt_kcbh @1 0xa2
ub1 spare1_kcbh @2 0x00
ub1 spare2_kcbh @3 0x00
ub4 rdba_kcbh @4 0x01000001
ub4 bas_kcbh @8 0x00000000
ub2 wrp_kcbh @12 0x0000
ub1 seq_kcbh @14 0x01
ub1 flg_kcbh @15 0x04 (KCBHFCKV)
ub2 chkval_kcbh @16 0x5281
ub2 spare3_kcbh @18 0x0000
这里是0×0100001,表示file 4 block 1,我们要将其改成正确的值:file 6 block 1 。 后面block号不变,即应该是0x01800001
BBED> modify /x 01008001 offset 4
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 4 to 515 Dba:0x01800001
------------------------------------------------------------------------
01008001 00000000 00000104 81520000 00000000 0004200b f2cdfb78 4e4f4445
33000000 c00c0000 80020000 00200000 04000300 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0f3f0000 00000000 8dc92131 93de0a36 d4a16b00 00000000 00000000 00000000
00000000 00000400 a6000000 b2e90a36 a4000000 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 04000000 05005553 45525300 00000000 00000000 00000000
00000000 00000000 00000000 04000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 bcdd0a36
cda06b00 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0ca86b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000
<32 bytes per line>
++++++ 第2个修改的地方:kccfhfsz 即文件大小
BBED> p kcvfhhdr
struct kcvfhhdr, 76 bytes @20
ub4 kccfhswv @20 0x00000000
ub4 kccfhcvn @24 0x0b200400
ub4 kccfhdbi @28 0x78fbcdf2
text kccfhdbn[0] @32 N
text kccfhdbn[1] @33 O
text kccfhdbn[2] @34 D
text kccfhdbn[3] @35 E
text kccfhdbn[4] @36 3
text kccfhdbn[5] @37
text kccfhdbn[6] @38
text kccfhdbn[7] @39
ub4 kccfhcsq @40 0x00000cc0
ub4 kccfhfsz @44 0x00000280 --这里
s_blkz kccfhbsz @48 0x00
ub2 kccfhfno @52 0x0004
ub2 kccfhtyp @54 0x0003
ub4 kccfhacid @56 0x00000000
ub4 kccfhcks @60 0x00000000
text kccfhtag[0] @64
......
首先你可以从os上去查看数据文件的实际大小,如下:
[oracle@node3 node3]$ ll test1.dbf
-rw-r----- 1 oracle dba 209723392 Mar 17 04:25 test1.dbf
不过需要注意一点的是,dbfile的大小应该你操作系统上看到的实际大小减去一个db block_size,因为还存在一个os block header。
(209723392-8192)/8192=25600
25600=6400
BBED> modify /x 00640000 offset 44
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 44 to 555 Dba:0x01800001
------------------------------------------------------------------------
00640000 00200000 06000300 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 aafc6900 00000000
98210936 93de0a36 d4a16b00 00000000 00000000 00000000 00000000 00000400
a8000000 921a0b36 a7000000 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
07000000 05005445 53543100 00000000 00000000 00000000 00000000 00000000
00000000 06000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 93a26b36 00000000
6fdf0a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
++++++ 第3个修改的地方:kccfhfno datafile文件号
BBED> modify /x 06 offset 52
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 52 to 563 Dba:0x01800001
------------------------------------------------------------------------
06000300 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 0f3f0000 00000000 8dc92131 93de0a36
d4a16b00 00000000 00000000 00000000 00000000 00000400 a6000000 b2e90a36
a4000000 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 04000000 05005553
45525300 00000000 00000000 00000000 00000000 00000000 00000000 04000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 0ca86b00 00000000 9be90a36 01000000
01000000 c2090000 10009a04 02000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
++++++ 第4个修改的地方:kscnbas v$datafile.create_change#
BBED> p kcvfhcrs
struct kcvfhcrs, 8 bytes @100
ub4 kscnbas @100 0x00003f0f
ub2 kscnwrp @104 0x0000
6945962 转换为 16进制 69fcaa
BBED> modify /x aafc69 offset 100
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 100 to 611 Dba:0x01800001
------------------------------------------------------------------------
aafc6900 00000000 8dc92131 93de0a36 d4a16b00 00000000 00000000 00000000
00000000 00000400 a6000000 b2e90a36 a4000000 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 04000000 05005553 45525300 00000000 00000000 00000000
00000000 00000000 00000000 04000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 bcdd0a36
cda06b00 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0ca86b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000
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>
++++++++ 第5个修改的地方:kcvfhcrt 表示v$datafile.create_time
BBED> p kcvfhcrt
ub4 kcvfhcrt @108 0x3121c98d
此时你将数据库mount,可以通过v$datafile直接查询得知,如下:
SQL> set lines 120
SQL> col creation_time_file for 999999999999999
SQL> col creation_name_scn for 999999999999999
SQL> select file#,to_char(creation_time,'yyyy-mm-dd hh24:mi:ss') creation_time_file,
(to_char(creation_time,'yyyy')-1988)*12*31*24*3600+
(to_char(creation_time,'mm')-1)*31*24*3600
+(to_char(creation_time,'dd')-1)*24*3600
+to_char(creation_time,'hh24')*3600
+to_char(creation_time,'mi')*60
+to_char(creation_time,'ss') creation_name_scn
from v$datafile order by 1;
FILE# CREATION_TIME_FILE CREATION_NAME_SCN
---------- -------------------------------------- -----------------
1 2013-08-24 11:37:33 824297853
2 2013-08-24 11:37:37 824297857
3 2013-08-24 12:07:19 824299639
4 2013-08-24 11:37:49 824297869
5 2016-02-02 12:03:21 902750601
6 2016-03-15 16:28:08 906568088 --转换后 36092198
6 rows selected.
或者你可以直接dump controlfile,然后从trace中获得该信息。
修改为如下:
BBED> modify /x 98210936 offset 108
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 108 to 619 Dba:0x01800001
------------------------------------------------------------------------
98210936 93de0a36 d4a16b00 00000000 00000000 00000000 00000000 00000400
a6000000 b2e90a36 a4000000 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
04000000 05005553 45525300 00000000 00000000 00000000 00000000 00000000
00000000 04000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000
9be90a36 01000000 01000000 c2090000 10009a04 02000000 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>
++++++++ 第6个修改的地方:kcvfhtsn 表示表空间号v$datafile.ts#
BBED> p kcvfhtsn
sword kcvfhtsn @332 4
通过v$datafile查询结果:
SQL> select file#,ts# from v$datafile order by 1;
FILE# TS#
---------- ----------
1 0
2 1
3 2
4 4
5 6
6 7
修改为:
BBED> modify /x 07 offset 332
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 332 to 843 Dba:0x01800001
------------------------------------------------------------------------
07000000 05005553 45525300 00000000 00000000 00000000 00000000 00000000
00000000 04000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000
9be90a36 01000000 01000000 c2090000 10009a04 02000000 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 0d000d00 0d000100
00000000 00000000 00000000 02000001 03000000 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>
++++++++ 第7个修改的地方: kcvfhrfn v$datafile.rfile# 即相对文件号
BBED> p kcvfhrfn
ub4 kcvfhrfn @368 0x00000004
BBED> modify /x 06 offset 368
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 368 to 879 Dba:0x01800001
------------------------------------------------------------------------
06000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000 9be90a36
01000000 01000000 c2090000 10009a04 02000000 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 0d000d00 0d000100 00000000
00000000 00000000 02000001 03000000 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>
+++++++++ 第8个修改的地方:kcvfhtnm 表空间名称即v$tablespace.name
BBED> p kcvfhtnm
text kcvfhtnm[0] @338 U
text kcvfhtnm[1] @339 S
text kcvfhtnm[2] @340 E
text kcvfhtnm[3] @341 R
text kcvfhtnm[4] @342 S
text kcvfhtnm[5] @343
text kcvfhtnm[6] @344
text kcvfhtnm[7] @345
text kcvfhtnm[8] @346
text kcvfhtnm[9] @347
text kcvfhtnm[10] @348
text kcvfhtnm[11] @349
text kcvfhtnm[12] @350
text kcvfhtnm[13] @351
text kcvfhtnm[14] @352
text kcvfhtnm[15] @353
text kcvfhtnm[16] @354
text kcvfhtnm[17] @355
text kcvfhtnm[18] @356
text kcvfhtnm[19] @357
text kcvfhtnm[20] @358
text kcvfhtnm[21] @359
text kcvfhtnm[22] @360
text kcvfhtnm[23] @361
text kcvfhtnm[24] @362
text kcvfhtnm[25] @363
text kcvfhtnm[26] @364
text kcvfhtnm[27] @365
text kcvfhtnm[28] @366
text kcvfhtnm[29] @367
BBED> d /v offset 338
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 338 to 849 Dba:0x01800001
-------------------------------------------------------
55534552 53000000 00000000 00000000 l USERS...........
00000000 00000000 00000000 00000600 l ................
......
<16 bytes per line>
我们只要知道表空间名称,转换一下即可:
SQL> select name from v$tablespace where ts#=7;
NAME
------------------------------------------------------------
TEST1
SQL> select dump('TEST1',16) from dual;
DUMP('TEST1',16)
--------------------------------------------------------
Typ=96 Len=5: 54,45,53,54,31
SQL> select dump ('USERS',16) from dual;
DUMP('USERS',16)
--------------------------------------------------------
Typ=96 Len=5: 55,53,45,52,53
修改为:
BBED> modify /x 54455354
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 338 to 849 Dba:0x01800001
------------------------------------------------------------------------
54455354 53000000 00000000 00000000 00000000 00000000 00000000 00000600
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 0000bcdd 0a36cda0 6b000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000ca8 6b000000 00009be9 0a360100
00000100 0000c209 00001000 9a040200 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 00000d00 0d000d00 01000000 00000000
00000000 00000200 00010300 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
BBED> modify /x 31 offset 342
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 342 to 853 Dba:0x01800001
------------------------------------------------------------------------
31000000 00000000 00000000 00000000 00000000 00000000 00000600 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 0000bcdd 0a36cda0 6b000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000ca8 6b000000 00009be9 0a360100 00000100
0000c209 00001000 9a040200 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 00000d00 0d000d00 01000000 00000000 00000000
00000200 00010300 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
这里补充一下,如果你的表空间名称跟实际不符,可能还需要修改kcvfhtln,表示长度。我这里是users即为5.
BBED> p kcvfhtln
ub2 kcvfhtln @336 0x0005
test1 长度也是5 不用改啦
BBED> sum apply
Check value for File 2, Block 1:
current = 0x24ca, required = 0x24ca
尝试启动数据库
SQL> startup
ORACLE instance started.
Total System Global Area 839282688 bytes
Fixed Size 2257880 bytes
Variable Size 545262632 bytes
Database Buffers 289406976 bytes
Redo Buffers 2355200 bytes
Database mounted.
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt
看来还有地方不对,我们来查询下v$datafile看下信息:
SQL> SELECT file#,rfile#,CREATION_CHANGE#,CHECKPOINT_CHANGE# ,UNRECOVERABLE_CHANGE#,LAST_CHANGE#,OFFLINE_CHANGE# FROM v$datafile ORDER BY 1;
FILE# RFILE# CREATION_CHANGE# CHECKPOINT_CHANGE# UNRECOVERABLE_CHANGE# LAST_CHANGE# OFFLINE_CHANGE#
---------- ---------- ---------------- ------------------ --------------------- ------------ ---------------
1 1 7 7053783 0 7053779
2 2 1834 7053783 0 7053779
3 3923328 7053783 0 7053779
4 4 16143 7053783 0 7053779
5 5952510 7053783 0 7053779
6 6 6945962 7053971 0 0
可以看到检查点信息不一致,这是因为开始我为了演示模拟中途open过了一次。
而目前datafile 6的实际scn跟实际不符:
BBED> set file 6 block 1
FILE# 6
BLOCK# 1
BBED> p kcvfhckp
struct kcvfhckp, 36 bytes @484
struct kcvcpscn, 8 bytes @484
ub4 kscnbas @484 0x006ba80c --checkpoint转换后 7055372
ub2 kscnwrp @488 0x0000
ub4 kcvcptim @492 0x360ae99b --checkpoint time 转换 906684827
ub2 kcvcpthr @496 0x0001
union u, 12 bytes @500
struct kcvcprba, 12 bytes @500
ub4 kcrbaseq @500 0x00000001
ub4 kcrbabno @504 0x000009c2
ub2 kcrbabof @508 0x0010
ub1 kcvcpetb[0] @512 0x02
ub1 kcvcpetb[1] @513 0x00
ub1 kcvcpetb[2] @514 0x00
ub1 kcvcpetb[3] @515 0x00
ub1 kcvcpetb[4] @516 0x00
ub1 kcvcpetb[5] @517 0x00
ub1 kcvcpetb[6] @518 0x00
ub1 kcvcpetb[7] @519 0x00
然而我们datafile 2的实际情况如何呢? 来查询v$datafile确认一下:
SQL> select file#,to_char(CHECKPOINT_TIME,'yyyy-mm-dd hh24:mi:ss') CHECKPOINT_TIME_file,
(to_char(CHECKPOINT_TIME,'yyyy')-1988)*12*31*24*3600+
(to_char(CHECKPOINT_TIME,'mm')-1)*31*24*3600
+(to_char(CHECKPOINT_TIME,'dd')-1)*24*3600
+to_char(CHECKPOINT_TIME,'hh24')*3600
+to_char(CHECKPOINT_TIME,'mi')*60
+to_char(CHECKPOINT_TIME,'ss') CHECKPOINT_TIME_scn
from v$datafile order by 1; 2 3 4 5 6 7 8
FILE# CHECKPOINT_TIME_FILE CHECKPOINT_TIME_SCN
---------- -------------------------------------- -------------------
1 2016-03-17 00:06:46 906682006
2 2016-03-17 00:06:46 906682006
3 2016-03-17 00:06:46 906682006
4 2016-03-17 00:06:46 906682006
5 2016-03-17 00:06:46 906682006
6 2016-03-17 00:10:23 906682223
6 rows selected.
我们可以看到,checkpoint scn和time都不对,所以还需要修改下:
7053971 =6BA293
BBED> modify /x 93a26b offset 484
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 484 to 995 Dba:0x01800001
------------------------------------------------------------------------
93a26b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000
......
<32 bytes per line>
906682223 = 360ADF6F
BBED> d /v offset 492
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 492 to 1003 Dba:0x01800001
-------------------------------------------------------
9be90a36 01000000 01000000 c2090000 l ...6............
10009a04 02000000 00000000 00000000 l ................
......
<16 bytes per line>
BBED> set file 6 block 1 offset 492
FILE# 6
BLOCK# 1
OFFSET 492
BBED> modify /x 6fdf0a36 offset 492
File: /oradata/node3/test1.dbf (6)
Block: 1 Offsets: 492 to 1003 Dba:0x01800001
------------------------------------------------------------------------
6fdf0a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000
......
<32 bytes per line>
修改完成之后我们可以通过dbv来检查下,看看文件头修改是否都正确,如下:
[oracle@node3 trace]$ dbv file=/oradata/node3/test1.dbf start=1 end=2
DBVERIFY: Release 11.2.0.4.0 - Production on Thu Mar 17 03:42:23 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
DBVERIFY - Verification starting : FILE = /oradata/node3/test1.dbf
DBVERIFY - Verification complete
Total Pages Examined : 2
Total Pages Processed (Data) : 0
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing (Index): 0
Total Pages Processed (Other): 2
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 0
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 7039342 (0.7039342)
最后我们再来将数据库open,如下:
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01122:database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01207: file is more recent than control file - old control file
SQL> recover datafile 6;
ORA-00283: recovery session canceled due to errors
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01207: file is more recent than control file - old control file
遇到过程了,先不要着急,我们来看下这个错误是什么意思? 从字面上的含义来看,意思是说改datafile的信息
可能比controlfile中的部分信息还要新,这个有可能,因为最开始我offline 文件后,open过,然后接着修改
文件头的时候的信息又是参考其他datafile header block来的,所以file 2的信息可能比以前的信息要新。
既然如此,那么我们重建下controlfile即可,注意要用noresetlogs方式创建:
SQL> oradebug setmypid
Statement processed.
SQL> alter database backup controlfile to trace;
Database altered.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/node3/node3/trace/node3_ora_31312.trc
CREATE CONTROLFILE REUSE DATABASE "NODE3" NORESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 '/oradata/node3/redo01.log' SIZE 50M BLOCKSIZE 512,
GROUP 2 '/oradata/node3/redo02.log' SIZE 50M BLOCKSIZE 512,
GROUP 3 '/oradata/node3/redo03.log' SIZE 50M BLOCKSIZE 512
-- STANDBY LOGFILE
DATAFILE
'/oradata/node3/system01.dbf',
'/oradata/node3/sysaux01.dbf',
'/oradata/node3/undotbs01.dbf',
'/oradata/node3/users01.dbf',
'/oradata/node3/example01.dbf',
--'/oradata/node3/test1.dbf'
CHARACTER SET WE8MSWIN1252;
SQL> alter database open;
Database altered.
SQL> select name,file#,status from v$datafile;
NAME FILE# STATUS
--------------------------------
/oradata/node3/system01.dbf 1 SYSTEM
/oradata/node3/sysaux01.dbf 2 ONLINE
/oradata/node3/undotbs01.dbf 3 ONLINE
/oradata/node3/users01.dbf 4 ONLINE
/oradata/node3/example01.dbf 5 ONLINE
/u01/app/oracle/product/11.2.0/db_1/dbs/MISSING00006 6 RECOVER
SQL> alter database rename file '/u01/app/oracle/product/11.2.0/db_1/dbs/MISSING00006' to '/oradata/node3/test1.dbf';
Database altered.
SQL> recover datafile 6;
Media recovery complete.
SQL> alter database datafile 6 online;
Database altered.
简单的小总结,针对文件头损坏的情况下,在恢复的情况下可能需要修复如下内容:
1. rdba_kcbh (offset 4)即使文件头block的rdba地址
2. kccfhfsz (offset 44) 即文件大小
3. kccfhfno (offset 52) 即datafile文件号
4. kscnbas (offset 100) 即v$datafile.create_change#
5. kcvfhcrt (offset 108) 即v$datafile.create_time
6. kcvfhtsn (offset 332) 即v$datafile.ts#,表示表空间号
7. kcvfhrfn (offset 368) 即v$datafile.rfile#, 表示相对文件号
8. kcvfhtnm (offset 338) 即v$tablespace.name,表示表空间名称(根据实际情况,可能还会需要修改kcvfhtln,表示表空间名称字符长度)
9. kscnbas (offset 484) 即checkpoint scn
10.kcvcptim (offset 492) 即last checkpoint time.
这个总结并不全面,可能很多情况还需要修改一些其他的地方,另外如果是system datafile,那么也会有所不同,比如oracle
数据库中的bootstrap$对象是存储在file 1 block 337中.而system 表空间的第一个datafile header中会有个root rdba地址是指向
bootstrap地址的,在11gR2版本中该地址变为file 1 block 521(不同版本可能有所差异).