kfed是oracle 10g开始就有的工具,kfed用来读取磁盘的盘头信息。
kfed在运维中扮演这重要的角色,比如数据库异常宕机,没有办法读取磁盘,kfed就可以在此时读取磁盘的盘头。
首先我们做一个读取磁盘盘头的范例
$ /grid/app/12.1.0/grid/bin/kfed read /dev/oraasm-mpath01 kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 1 ; 0x002: kfbtyp_diskhead kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 0 ; 0x004: blk=0 kfbh.block.obj: 2147483690 ; 0x008: disk=42 kfbh.check: 3995290152 ; 0x00c: 0xee234a28 kfbh.fcn.base: 7937820 ; 0x010: 0x00791f1c 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[1]: 0 ; 0x00c: 0x00000000 kfdhdb.driver.reserved[2]: 0 ; 0x010: 0x00000000 kfdhdb.driver.reserved[3]: 0 ; 0x014: 0x00000000 kfdhdb.driver.reserved[4]: 0 ; 0x018: 0x00000000 kfdhdb.driver.reserved[5]: 0 ; 0x01c: 0x00000000 kfdhdb.compat: 202375168 ; 0x020: 0x0c100000 kfdhdb.dsknum: 42 ; 0x024: 0x002a kfdhdb.grptyp: 1 ; 0x026: kfdgtp_external kfdhdb.hdrsts: 3 ; 0x027: kfdhdr_member kfdhdb.dskname: datadg_0042 ; 0x028: length=11 kfdhdb.grpname: datadg ; 0x048: length=6 kfdhdb.fgname: datadg_0042 ; 0x068: length=11 kfdhdb.capname: ; 0x088: length=0 kfdhdb.crestmp.hi: 33067786 ; 0x0a8: hour=0xa days=0x18 mnth=0x4 year=0x7e2 kfdhdb.crestmp.lo: 1994433536 ; 0x0ac: usec=0x0 msec=0x29 secs=0x2e mins=0x1d kfdhdb.mntstmp.hi: 33068390 ; 0x0b0: hour=0x6 days=0xb mnth=0x5 year=0x7e2 kfdhdb.mntstmp.lo: 584754176 ; 0x0b4: usec=0x0 msec=0x2a9 secs=0x2d mins=0x8 kfdhdb.secsize: 512 ; 0x0b8: 0x0200 kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 kfdhdb.ausize: 8388608 ; 0x0bc: 0x00800000 kfdhdb.mfact: 454272 ; 0x0c0: 0x0006ee80 kfdhdb.dsksize: 65536 ; 0x0c4: 0x00010000 kfdhdb.pmcnt: 3 ; 0x0c8: 0x00000003 kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001 kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 kfdhdb.f1b1locn: 0 ; 0x0d4: 0x00000000 kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000 kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000 kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000 kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000 kfdhdb.dbcompat: 202375168 ; 0x0e0: 0x0c100000 kfdhdb.grpstmp.hi: 33059027 ; 0x0e4: hour=0x13 days=0x6 mnth=0xc year=0x7e1 kfdhdb.grpstmp.lo: 1868255232 ; 0x0e8: usec=0x0 msec=0x2d4 secs=0x35 mins=0x1b kfdhdb.vfstart: 0 ; 0x0ec: 0x00000000 kfdhdb.vfend: 0 ; 0x0f0: 0x00000000 kfdhdb.spfile: 0 ; 0x0f4: 0x00000000 kfdhdb.spfflg: 0 ; 0x0f8: 0x00000000 kfdhdb.flags: 1 ; 0x0fc: 0x00000001 kfdhdb.f1b1fcn.base: 0 ; 0x100: 0x00000000 kfdhdb.f1b1fcn.wrap: 0 ; 0x104: 0x00000000 kfdhdb.ub4spare[0]: 0 ; 0x108: 0x00000000 kfdhdb.ub4spare[1]: 0 ; 0x10c: 0x00000000 kfdhdb.ub4spare[2]: 0 ; 0x110: 0x00000000 ... kfdhdb.ub4spare[50]: 0 ; 0x1d0: 0x00000000 kfdhdb.acdb.aba.seq: 0 ; 0x1d4: 0x00000000 kfdhdb.acdb.aba.blk: 0 ; 0x1d8: 0x00000000 kfdhdb.acdb.ents: 0 ; 0x1dc: 0x0000 kfdhdb.acdb.ub2spare: 0 ; 0x1de: 0x0000
盘头中包含了磁盘的信息,比如磁盘名,磁盘组名,au size,block size
这次我们需要使用的就是kfdhdb.dskname磁盘名。
在一般的磁盘绑定中,比如udev,multipath,都需要在绑定文件中写明scsi_id,把绑定后的磁盘名和scsi_id做对应,这样机器在重启后就不会把磁盘绑定错,就不会导致asm起不来,就不会导致数据起不来的情况。
但是在有些环境中,就会有上述事情发生,机器重启后磁盘对应错误,而且各个节点本身的对应顺序就不一致,就只有通过kfed读盘头的方式去一个一个的梳理每个节点的磁盘绑定关系。
一次事故,在服务器重启后,asm没有启动,日志中显示没有打开磁盘。
在确认磁盘存在且可读的情况下,检查了磁盘绑定,发现没有绑定scsi id,只可能是磁盘link的顺序跟重启之前不一致了
比如有cache opening disk xx of grp x:diskname diskpath 的错误
可截取diskname和disk path,通过kfed读取dm文件,找到正确的盘
[root@dbnode01 enmo]# cat scan_disk_ln.sh while read line do disk=`echo $line|awk '{print $1}'` path=`echo $line|awk '{print $2}'` for i in `ls /dev/dm-*` do /grid/app/12.1.0/grid/bin/kfed read $i |egrep -i "$disk" >/dev/null if [ $ -eq 0 ];then echo "ln -s "$i $path fi done done
上述脚本需要仔细查看,理解其本意。理解multipath,udev,link的含义。
输出结果是dm和disk path的软连接命令,可以直接使用,但是这也是临时的结果
输出结果可再次加工,使用/usr/lib/udev/scsi_id -g -u -d /dev/dm* 命令生成scsi id,然后绑定到multipath的配置文件或者udev的规则文件中去。