device-mapper: multipath: Failing path recovery

https://yq.aliyun.com/articles/18067

摘要: 由于扇区损坏导致多路径设备failed. 现象如下 :  # dmesg : device-mapper: multipath: Failing path 8:128. qla2xxx 0000:07:00.

由于扇区损坏导致多路径设备failed.
现象如下 : 
# dmesg : 
device-mapper: multipath: Failing path 8:128.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
qla2xxx 0000:07:00.1: scsi(1:0:0:1): Mid-layer underflow detected (40000 of 40000 bytes)...returning error status.
sd 1:0:0:1: SCSI error: return code = 0x00070000
end_request: I/O error, dev sda, sector 3870947799
device-mapper: multipath: Failing path 8:0.
sd 0:0:0:1: SCSI error: return code = 0x08000002
sdi: Current: sense key: Medium Error
    Add. Sense: Unrecovered read error

Info fld=0x0
end_request: I/O error, dev sdi, sector 3870947799

# multipath -ll
msa2vd01vol01 (3600c0ff000xxxxxxf810394c01000000) dm-0 HP,MSA2312fc
[size=1.8T][features=1 queue_if_no_path][hwhandler=0][rw]
\_ round-robin 0 [prio=50][enabled]
 \_ 0:0:0:1 sdi 8:128 [failed][ready]
\_ round-robin 0 [prio=10][enabled]
 \_ 1:0:0:1 sda 8:0   [failed][ready]


扇区损坏可能是前段时间存储故障, 以及存储的volume write back缓存机制导致的.
修复先要将多路径设备搞好 : 
echo 1 > /sys/block/sda/device/delete
echo 1 > /sys/block/sdi/device/delete
echo "- - -" > /sys/class/scsi_host/${HBA}/scan, 如下
echo "- - -" > /sys/class/scsi_host/host0/scan
echo "- - -" > /sys/class/scsi_host/host1/scan

# multipath -v2
: checker msg is "readsector0 checker reports path is down"
reload: msa2vd01vol01 (3600c0ff000xxxxxxf810394c01000000)  HP,MSA2312fc
[size=1.8T][features=0][hwhandler=0][n/a]
\_ round-robin 0 [prio=50][undef]
 \_ 0:0:0:1 sda 8:0   [undef][ready]
\_ round-robin 0 [prio=10][undef]
 \_ 1:0:0:1 sde 8:64  [undef][ready]

dmesg : 
  Vendor: HP        Model: MSA2312fc         Rev: M112
  Type:   Direct-Access                      ANSI SCSI revision: 05
SCSI device sda: 3902343744 512-byte hdwr sectors (1998000 MB)
sda: Write Protect is off
sda: Mode Sense: 93 00 00 08
SCSI device sda: drive cache: write back
SCSI device sda: 3902343744 512-byte hdwr sectors (1998000 MB)
sda: Write Protect is off
sda: Mode Sense: 93 00 00 08
SCSI device sda: drive cache: write back
 sda: sda1
sd 0:0:0:1: Attached scsi disk sda
sd 0:0:0:1: Attached scsi generic sg1 type 0
  Vendor: HP        Model: MSA2312fc         Rev: M112
  Type:   Direct-Access                      ANSI SCSI revision: 05
SCSI device sde: 3902343744 512-byte hdwr sectors (1998000 MB)
sde: Write Protect is off
sde: Mode Sense: 93 00 00 08
SCSI device sde: drive cache: write back
SCSI device sde: 3902343744 512-byte hdwr sectors (1998000 MB)
sde: Write Protect is off
sde: Mode Sense: 93 00 00 08
SCSI device sde: drive cache: write back
 sde: sde1
sd 1:0:0:1: Attached scsi disk sde
sd 1:0:0:1: Attached scsi generic sg6 type 0


# multipath -ll
msa2vd01vol01 (3600c0ff000xxxxxxf810394c01000000) dm-0 HP,MSA2312fc
[size=1.8T][features=1 queue_if_no_path][hwhandler=0][rw]
\_ round-robin 0 [prio=50][enabled]
 \_ 0:0:0:1 sda 8:0   [active][ready]
\_ round-robin 0 [prio=10][enabled]
 \_ 1:0:0:1 sde 8:64  [active][ready]

umount 挂载点.
然后使用fsck修复.
fsck -v -p /dev/mapper/msa2vd01vol01p1

