首页 > Linux操作系统 > Linux操作系统 > 从ASM磁盘中还原出文件(二)
前面已经找到了FILEDIR在[DISK]VOL1[AUN]22上
编写了如下脚本,生成dd出文件的语句
|
## FILEDIR所在AU位置 AUN=22;
## 从FILEDIR中获取AU位置 for((i=0;i<=256;i++)) do kfed p=read aun=$AUN blkn=$i dev=/dev/oracleasm/disks/VOL1|grep -E "kfbh.block.blk|xptr.au|xptr.disk|kfffdb.xtntcnt|kfffdb.break" done > kfed.out
## 格式化kfed.out ## 如果FILEDIR中存放的AU信息超过60条后,后续放的是一个KFBTYP_INDIRECT cat kfed.out|awk -F: '{ if($1~"blk"){split($2,arr," ;");BLK=arr[1];gsub(/ /,"",BLK)} else if($1~"xtntcnt"){split($2,arr," ;");CNT=arr[1];gsub(/ /,"",CNT)} else if($1~"break"){split($2,arr," ;");BREAK=arr[1];gsub(/ /,"",BREAK)} else if($1~"au"){ split($2,arr," ;");AU=arr[1];gsub(/ /,"",AU) SEQ=$1;gsub(/kfffde\[/,"",SEQ);gsub(/\].xptr.au/,"",SEQ) }else if($1~"disk"){ split($2,arr," ;");DISK=arr[1];gsub(/ /,"",DISK) if((DISK != 0 || AU != 0)&&(DISK != 65535 || AU != 4294967295)){ if(BREAK != SEQ){ # 这里应该修改成<,以支持break后的AU print BLK","DISK","AU","CNT","BREAK","SEQ }else{ print("for((i=0;i<=256;i++))") print("do") print(" kfed p=read aun="AU" blkn=$i dev=/dev/oracleasm/disks/VOL"(DISK+1)"|grep -E \"kfbh.block.obj|xptr.au|xptr.disk\"" ) print("done") } } } }'> kfed_tmp_1.out
## 从KFBTYP_INDIRECT中获取AU信息 cat kfed_tmp_1.out|grep -E "for|do|kfed|done" > kfed_tmp_1.sh
sh kfed_tmp_1.sh |awk -F: '{ if($1~"obj"){split($2,arr," ;");BLK=arr[1];gsub(/ /,"",BLK)} else if($1~"au"){ split($2,arr," ;");AU=arr[1];gsub(/ /,"",AU) }else if($1~"disk"){ split($2,arr," ;");DISK=arr[1];gsub(/ /,"",DISK) if((DISK != 0 || AU != 0)&&(DISK != 65535 || AU != 4294967295)){ print BLK","DISK","AU } } }' > kfed_tmp_2.out
## 格式化捕获的信息,生成DD脚本 cat kfed_tmp_1.out|grep -v -E "for|do|kfed|done"|awk -F, '{ print $1" 1 "NR" "$2" "$3 }' > kfed_tmp_3.out
cat kfed_tmp_2.out|awk -F, '{ print $1" 2 "NR" "$2" "$3 }' >> kfed_tmp_3.out
cat kfed_tmp_3.out|sort -k +1n -k +2n -k +3n|awk '{ if(FILENAME!=$1){ i=0; FILENAME=$1; }else{ i++; } print "dd if=/dev/oracleasm/disks/VOL"($4+1)" bs=1024k count=1 skip="$5" f=/tmp/"$1".dbf seek="i }' > dd.sh |
执行dd.sh
dd.sh的脚本大概是这样的:
dd if=/dev/oracleasm/disks/VOL2 bs=1024k count=1 skip=290 f=/tmp/264.dbf seek=0
dd if=/dev/oracleasm/disks/VOL1 bs=1024k count=1 skip=298 f=/tmp/264.dbf seek=1
dd if=/dev/oracleasm/disks/VOL3 bs=1024k count=1 skip=290 f=/tmp/264.dbf seek=2
dd if=/dev/oracleasm/disks/VOL2 bs=1024k count=1 skip=291 f=/tmp/264.dbf seek=3
dd if=/dev/oracleasm/disks/VOL1 bs=1024k count=1 skip=299 f=/tmp/264.dbf seek=4
dd if=/dev/oracleasm/disks/VOL3 bs=1024k count=1 skip=291 f=/tmp/264.dbf seek=5
dd if=/dev/oracleasm/disks/VOL1 bs=1024k count=1 skip=300 f=/tmp/265.dbf seek=0
dd if=/dev/oracleasm/disks/VOL1 bs=1024k count=1 skip=301 f=/tmp/266.dbf seek=0
dd if=/dev/oracleasm/disks/VOL2 bs=1024k count=1 skip=292 f=/tmp/266.dbf seek=1
[oracle10@zhangqiaoc ~]$ sh dd.sh
1+0 records in
1+0 records out
1+0 records in
1+0 records out
1+0 records in
……
[oracle10@zhangqiaoc tmp]$ ls -ltr|grep dbf
total 1247152
-rw-r--r-- 1 oracle10 dba 8388608 Aug 20 06:25 256.dbf
-rw-r--r-- 1 oracle10 dba 58720256 Aug 20 06:25 257.dbf
-rw-r--r-- 1 oracle10 dba 58720256 Aug 20 06:25 258.dbf
-rw-r--r-- 1 oracle10 dba 58720256 Aug 20 06:26 259.dbf
-rw-r--r-- 1 oracle10 dba 315621376 Aug 20 06:27 260.dbf
-rw-r--r-- 1 oracle10 dba 210763776 Aug 20 06:27 261.dbf
-rw-r--r-- 1 oracle10 dba 126877696 Aug 20 06:28 262.dbf
-rw-r--r-- 1 oracle10 dba 22020096 Aug 20 06:28 263.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 265.dbf
-rw-r--r-- 1 oracle10 dba 6291456 Aug 20 06:28 264.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 271.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 270.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 269.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 268.dbf
-rw-r--r-- 1 oracle10 dba 1048576 Aug 20 06:28 267.dbf
-rw-r--r-- 1 oracle10 dba 35651584 Aug 20 06:28 266.dbf
确定各个文件代表什么
先要找到KFBTYP_ALIASDIR块
************************************************************
i=1
while (($i<=50))
do
echo "[AUN]"$i
kfed p=find aun=$i dev=/dev/oracleasm/disks/VOL1|grep "type 11"|wc -l
i=$(($i+1))
done
i=1
while (($i<=50))
do
echo "[AUN]"$i
kfed p=find aun=$i dev=/dev/oracleasm/disks/VOL2|grep "type 11"|wc -l
i=$(($i+1))
done
i=1
while (($i<=50))
do
echo "[AUN]"$i
kfed p=find aun=$i dev=/dev/oracleasm/disks/VOL3|grep "type 11"|wc -l
i=$(($i+1))
done
输出就不贴了,可以找到KFBTYP_ALIASDIR在VOL3的AU15上
然后kfed这个块看看
************************************************************
i=0
while (($i<=256))
do
echo $i
kfed p=read aun=15 blkn=$i dev=/dev/oracleasm/disks/VOL2|grep -E "name|fnum"|grep -v -E "length=0|0x00000000"
i=$(($i+1))
done
0
kfade[0].name: ASM10 ; 0x034: length=5
kfade[0].fnum: 4294967295 ; 0x064: 0xffffffff
1
kfade[0].name: CONTROLFILE ; 0x034: length=11
kfade[0].fnum: 4294967295 ; 0x064: 0xffffffff
kfade[1].name: ONLINELOG ; 0x080: length=9
kfade[1].fnum: 4294967295 ; 0x0b0: 0xffffffff
kfade[2].name: DATAFILE ; 0x0cc: length=8
kfade[2].fnum: 4294967295 ; 0x0fc: 0xffffffff
kfade[3].name: TEMPFILE ; 0x118: length=8
kfade[3].fnum: 4294967295 ; 0x148: 0xffffffff
kfade[4].name: PARAMETERFILE ; 0x164: length=13
kfade[4].fnum: 4294967295 ; 0x194: 0xffffffff
kfade[5].name: spfileASM10.ora ; 0x1b0: length=15
kfade[5].fnum: 265 ; 0x1e0: 0x00000109
kfade[6].name: ARCHIVELOG ; 0x1fc: length=10
kfade[6].fnum: 4294967295 ; 0x22c: 0xffffffff
2
kfade[0].name: Current ; 0x034: length=7
kfade[0].fnum: 256 ; 0x064: 0x00000100
3
kfade[0].name: group_1 ; 0x034: length=7
kfade[0].fnum: 257 ; 0x064: 0x00000101
kfade[1].name: group_2 ; 0x080: length=7
kfade[1].fnum: 258 ; 0x0b0: 0x00000102
kfade[2].name: group_3 ; 0x0cc: length=7
kfade[2].fnum: 259 ; 0x0fc: 0x00000103
4
kfade[0].name: SYSTEM ; 0x034: length=6
kfade[0].fnum: 260 ; 0x064: 0x00000104
kfade[1].name: UNDOTBS1 ; 0x080: length=8
kfade[1].fnum: 261 ; 0x0b0: 0x00000105
kfade[2].name: SYSAUX ; 0x0cc: length=6
kfade[2].fnum: 262 ; 0x0fc: 0x00000106
kfade[3].name: USERS ; 0x118: length=5
kfade[3].fnum: 264 ; 0x148: 0x00000108
5
kfade[0].name: TEMP ; 0x034: length=4
kfade[0].fnum: 263 ; 0x064: 0x00000107
6
kfade[0].name: spfile ; 0x034: length=6
kfade[0].fnum: 265 ; 0x064: 0x00000109
7
kfade[0].name: 2010_08_19 ; 0x034: length=10
kfade[0].fnum: 4294967295 ; 0x064: 0xffffffff
8
kfade[0].name: thread_1_seq_9 ; 0x034: length=14
kfade[0].fnum: 266 ; 0x064: 0x0000010a
kfade[1].name: thread_1_seq_10 ; 0x080: length=15
kfade[1].fnum: 267 ; 0x0b0: 0x0000010b
kfade[2].name: thread_1_seq_11 ; 0x0cc: length=15
kfade[2].fnum: 268 ; 0x0fc: 0x0000010c
kfade[3].name: thread_1_seq_12 ; 0x118: length=15
kfade[3].fnum: 269 ; 0x148: 0x0000010d
kfade[4].name: thread_1_seq_13 ; 0x164: length=15
kfade[4].fnum: 270 ; 0x194: 0x0000010e
kfade[5].name: thread_1_seq_14 ; 0x1b0: length=15
kfade[5].fnum: 271 ; 0x1e0: 0x0000010f
9
现在有了INTERNAL FILE ID和NAME的大概对应关系了,那么可以尝试启动数据库了
************************************************************
mv 256.dbf controlfile
mv 257.dbf redo01
mv 258.dbf redo02
mv 259.dbf redo03
mv 260.dbf system
mv 261.dbf undotbs1
mv 262.dbf sysaux
mv 264.dbf users
mv 263.dbf temp
mv 265.dbf spfile
[oracle10@zhangqiaoc tmp]$ strings spfile > pfile.ora
修改control_files参数
SQL> startup nomount pfile='/tmp/pfile.ora';
ORACLE instance started.
Total System Global Area 205520896 bytes
Fixed Size 1266608 bytes
Variable Size 75500624 bytes
Database Buffers 125829120 bytes
Redo Buffers 2924544 bytes
SQL> alter database mount;
alter database mount
*
ERROR at line 1:
ORA-00227: corrupt block detected in control file: (block 15, # blocks 1)
ORA-00202: control file: '/tmp/controlfile'
当MOUNT数据库时,ORACLE检验控制文件块大小和记录在控制文件头部中的文件大小是否和db_block_size和OS报告的文件大小(如果可用)是否匹配。因为我都是直接按照1MB dd的,所以可能报错
还可能是STRIPE SIZE的关系,控制文件的stripe size为128K,没环境了,以后在测试,数据文件的stripe size为1M,这样直接dd是没问题的
SQL> CREATE CONTROLFILE REUSE DATABASE "ASM10" NORESETLOGS ARCHIVELOG
2 MAXLOGFILES 16
3 MAXLOGMEMBERS 3
4 MAXDATAFILES 100
5 MAXINSTANCES 8
6 MAXLOGHISTORY 292
7 LOGFILE
8 GROUP 1 (
9 '/tmp/redo01'
10 ) SIZE 50M,
11 GROUP 2 (
12 '/tmp/redo02'
13 ) SIZE 50M,
14 GROUP 3 (
15 '/tmp/redo03'
16 ) SIZE 50M
17 DATAFILE
18 '/tmp/system',
19 '/tmp/undotbs1',
20 '/tmp/sysaux',
21 '/tmp/users'
22 CHARACTER SET ZHS16GBK
23 ;
Control file created.
SQL> SQL> recover database;
ORA-00283: recovery session canceled due to errors
ORA-00264: no recovery required
SQL> alter database open;
Database altered.
SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/tmp/temp'
2 SIZE 20971520 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
Tablespace altered.
RMAN> backup validate check logical database;
Starting backup at 20-AUG-10
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=140 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00001 name=/tmp/system
input datafile fno=00002 name=/tmp/undotbs1
input datafile fno=00003 name=/tmp/sysaux
input datafile fno=00004 name=/tmp/users
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:36
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 20-AUG-10
SQL> SELECT * FROM v$backup_corruption;
no rows selected
[oracle10@zhangqiaoc tmp]$ dbv file=system blocksize=8192
DBVERIFY: Release 10.2.0.4.0 - Production on Fri Aug 20 07:23:36 2010
Copyright (c) 1982, 2007, Oracle. All rights reserved.
DBVERIFY - Verification starting : FILE = ./system
DBVERIFY - Verification complete
Total Pages Examined : 38400
Total Pages Processed (Data) : 11573
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 3325
Total Pages Failing (Index): 0
Total Pages Processed (Other): 1785
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 21717
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Highest block SCN : 175890 (0.175890)
PS:DISK ID和文件名对不上的可以去kfed KFBTYP_DISKDIR(type=6)
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE
跟多ASM内部信息可以参考Julian Dyke的Automatic Storage Management.ppt
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8242091/viewspace-671474/ ,如需转载,请注明出处,否则将追究法律责任。