一、10.2.0.5 之前版本
对于 10.2.0.5.0 之前,ASM 文件头是没有备份的,所以容易出故障 ,磁盘组坏掉就不容易修复。
(一)有备份的情况下磁盘头恢复
1、磁盘头备份
set linesize 1000
col name for a30
col path for a30
select NAME,
MOUNT_STATUS,
STATE,
DISK_NUMBER "DNO",
PATH,
TOTAL_MB,
FREE_MB,
GROUP_NUMBER "GNO"
from v$ASM_DISK;
select state,name,type,total_mb,free_mb from v$asm_diskgroup_stat;
mkdir /oracle/asmbak
kfed read /dev/asm_data_1 text=/oracle/asmbak/asm_data01_header.txt
2、模拟磁头损坏
- 挺掉节点2集群
- 关闭节点1数据库实例
- 磁盘头损坏: dd if=/dev/zero of=/dev/asm_data_1 bs=1024 count=1
3、磁盘头恢复
kfed merge /dev/asm_data_1 text=/oracle/asmbak/asm_data01_header.txt
(二)有备份的情况下磁盘头恢复
如果两个盘是同时创建,这种情况比较简单,方法是通过kfed 从好的盘读取出来修改部分数据后恢复回坏的那个磁盘头,修改内容是:
kfbh.block.obj
kfdhdb.dsknum
kfdhdb.dskname
kfdhdb.fgname
kfdhdb.f1b1locn
不可恢复的情况是:
- asm磁盘组只有一个盘
- asm 磁盘组中 disk directory 所在的磁盘信息丢失
元数据部分解释:
kfed read /dev/asm_data_1 aun=0 blkn=0|more
kfbh.endian: 1 ; 0x000: 0x01 --大小字节,0是大,1是小
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD --元数据类型,磁盘头
kfbh.datfmt: 1 ; 0x003: 0x01 --1是已经格式化的
kfbh.block.blk: 0 ; 0x004: blk=0 --ASM磁盘头的块号,这里是0
kfbh.block.obj: 2147483648 ; 0x008: disk=0 --磁盘组的磁盘编号是第0个
kfbh.check: 1929420377 ; 0x00c: 0x73009e59 --校验用的
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8
kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000
..........
kfdhdb.driver.reserved[5]: 0 ; 0x01c: 0x00000000
kfdhdb.compat: 186647552 ; 0x020: 0x0b200400 --软件兼容版本,这里是11.2.0.4
kfdhdb.dsknum: 0 ; 0x024: 0x0000 --磁盘编号
kfdhdb.grptyp: 1 ; 0x026: KFDGTP_EXTERNAL --磁盘组冗余度:1=外部,2=正常,3=告警,0-无效
kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname: DATA_0000 ; 0x028: length=9
kfdhdb.grpname: DATA ; 0x048: length=4
kfdhdb.fgname: DATA_0000 ; 0x068: length=9
kfdhdb.capname: ; 0x088: length=0
kfdhdb.crestmp.hi: 33173623 ; 0x0a8: HOUR=0x17 DAYS=0x3 MNTH=0xc YEAR=0x7e8 --本磁盘加入到磁盘组的时间
kfdhdb.crestmp.lo: 412121088 ; 0x0ac: USEC=0x0 MSEC=0x1e SECS=0x9 MINS=0x6 --本磁盘加入到磁盘组的时间
kfdhdb.mntstmp.hi: 33173652 ; 0x0b0: HOUR=0x14 DAYS=0x4 MNTH=0xc YEAR=0x7e8 --磁盘最后一次mount时间
kfdhdb.mntstmp.lo: 2796618752 ; 0x0b4: USEC=0x0 MSEC=0x41 SECS=0x2b MINS=0x29 --磁盘最后一次mount时间
kfdhdb.secsize: 512 ; 0x0b8: 0x0200 --扇区大小:512
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 --asm 元数据大小:4K
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000 --AU 大小,这里是1MB
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80
kfdhdb.dsksize: 30720 ; 0x0c4: 0x00007800 --磁盘分配的AU数,30720*1MB=30GB
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002 --物理元数据分配AU的数量
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 --记录分配的首个block,2表示本AU的块2
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.dbcompat: 186647552 ; 0x0e0: 0x0b200400
kfdhdb.grpstmp.hi: 33173623 ; 0x0e4: HOUR=0x17 DAYS=0x3 MNTH=0xc YEAR=0x7e8
kfdhdb.grpstmp.lo: 412011520 ; 0x0e8: USEC=0x0 MSEC=0x3b3 SECS=0x8 MINS=0x6
二、10.2.0.5(包含)之后版本
1、查看磁盘头备份位置
对于 10.2.0.5.0以及以后版本,不管 au size 是多少,asm disk header 自动备份存储的位置是第2 个 au 的倒数第 2 个 block
计算方法:
AU大小/block_size]*2-2 [因为从第一个块从 0 计数],通过该方法计算结论为:
1 个 AU 256
1M:510 (0-511) --1048576*1/4096*2-2=510
2M:1022
4M:2046
8M:4094 --1048576*8/4096 *2-2 = 4094
16M:8190
32M:16382
64M:32766
--查看block size
col name for a20
col value for a20
col describ for a20
set linesize 1000
SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ FROM SYS.x$ksppi x,SYS.x$ksppcv y
WHERE x.indx = y.indx AND x.ksppinm in ('_asm_ausize','_asm_blksize');
--查看指定磁盘组的AU_SIZE
set linesize 1000
col name for a40
col value for a30
SELECT SUBSTR(dg.name, 1, 12) AS diskgroup,
SUBSTR(a.name, 1, 24) AS name,
SUBSTR(a.value, 1, 24) AS value,
read_only
FROM V$ASM_DISKGROUP dg, V$ASM_ATTRIBUTE a
WHERE dg.name = 'DATA'
AND dg.group_number = a.group_number
AND a.name NOT LIKE '%template%';
2、磁盘头修复实验
--一般前面42mb都是存元数据,非业务数据。12c之前只有盘头1个block的自动备份,12c开始会自动备份盘头前面的1个AU。
dd if=/dev/zero of=/dev/asm_data_2 bs=1024 count=1
--查看 au size
kfed read /dev/asm_data_2 | grep ausize
--查看自动备份的磁盘头是否存在,如果存在就可以恢复
kfed read /dev/asm_data_2 blkn=510 | more
kfed repair /dev/asm_data_2
三、asm启动不起来的恢复
amdu -diskstring '/dev/asm_*' -extract ARCH.256




