mdadm 软 raid 相关
Table of Contents
1 raid array 中的设备
1.1 应该使用设备上的分区而不是整个设备
李守中认为应该使用磁盘分区作为 raid array 的组成部分,而不应直接使用整个磁盘。
不同制造商生产的磁盘 (甚至同一制造商生产的,标称容量相同的,不同型号的磁盘) 不一定具有完全相同的磁盘大小。这就意味着,在由多个整磁盘 (而不是用分区) 组建的 raid array 中,某个设备出现损坏时,用来替换已损坏磁盘的新盘必须和坏盘拥有相同的容量。当容量不同时,新盘无法替换旧盘。
使用磁盘分区作为 raid array 的组成部分可以避免因磁盘容量差异而导致的问题。
1.2 存储设备分区策略
分区策略为: 每个磁盘上的分区大小 = 容量最小的磁盘上的分区的大小 ,并且 用于 raid 的分区的大小 < 多个磁盘设备中容量最小的磁盘设备的大小 。
例如,两个标称容量为 3TB 磁盘组 RAID1:
sudo parted -l
命令显示容量最小的磁盘的容量为 3002G。- 分区容量必须小于 3002G,这里取 3001G,其余空间被浪费。
- 同样地,另一个硬盘上的分区大小必须和前一个硬盘上的分区大小相同,也取 3001G,剩下的空间被浪费。
然后,使用每个磁盘上的分区来组成阵列。
浪费掉的空间保证了: 即使新盘容量比坏盘容量小,但只要容量差距小于被浪费掉的空间,那么就能在新盘上创建和坏盘容量相同的分区,并把这个分区加入 raid。
1.3 避免单一故障点
磁盘一定会坏,但没人知道它什么时候会坏。
假设现在有多块磁盘。如果这些磁盘均为同一型号,那么它们有相同故障点的概率极高。如果这 2 块磁盘还来自同一批次,那么它们不但有相同的故障点,这 2 块盘的寿命也非常接近。
混用磁盘,可以让整个 raid array 的可靠性和容错性更好。
混用不同生产商的磁盘,可以使 raid array 中磁盘的故障点尽量分散。否则,如果所有磁盘来自同一个型号,那么这些磁盘就的故障点高度重合,只要有一个故障点被触发,所有的磁盘都会受到影响。如果它们还来自同一个批次,那么当 raid array 中的一个磁盘因寿命问题 (零件老化、电机磨损之类的问题) 出现故障时,剩下的磁盘能不能支撑到数据迁移完毕还很难说。
2 创建与销毁 raid
mdadm 命令常用参数:
-A
,--assemble
激活阵列。-a
,--add
添加设备到阵列。-C
,--create
新建一个阵列。-C --homehost=<host_name>
, 新建阵列时指定主机名。-C --name=<name>
, 新建阵列时指定阵列名。-c
,--chunk=<size>
指定阵列的块大小。默认 512K。-D
,--detail
打印一个或多个阵列设备信息。-f
,--fail
将列出的设备标记为故障。-G
,--grow
改变阵列大小和形态。-l
,--level=<level>
设置阵列级别。-n
,--raid-devices=<member>
指定阵列成员信息。-r
,--remove
删除列出的设备,设备不可处于活动状态。-S
,--stop
停止阵列,释放所有资源。-s
,--scan
扫描配置文件或/proc/mdstat
得到阵列缺失信息。-v
,--verbose
显示详细信息。-x
,--spare-devices=<number>
指定阵列中热备设备的数量。
2.1 创建 raid
raid1 创建:
- 2 个设备分区组 raid1:
mdadm --create /dev/md0 --level=raid1 --raid-devices=2 /dev/<device-a-partition> /dev/<device-b-partition>
- 用 1 个设备分区创建降级的 raid1:
- 创建降级的 raid1:
mdadm --create /dev/md0 --level=raid1 --raid-devices=2 /dev/<device-a-partition> missing
- 补上 raid1 的另一部分
mdadm --add /dev/md0 /dev/<device-b-partition>
- 创建降级的 raid1:
raid10 创建:
- 先创建 2 个 raid1:
mdadm --create /dev/md2 --level=raid1 --raid-devices=2 /dev/<device-a-partition> /dev/<device-b-partition>
mdadm --create /dev/md3 --level=raid1 --raid-devices=2 /dev/<device-c-partition> /dev/<device-d-partition>
- 再用 2 个 raid1 创建一个 raid0:
mdadm --create /dev/md4 --level=raid0 --raid-devices=2 /dev/md{2,3}
raid5 创建: (最少需要 3 个设备,允许 1 个设备损坏)
- 3 个工作设备和 1 个热备设备组 raid5:
mdadm --create -v /dev/md5 --level=raid5 --raid-devices=3 --spare-devices=1 /dev/<device-a-partition> /dev/<device-b-partition> /dev/<device-c-partition> /dev/<device-d-partition>
- 将 1 个热备设备加入 raid5 使工作设备变成 4 个:
mdadm --grow /dev/md5 --raid-devices=4
raid6 创建: (最少需要 4 个设备,允许 2 个设备损坏)
- 4 个工作设备和 1 个热备设备组 raid5:
mdadm --create -v /dev/md6 --level=raid6 --raid-devices=4 --spare-devices=1 /dev/<device-a-partition> /dev/<device-b-partition> /dev/<device-c-partition> /dev/<device-d-partition> /dev/<device-e-partition>
- 将 1 个热备设备加入 raid6 使工作设备变成 5 个:
mdadm --grow /dev/md6 --raid-devices=5
创建完成之后,扫描所有的 raid 并把配置存入配置文件中:
- RedHat:
mdadm --detail --scan >> /etc/mdadm.conf
- Debian:
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
cat /proc/mdstat
查看阵列状态。
mdadm --examine /dev/sda3
确认一个设备是否是 raid 的一部分。
raid 停止与激活:
mdadm -Ds > /etc/mdadm.conf
停止前一定要先保存 raid 信息到配置文件。mdadm -S /dev/md5
停止阵列。mdadm -As
激活所有阵列 (参考迁移 raid 章节)。
2.2 销毁 raid
假设,现在需要销毁 /dev/md1 这个 raid array。现在它已经被取消挂载。
mdadm --stop /dev/md1
停止这个阵列。- 在
/etc/mdadm.conf
中删除对应的配置行。 mdadm --remove /dev/md1
删除 raid 设备。
如果第三条命令报错,说找不到要删除的设备,类似这样:
mdadm: error opening md1: No such file or directory
执行 mdadm --zero-superblock {/dev/<raid-device-a-partition> /dev/<raid-device-b-partition> ...}
直接删除设备分区上的超级块 (块里保存了 raid 信息)。
最后执行 cat /proc/mdstat
确认一下 /dev/md1 是否已经消失。
3 维护 raid
编辑 /etc/mdadm/mdadm.conf 之后,要执行 sudo update-initramfs -u
才能让新的配置文件生效,如果有多个内核,执行 sudo update-initramfs -k all -u
。
3.1 迁移 raid
3.1.1 mdadm.conf 文件还在
复制旧机器的 mdadm.conf 文件到新机器上,然后把旧机器上的挂载配置迁移到新机器上即可。
3.1.2 mdadm.conf 文件丢失
把旧 raid 设备导入新机器后,需要重新使用命令将所有设备组装成一个名为 /dev/md[0-127]
的虚拟设备。
然后执行 mdadm --detail --scan >> /etc/mdadm.conf
(RedHat) 或者 mdadm --detail --scan >> /etc/mdadm/mdadm.conf
(Debian) 重新生成配置文件。
如果不重新生成配置文件,那么在系统重启之后还要再重新组装一遍设备。
假设用了四个盘,需要执行以下命令:
mdadm --assemble --scan --verbose /dev/md<number> /dev/<device-a-partition> /dev/<device-b-partition> /dev/<device-c-partition> /dev/<device-d-partition>
3.2 raid 序号与名字
每个 raid array 都对应一个 /dev/md[0-127]
条目,只要 raid 存在,这个条目必然存在。
3.2.1 更改 raid 设备序号
现有 raid1 设备 /dev/md127 要将其改为 /dev/md0。
- 移除 /dev/md127:
root@debian11:~# mdadm --stop /dev/md127 mdadm: stopped /dev/md127
- 用新序号重新组装 raid1:
# 如果 metadata 版本为 1.0 或更高版本,使用以下命令: root@debian11:~# mdadm --assemble /dev/md0 /dev/sd{b,c}1 mdadm: /dev/md0 has been started with 2 drives.
# 如果 metadata 版本为 0.90 (这个版本的 mdadm 允许内核自动组装) 或者更早,使用以下命令: root@debian11:~# mdadm --assemble /dev/md0 --update=super-minor /dev/sd[bc]1
- 最后
mdadm --detail --scan >> /etc/mdadm.conf
(RedHat) 或者mdadm --detail --scan >> /etc/mdadm/mdadm.conf
(Debian) 保存配置。
3.2.2 更改 raid name
现有 raid1 设备:
root@debian11:~# mdadm --detail --scan /dev/md0 ARRAY /dev/md0 metadata=1.2 name=debian11:0 UUID=3c59bf1a:aa2ed094:fe871a27:59f491b7 root@debian11:~# mdadm -D /dev/md0 /dev/md0: Version : 1.2 Creation Time : Tue Oct 19 20:05:20 2021 Raid Level : raid1 Array Size : 14054400 (13.40 GiB 14.39 GB) Used Dev Size : 14054400 (13.40 GiB 14.39 GB) Raid Devices : 2 Total Devices : 2 Persistence : Superblock is persistent Update Time : Sun Mar 20 22:00:33 2022 State : clean Active Devices : 2 Working Devices : 2 Failed Devices : 0 Spare Devices : 0 Consistency Policy : resync Name : debian11:0 (local to host debian11) UUID : 3c59bf1a:aa2ed094:fe871a27:59f491b7 Events : 299 Number Major Minor RaidDevice State 0 8 97 0 active sync /dev/sdg1 2 8 81 1 active sync /dev/sdf1
要将倒数第 7 行的 Name
改为 debian11:optane16ga
。
注: Name
值含义为 <homehost>:<name>
即前者为主机名 (/etc/hostname 里的值) 后者为 raid array 名称。
第一步,移除 /dev/md0:
root@debian11:~# mdadm --stop /dev/md0 mdadm: stopped /dev/md0
第二步,组装 raid1 时更新名称:
# 如果 metadata 版本为 1.0 或更高版本,使用以下命令: root@debian11:~# mdadm --assemble /dev/md0 /dev/sd{b,c}1 --name=optane16ga --update=name mdadm: /dev/md0 has been started with 2 drives.
最后一步 mdadm --detail --scan >> /etc/mdadm.conf
(RedHat) 或者 mdadm --detail --scan >> /etc/mdadm/mdadm.conf
(Debian) 保存配置。
3.3 更换损坏的磁盘
现有 /dev/sd{b,c}1
组成的 raid1 设备 /dev/md0,现 /dev/sdb 设备已损坏,需要在保证 /dev/md0 正常运行的情况下,将 /dev/sdb 移出 raid。
- 将 /dev/sdb1 标记为
fail
:mdadm --manage /dev/md0 --fail /dev/sdb1
root@debian11:~# mdadm --manage /dev/md0 --fail /dev/sdb1 mdadm: set /dev/sdb1 faulty in /dev/md0 root@debian11:~# cat /proc/mdstat Personalities : [raid1] md0 : active raid1 sdc1[2] sdb1[0](F) 7813343232 blocks super 1.2 [2/1] [_U] bitmap: 0/59 pages [0KB], 65536KB chunk unused devices: <none>
- 从 /dev/md0 中删除 /dev/sdb1:
mdadm --manage /dev/md0 --remove /dev/sdb1
root@debian11:~# mdadm --manage /dev/md0 --remove /dev/sdb1 mdadm: hot removed /dev/sdb1 from /dev/md0
- 此时,从机器上拿下 /dev/sdb,换上新磁盘并分区。假设新磁盘同样为 /dev/sdb 其上分区同样为 /dev/sdb1。
- 将新磁盘加入到 raid 中:
root@debian11:~# mdadm --manage /dev/md0 --add /dev/sdb1 mdadm: re-added /dev/sdb1
到此,操作完成。剩下的只要等数据被同步到新磁盘上即可。