查看文件系统信息 : 
dumpe2fs /dev/mapper/msa2vd01vol01p1 >~/dumpe2fs.log
Filesystem volume name:   
Last mounted on:          
Filesystem UUID:          63d08b38-6214-4a28-8f3e-0b8fd9c1734e
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file
Default mount options:    (none)
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              243908608
Block count:              487791627
Reserved block count:     24389581
Free blocks:              117876429
Free inodes:              243257871
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      907
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         16384
Inode blocks per group:   512
Filesystem created:       Wed Jul 21 19:10:23 2010
Last mount time:          Tue May 14 07:38:24 2013
Last write time:          Tue May 14 07:38:24 2013
Mount count:              1
Maximum mount count:      36
Last checked:             Mon May 13 22:19:35 2013
Check interval:           15552000 (6 months)
Next check after:         Sat Nov  9 22:19:35 2013
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Journal inode:            8
Default directory hash:   tea

计算扇区对应的数据块id : 
blocksize=4096, 扇区大小为512字节, 所以扇区号为3870947799对应的blockid= 3870947799/8=483868474.875
dumpe2fs.log, 看看这个blockid是在哪个group中.
Group 14766: (Blocks 483852288-483885055)
  Block bitmap at 483852288 (+0), Inode bitmap at 483852289 (+1)
  Inode table at 483852290-483852801 (+2)
  1027 free blocks, 16384 free inodes, 0 directories
  Free blocks: 483855860-483856886
  Free inodes: 241926145-241942528


使用badblocks检查坏块.
badblocks -v -b 4096 -o ./badblocks.20130514 /dev/sda 483868480 483868460

定位到坏块为 483868476
# cat badblocks.20130514
483868476

