在文章“Linux 中软件 RAID 的使用”中我们讲述了 Linux 系统中软 RAID 的基本概念和如何使用 mdadm 程序来管理软 RAID 设备,通过对 mdadm 命令的主要参数来介绍软 RAID 设备的创建,删除,停止和扩展等操作,以及其元数据和位图 bitmap 数据的管理方法。在本文中我们讨论使用软 RAID 设备常见的问题以及解决的方法。
1. RAID 的子设备物理上要独立不相关
对一个磁盘上的多个磁盘分区做RAID是没有价值的,因为不但违背了RAID阵列中设备独立性的原则,不能增加阵列的可靠性,当这个磁盘失效后必然不可避免的导致数据丢失,而且还导致阵列的性能显著降低,当数据读写时磁头在磁盘的多个分区上来回抖动带来长时间的搜索耗时。
2. RAID 0 没有数据冗余功能
RAID 0 只能使用数据块条带化(stripping)功能来提高性能,如果有磁盘失效则会导致MD设备上的数据丢失,在读写MD设备时出错。
3. 快速测试命令
当创建磁盘时,如果已知设备上的数据已经是同步(sync)成功过,或者仅仅是用来测试阵列,可以使用--assume-clean参数来通知MD驱动不必初始化阵列。
mdadm -C /dev/md0 -l5 -n6 /dev/sd[b-g] -x1 /dev/sdh --assume-clean
如果想避免mdadm每次创建命令时,因为设备上还有以前的元数据的提示,避免手工输入,可以使用--run(或者其缩写-R)通知阵列直接运行。
mdadm --create --run /dev/md0 -l5 -n6 /dev/sd[b-g] -x1 /dev/sdh --assume-clean
4. 异构磁盘组成的RAID
RAID0可以支持不同大小的磁盘构造多个区域(zone)的RAID,每个区域有不同的磁盘个数。使用fdisk命令查询/dev/sdi1为2GB, /dev/sdj1为4GB,/dev/sdk1为1GB,所以做成RAID0设备为7GB。
mdadm -C /dev/md0 -l5 -n6 /dev/sd[b-g] -x1 /dev/sdh --assume-clean
而RAID1,RAID456, RAID10等对不同大小的磁盘只能使用最小的磁盘的容量作为公共的大小,多余的部分被浪费掉。/dev/sdi1,/dev/sdj1,/dev/sdk1做成的RAID5设备为2GB,是最小的设备/dev/sdk1的2倍,设备/dev/sdi1和sdj1分别浪费了1GB和3GB。
[root@fc5 mdadm-2.6.3]# ./mdadm �CCR /dev/md1 -l0 -n3 /dev/sd[i-k]1
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md1 | grep "Array Size"
Array Size : 7337664 (7.00 GiB 7.51 GB)
在阵列的状态信息查询中的大小(ArraySize)前面使用的是KB,也表示MD块设备的实际大小;而后面的两个值只是为了显示处理后的结果。
[root@fc5 mdadm-2.6.3]# ./mdadm �CCR /dev/md1 -l0 -n3 /dev/sd[i-k]1
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md1 | grep "Array Size"
Array Size : 7337664 (7.00 GiB 7.51 GB)
[root@fc5 mdadm-2.6.3]# ./mdadm -CR /dev/md1 -l5 -n3 /dev/sd[i-k]1
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md1 | grep "Array Size"
Array Size : 2096896 (2048.09 MiB 2147.22 MB)
5. 配置共享的热备盘
mdadm程序是允许多个RAID组共享冗余磁盘的。 例如有/dev/md0和/dev/md1两个阵列,在创建时/dev/md0里面有一个热备磁盘,而/dev/md1没有热备磁盘。我们只要在/etc/mdadm.conf中配置两个阵列使用相同的spare-group组。
[root@fc5 mdadm-2.6.3]# cat /etc/mdadm.conf
DEVICE /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh
/dev/sdi1 /dev/sdj1 /dev/sdk1
ARRAY /dev/md1 level=raid0 num-devices=3 spare-group=sparedisks
UUID=dcff6ec9:53c4c668:58b81af9:ef71989d
ARRAY /dev/md0 level=raid10 num-devices=6 spare-group=sparedisks
UUID=0cabc5e5:842d4baa:e3f6261b:a17a477a
并运行mdadm 的监控(monitor)模式命令。当/dev/md1阵列中的一个磁盘/dev/sdi1失效时,mdadm会自动从/dev/md0组中上移走spare磁盘,并加入/dev/md1中。
[root@fc5 mdadm-2.6.3]#./mdadm --monitor --mail=root@localhost --syslog --program=/root/md.sh
--delay=300 /dev/md* --daemonise
8105
[root@fc5 mdadm-2.6.3]#./mdadm /dev/md1 -f /dev/sdi1
mdadm: set /dev/sdi1 faulty in /dev/md1
[root@fc5 mdadm-2.6.3]#./mdadm -D /dev/md1
/dev/md1:
Version : 00.90.03
Creation Time : Mon Aug 23 00:10:00 1999
Raid Level : raid5
Array Size : 2096896 (2048.09 MiB 2147.22 MB)
Used Dev Size : 1048448 (1024.05 MiB 1073.61 MB)
Raid Devices : 3
Total Devices : 4
Preferred Minor : 1
Persistence : Superblock is persistent
Update Time : Mon Aug 23 00:13:15 1999
State : clean, degraded, recovering
Active Devices : 2
Working Devices : 3
Failed Devices : 1
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 64K
Rebuild Status : 78% complete
UUID : 34d3de75:6912dc24:e1316607:4e72cd01
Events : 0.4
Number Major Minor RaidDevice State
3 8 112 0 spare rebuilding /dev/sdh
1 8 145 1 active sync /dev/sdj1
2 8 161 2 active sync /dev/sdk1
4 8 129 - faulty spare /dev/sdi1
6. 多种元数据格式
目前MD设备有两种主要的元数据格式(0.9版本和1.x版本),主要是元数据占用的空间不同和支持的底层设备个数不同,而且1.x版本还可以指定元数据写入设备的具体位置(1.0为在设备尾部,1.1为在设备开始,1.2为在设备开始的4KB位置)。创建阵列通过--metadata(或者其缩写-e)参数来指定元数据格式版本。
[root@fc5 mdadm-2.6.3]# ./mdadm -CR /dev/md0 -l5 -n6 -x1 /dev/sd[b-h]
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0 | grep Version
Version : 00.90.03
[root@fc5 mdadm-2.6.3]# ./mdadm -CR /dev/md0 -l5 -n6 -x1 -e1.0 /dev/sd[b-h]
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0 | grep Version
Version : 01.00.03
[root@fc5 mdadm-2.6.3]# ./mdadm -CR /dev/md0 -l5 -n6 -x1 -e1.1 /dev/sd[b-h]
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0 | grep Version
Version : 01.01.03
[root@fc5 mdadm-2.6.3]# ./mdadm -CR /dev/md0 -l5 -n6 -x1 -e1.2 /dev/sd[b-h]
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0 | grep Version
Version : 01.02.03
当阵列将磁盘移走后,也使用--zero-superblock清空设备上面的元数据信息。
[root@fc5 mdadm-2.6.3]# ./mdadm -Es /dev/sdh
ARRAY /dev/md0 level=raid5 num-devices=6
UUID=acd2b182:4695ee20:37689502:eb0423e1
spares=1
[root@fc5 mdadm-2.6.3]# ./mdadm /dev/md0 -f /dev/sdh -r /dev/sdh
mdadm: set /dev/sdh faulty in /dev/md0
mdadm: hot removed /dev/sdh
[root@fc5 mdadm-2.6.3]# ./mdadm --zero-superblock /dev/sdh
[root@fc5 mdadm-2.6.3]# ./mdadm -Es /dev/sdh
[root@fc5 mdadm-2.6.3]#
7. 可分区的RAID设备
如果想对支持分区的MD设备(Partitionable raid array)进行分区,需要在创建时使用/dev/md_d0来替代前面的/dev/md0。创建阵列是通过--auto=mdp(或者其缩写-ap)参数指定。
[root@fc5 mdadm-2.6.3]# ./mdadm -Cv --auto=mdp /dev/md_d0 -l5 -n6 /dev/sd[b-g] -x1 /dev/sdh
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 64K
mdadm: size set to 1048512K
mdadm: array /dev/md_d0 started.
[root@fc5 mdadm-2.6.3]# fdisk /dev/md_d0
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
The number of cylinders for this disk is set to 1310640.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1310640, default 1):1
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-1310640, default 1310640): +1024M
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (250002-1310640, default 250002):250002
Using default value 250002
Last cylinder or +size or +sizeM or +sizeK (250002-1310640, default 1310640):1310640
Using default value 1310640
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@fc5 mdadm-2.6.3]# fdisk -l /dev/md_d0
Disk /dev/md_d0: 5368 MB, 5368381440 bytes
2 heads, 4 sectors/track, 1310640 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Device Boot Start End Blocks Id System
/dev/md_d0p1 1 250001 1000002 83 Linux
/dev/md_d0p2 250002 1310640 4242556 83 Linux
MD设备支持两种块设备,一种是不可分区类型的名字是md设备,主设备号是9,另一种是可分区的名字是mdp设备,mdp的主设备号是动态分配的,一个mdp设备最多能支持63个分区。查看/proc/device信息能看到mdp的主设备号,查询/proc/partitions信息能看到md和mdp设备的主设备号和从设备号。
[root@fc5 mdadm-2.6.3]# cat /proc/devices | grep md
1 ramdisk
9 md
253 mdp
[root@fc5 mdadm-2.6.3]# cat /proc/partitions | grep md
9 1 2096896 md1
253 0 5242560 md_d0
253 1 1000002 md_d0p1
253 2 1000002 md_d0p2
8. 怎样扩展RAID设备
Grow模式中的容量扩展(resize)功能不但支持设备大小增加,也可以支持设备大小减少,但要求使用者自己来保证MD设备有效数据上不被截断导致丢失。
[root@fc5 mdadm-2.6.3]# ./mdadm /dev/md0 --grow --size=102400
[root@fc5 mdadm-2.6.3]# ./mdadm -Q /dev/md0
/dev/md0: 600.00MiB raid5 7 devices, 0 spares. Use mdadm --detail for more detail.
而磁盘个数扩展(reshape)功能不支持设备个数减少,如果在阵列中空闲的热备盘而且也没有指定backup文件,则不能扩展。如果对于RAID5阵列有备份(backup)文件可以支持扩展一个磁盘,扩展后的磁盘阵列是降级模式的,不支持扩展多个磁盘或者对降级的RAID5阵列再扩展。这些扩展模式不够安全,仅仅是暂时没有热备盘的权宜之计,一般合理的操作还是先增加空闲的热备磁盘再执行扩展命令。
[root@fc5 mdadm-2.6.3]# ./mdadm --grow /dev/md0 -n6
mdadm: /dev/md0: Cannot reduce number of data disks (yet).
[root@fc5 mdadm-2.6.3]# ./mdadm --grow /dev/md0 -n8
mdadm: Need to backup 2688K of critical section.
mdadm: /dev/md0: Cannot grow - need a spare or backup-file to backup critical section
[root@fc5 mdadm-2.6.3]# ./mdadm -G /dev/md0 -n9 --backup-file=/root/bak-reshape
mdadm: Need to backup 1024K of critical section..
mdadm: /dev/md0: failed to initiate reshape
[root@fc5 mdadm-2.6.3]# ./mdadm -G /dev/md0 -n8 --backup-file=/root/bak-reshape
mdadm: Need to backup 2688K of critical section..
mdadm: ... critical section passed.
[root@fc5 mdadm-2.6.3]# cat /proc/mdstat
Personalities : [raid0] [raid10] [raid6] [raid5] [raid4]
md0 : active raid5 sdh[6] sdg[5] sdf[4] sde[3] sdd[2] sdc[1] sdb[0]
6291072 blocks super 0.91 level 5, 64k chunk, algorithm 2 [8/7] [UUUUUUU_]
[>..................] reshape = 2.6% (28608/1048512) finish=4.1min speed=4086K/sec
md1 : active raid0 sdk1[2] sdj1[1] sdi1[0]
7337664 blocks 64k chunks
unused devices: < none >
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0
/dev/md0:
Version : 00.91.03
Creation Time : Sun Aug 22 23:46:29 1999
Raid Level : raid5
Array Size : 6291072 (6.00 GiB 6.44 GB)
Used Dev Size : 1048512 (1024.11 MiB 1073.68 MB)
Raid Devices : 8
Total Devices : 7
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Sun Aug 22 23:46:56 1999
State : clean, degraded, recovering
Active Devices : 7
Working Devices : 7
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 64K
Reshape Status : 4% complete
Delta Devices : 1, (7->8)
UUID : 50e886b9:9e28d243:a7f6457d:5eb47f2e
Events : 0.94
Number Major Minor RaidDevice State
0 8 16 0 active sync /dev/sdb
1 8 32 1 active sync /dev/sdc
2 8 48 2 active sync /dev/sdd
3 8 64 3 active sync /dev/sde
4 8 80 4 active sync /dev/sdf
5 8 96 5 active sync /dev/sdg
6 8 112 6 active sync /dev/sdh
7 0 0 7 removed
[root@fc5 mdadm-2.6.3]# cat /proc/mdstat
Personalities : [raid0] [raid10] [raid6] [raid5] [raid4]
md0 : active raid5 sdh[6] sdg[5] sdf[4] sde[3] sdd[2] sdc[1] sdb[0]
7339584 blocks level 5, 64k chunk, algorithm 2 [8/7] [UUUUUUU_]
md1 : active raid0 sdk1[2] sdj1[1] sdi1[0]
7337664 blocks 64k chunks
unused devices: < none >
[root@fc5 mdadm-2.6.3]# ./mdadm -D /dev/md0
/dev/md0:
Version : 00.90.03
Creation Time : Sun Aug 22 23:46:29 1999
Raid Level : raid5
Array Size : 7339584 (7.00 GiB 7.52 GB)
Used Dev Size : 1048512 (1024.11 MiB 1073.68 MB)
Raid Devices : 8
Total Devices : 7
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Sun Aug 22 23:50:18 1999
State : clean, degraded
Active Devices : 7
Working Devices : 7
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 64K
UUID : 50e886b9:9e28d243:a7f6457d:5eb47f2e
Events : 0.766
Number Major Minor RaidDevice State
0 8 16 0 active sync /dev/sdb
1 8 32 1 active sync /dev/sdc
2 8 48 2 active sync /dev/sdd
3 8 64 3 active sync /dev/sde
4 8 80 4 active sync /dev/sdf
5 8 96 5 active sync /dev/sdg
6 8 112 6 active sync /dev/sdh
7 0 0 7 removed
[root@fc5 mdadm-2.6.3]# ./mdadm -G /dev/md0 -n9 --backup-file=/root/bak-reshape
mdadm: Need to backup 3584K of critical section..
mdadm: /dev/md0: failed to find device 7. Array might be degraded.
--grow aborted
9. 为什么不能扩展RAID设备
当使用grow模式时,如果内核不支持sysfs或者MD驱动版本较低不支持时则会返回错误。另外使用strace命令跟踪能导致在哪个函数调用上出错返回。
[root@fc5 mdadm-2.6.3]# ./mdadm --grow /dev/md0 -n6
mdadm: Need to backup 1280K of critical section..
mdadm: /dev/md0: Cannot get array details from sysfs
如果系统没有加载sysfs,需要使用mount命令加载。
mount �Ct sysfs sysfs /sys/
10. 为什么不能停止MD设备
当停止MD阵列时,有时被返回MD设备正在被使用错误,需要检查MD设备被哪个上层设备使用。一个情况是被文件系统使用,如已经被mount起来:
[root@fc5 mdadm-2.6.3]# df -h | grep md
/dev/md0 485M 11M 449M 3% /mnt/md-test
另一种情况是MD设备被用户层其他程序打开使用,如nbd-server导出MD设备:
[root@fc5 md0]#fuser -u /dev/md0
/dev/md0: 3507(root)
[root@fc5 md0]#ps ax| grep 3507
3507 ?
还有可能是内核驱动程序打开使用,如被LVM程序当作物理卷(PV)使用:
[root@fc5 mdadm-2.6.3]# ls -l /sys/block/md0/holders/
total 0
lrwxrwxrwx 1 root root 0 08-22 23:31 dm-0 -> ../../../block/dm-0
小结
如果在软RAID使用中遇到问题不能解决,应该首先查看mdadm的帮助信息;如果还不能解决,可以到mdadm的邮件列表寻找是否有相关的问题解答或者详细描述该问题的发生过程请求大家帮助。