李守中

mdadm 软 raid 相关

Table of Contents

1 raid array 中的设备

1.1 应该使用设备上的分区而不是整个设备

李守中认为应该使用磁盘分区作为 raid array 的组成部分,而不应直接使用整个磁盘。

不同制造商生产的磁盘 (甚至同一制造商生产的,标称容量相同的,不同型号的磁盘) 不一定具有完全相同的磁盘大小。这就意味着,在由多个整磁盘 (而不是用分区) 组建的 raid array 中,某个设备出现损坏时,用来替换已损坏磁盘的新盘必须和坏盘拥有相同的容量。当容量不同时,新盘无法替换旧盘。

使用磁盘分区作为 raid array 的组成部分可以避免因磁盘容量差异而导致的问题。

1.2 存储设备分区策略

分区策略为: 每个磁盘上的分区大小 = 容量最小的磁盘上的分区的大小 ,并且 用于 raid 的分区的大小 < 多个磁盘设备中容量最小的磁盘设备的大小

例如,两个标称容量为 3TB 磁盘组 RAID1:

  1. sudo parted -l 命令显示容量最小的磁盘的容量为 3002G。
  2. 分区容量必须小于 3002G,这里取 3001G,其余空间被浪费。
  3. 同样地,另一个硬盘上的分区大小必须和前一个硬盘上的分区大小相同,也取 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>

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。现在它已经被取消挂载。

  1. mdadm --stop /dev/md1 停止这个阵列。
  2. /etc/mdadm.conf 中删除对应的配置行。
  3. 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。

  1. 移除 /dev/md127:
root@debian11:~# mdadm --stop /dev/md127
mdadm: stopped /dev/md127
  1. 用新序号重新组装 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
  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。

  1. 将 /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>
  1. 从 /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
  1. 此时,从机器上拿下 /dev/sdb,换上新磁盘并分区。假设新磁盘同样为 /dev/sdb 其上分区同样为 /dev/sdb1。
  2. 将新磁盘加入到 raid 中:
root@debian11:~# mdadm --manage /dev/md0 --add /dev/sdb1
mdadm: re-added /dev/sdb1

到此,操作完成。剩下的只要等数据被同步到新磁盘上即可。



Last Update: 2023-08-13 Sun 14:31

Contact: [email protected]     Generated by: Emacs 27.1 (Org mode 9.3)

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议