接下来是修复 : 
# dd if=/dev/sda of=./badblock483868476.data bs=4096 skip=483868476 count=1
dd: reading `/dev/sda': Input/output error
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.003665 seconds, 0.0 kB/s

如果读出数据来了, 那么可以将数据回写进行修复.
dd if=./badblock483868476.data of=/dev/sda seek=483868476 bs=4096 count=1


多遍尝试后如果数据无法读取, 则可以采用覆写的方法修复. 直接放弃这个数据块.
badblocks -f -v -w -b 4096 /dev/sda 483868477 483868476
/dev/sda is apparently in use by the system; badblocks forced anyway.
Checking for bad blocks in read-write mode
From block 483868476 to 483868477
Testing with pattern 0xaa: done                                
Reading and comparing: done                                
Testing with pattern 0x55: done                                
Reading and comparing: done                                
Testing with pattern 0xff: done                                
Reading and comparing: done                                
Testing with pattern 0x00: done                                
Reading and comparing: done                                
Pass completed, 0 bad blocks found.

再次检测已无坏块 : 
# badblocks -v -b 4096 /dev/sda 483868480 483868460
Checking blocks 483868460 to 483868480
Checking for bad blocks (read-only test): done                                
Pass completed, 0 bad blocks found.


# 接下来是将数据库中的这部分数据重建. 
如果是PostgreSQL 可以使用
ZERO_DAMAGED_PAGES = true

将数据读出后重新写入. 
如果是greenplum, 并且是压缩表的话, 可能会有解压错误, 所以建议重新抽取数据.
ERROR:  ZLIB uncompress failed (detail: 'The compressed data was corrupted', output buffer length 32568, compressed length 12136, (block count 3651)) (gp_compress.c:355)  (seg4 slice1 dw-host37-if2:51001 pid=5024)


【参考】
1.  https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/5/pdf/Online_Storage_Reconfiguration_Guide/Red_Hat_Enterprise_Linux-5-Online_Storage_Reconfiguration_Guide-en-US.pdf?
2.  http://h10025.www1.hp.com/ewfrf/wc/document?cc=us&lc=en&dlc=en&tmp_geoLoc=true&docname=c03113986
3.  http://www.ehow.com/how_6864409_fix-bad-sectors-ubuntu.html
4. dumpe2fs
5. tune2fs
6. fsck
7. e2fsck
8. badblocks
9. mkfs.ext3时可以忽略badblocks检测到的坏扇区.

[其他摘录]
现在的硬盘,在内部会有一保留区域,来替换出现坏块的扇区,这对于磁盘外的系统来说是透明的,
如果已经存在了坏道,硬盘会在写入的时候将它替换到别的位置, 注意, 只有在写入的时候,才进行重定位。
我們完全不必要使用上层的文件系统的坏道表功能, 只要对坏块位置进行写入,就可以修复了。

使用badblocks 可以查出坏块,然后badblocks本是具有写测试功能,我們只需要用badblocks就可以了,
因为不用向上层的文件系统提供坏道表, 所以我們在扫描坏道时,不用设置块大小参数(-b),
首先扫描坏道
badblocks -b 4096 -o /root/sdb.bad /etc/sdb 
经过慢长的时间,我們得到了一个文件/root/sdb.bad :
16435904
sdb 有1个坏块
先用dd尽量备份坏块
dd if=/dev/sdb bs=4096 skip=16435904 of=/tmp/15435904.dat count=1
如果显示读取字节数是0就多试几次, 不行就可能丢失此块数据, 倒是不用担心,一般不会有太大问题.
用badblocks的写测试功能,对这些坏块进行重写(注意! -w写测试会覆盖数据):
badblocks -w -f /dev/sdb5 16435904 16435904
如果前面的操作有成功的备份/tmp/15435904.dat, 就把它写回:
dd if=/tmp/15435904.dat of=/dev/sdb seek=15435904 bs=4096 count=1
其实我們不需要等待badblocks扫描完成, 就可以进行修复。

badblocks是对块设备进行处理, 所以可以实现对挂载中的系统进行处理。

数据比硬盘值钱, 这只可以作为临时措施,出现坏道, 还是应该换硬盘,现在硬盘不贵。

///badblocks -v /dev/sda  这个是检查硬盘有无坏道/坏扇区的命令//
   硬盘是一个损耗设备,当使用一段时间后可能会出现坏道等物理故障。电脑硬盘出现坏道后,如果不及时更换或进行技术处理,坏道就会越来越多,并会造成频繁 死机和数据丢失。最好的处理方式是更换磁盘,但在临时的情况下,应及时屏蔽坏道部分的扇区,不要触动它们。badblocks就是一个检查坏道位置的工 具。
一、命令参数
badblocks使用格式为:
引用
badblocks  [  -svwnf  ]  [  -b block-size ] [ -c blocks_at_once ] [ -i
      input_file ] [ -o output_file ] [ -p num_passes ] [ -t test_pattern  ]
      device [ last-block ] [ start-block ]

参数含义是:
引用
-b blocksize 
 指定磁盘的区块大小,单位为字节,默认值为“block 4K ”(4K/block)
-c blocksize 
 每个区块检查的次数,默认是16次
-f
 强制在一个已经挂载的设备上执行读写或非破坏性的写测试操作
 (我们建议先umount设备,然后再进行坏道检测。仅当/etc/mtab出现误报设备挂载错误的时候可以使用该选项)
-i file
 跳过已经显示在file文件中的坏道,而不进行检测(可以避免重复检测)
-o file 
 把检测结果输出到file文件
-p number
 重复搜寻设备,直到在指定通过次数内都没有找到新的坏块位置,默认次数为0 
-s
 在检查时显示进度
-t pattern 
 通过按指定的模式读写来检测区块。你可以指定一个0到ULONG_MAX-1的十进制正值,或使用random(随机)。
 如果你指定多个模式,badblocks将使用第一个模式检测所有的区块,然后再使用下一个模式检测所有的区块。
 Read-only方式仅接受一个模式,它不能接受random模式的。
-v
 执行时显示详细的信息
-w
 对每个区块都先写入,然后再从它读取信息
[device]
 指定要检查的磁盘装置。
[last-block]
 指定磁盘装置的区块总数。
[start-block]
 指定要从哪个区块开始检查

二、示例
badblocks以4096的一个block,每一个block检查16次,将结果输出到“hda-badblocks-list”文件里

# badblocks -b 4096 -c 16 /dev/hda1 -o hda-badblocks-list

hda-badblocks-list”是个文本文件,内容如下:
引用
# cat hda-badblocks-list 
51249 
51250 
51251 
51253 
51254 
……
61245 
……

可以针对可疑的区块多做几次操作。下面,badblocks以4096字节为一个“block”,每一个“block”检查1次, 将结果输出到“hda-badblocks-list.1”文件中,由第51000 block开始,到63000 block结束

# badblocks -b 4096 -c 1 /dev/hda1 -o hda-badblocks-list.1 63000 51000

这 次花费的时间比较短,硬盘在指定的情况下在很短的时间就产生“嘎嘎嘎嘎”的响声。由于检查条件的不同,其输出的结果也不完全是相同的。重复几次同样的操 作,因条件多少都有些不同,所以结果也有所不同。进行多次操作后,直到产生最后的hda-badblock-list.final文件。

三、其他
1、fsck使用badblocks的信息
badblocks只会在日志文件中标记出坏道的信息,但若希望在检测磁盘时也能跳过这些坏块不检测,可以使用fsck的-l参数:
# fsck.ext3 -l /tmp/hda-badblock-list.final /dev/hda1

2、在创建文件系统前检测坏道
badblocks可以随e2fsck和mke2fs的-c删除一起运行(对ext3文件系统也一样),在创建文件系统前就先检测坏道信息:

# mkfs.ext3 -c /dev/hda1

代码表示使用-c在创建文件系统前检查坏道的硬盘。
这 个操作已经很清楚地告知我们可以采用“mkfs.ext3 -c”选项用“read-only”方式检查硬盘。这个命令会在格式化硬盘时检查硬盘,并标出错误的硬盘“block”。用这个方法格式化硬盘,需要有相 当大的耐心,因为命令运行后,会一个个用读的方式检查硬盘。
本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至[email protected];如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:[email protected] 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

你可能感兴趣的:(RAC)