從ASM磁碟中還原出檔案(二)

westzq1984發表於2010-08-20
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE接著測試了,環境為LINUX + ASMLIB


前面已經找到了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_ALIASDIRVOL3AU15

 

然後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 IDNAME的大概對應關係了,那麼可以嘗試啟動資料庫了

************************************************************

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_sizeOS報告的檔案大小(如果可用)是否匹配。因為我都是直接按照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部落格 ” ,連結:http://blog.itpub.net/8242091/viewspace-671474/,如需轉載,請註明出處,否則將追究法律責任。

相關文章