用 mdadm 创建 RAID1 并模拟磁盘故障恢复

软 RAID(mdadm)相比硬 RAID 卡的优势是便宜 + 透明 + 跨硬件可迁移。
代价是占一点 CPU、组装比硬 RAID 复杂。家庭 NAS / 小型服务器很常用 RAID1
(镜像)做最基础的硬盘冗余。

下面用 /dev/sdb/dev/sdc 两块同型号硬盘做 RAID1,挂到 /srv/data

1. 准备分区

# 看现状
lsblk
sudo wipefs -a /dev/sdb /dev/sdc   # 清残留 FS / 分区表签名

# 给两块盘都建一个 Linux RAID 类型的分区
for d in /dev/sdb /dev/sdc; do
  sudo parted -s "$d" mklabel gpt
  sudo parted -s "$d" mkpart primary 1MiB 100%
  sudo parted -s "$d" set 1 raid on
done

lsblk
# sdb      8:16   0  4T  0 disk
# └─sdb1   8:17   0  4T  0 part
# sdc      8:32   0  4T  0 disk
# └─sdc1   8:33   0  4T  0 part

2. 创建 RAID1

sudo mdadm --create /dev/md0 \
  --level=1 \
  --raid-devices=2 \
  --metadata=1.2 \
  --name=md0 \
  /dev/sdb1 /dev/sdc1
# Continue creating array? y

初始化(resync)会在后台跑,过程中阵列可用但慢:

cat /proc/mdstat
# Personalities : [raid1]
# md0 : active raid1 sdc1[1] sdb1[0]
#       3906886976 blocks super 1.2 [2/2] [UU]
#       [>....................]  resync =  3.6% (142336640/3906886976) finish=312.4min speed=200800K/sec

watch -n 5 cat /proc/mdstat   # 看进度

不想等 resync 也能立刻继续下面步骤(性能会差点)。

3. 文件系统 + 挂载

sudo mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -L data /dev/md0
sudo mkdir /srv/data
sudo mount /dev/md0 /srv/data
df -h /srv/data

写入 fstab:

echo "LABEL=data /srv/data ext4 defaults,nofail 0 2" \
  | sudo tee -a /etc/fstab
# nofail:万一阵列没起来,启动不会卡死

4. 保存 mdadm 配置(关键,否则 reboot 后阵列名变)

sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
# ARRAY /dev/md/md0 metadata=1.2 name=hostname:md0 UUID=...

sudo update-initramfs -u

5. 模拟磁盘故障(演练,重要)

任何 RAID 都要做一次"假装坏一块"的演练,确认告警 + 替换流程通畅。

# 标记 sdb1 为 faulty
sudo mdadm /dev/md0 --fail /dev/sdb1
cat /proc/mdstat
# md0 : active raid1 sdc1[1] sdb1[0](F)
#       3906886976 blocks super 1.2 [2/1] [_U]
#       ^^^^^^ 缺一块 ^^^

# 应用仍在跑(RAID1 可单盘工作)
echo hello | sudo tee /srv/data/test.txt
cat /srv/data/test.txt

# 从阵列移除 faulty 盘
sudo mdadm /dev/md0 --remove /dev/sdb1

# 模拟换上新盘(这里直接加回来;现实里换新硬盘后重新分区然后加)
sudo mdadm /dev/md0 --add /dev/sdb1
cat /proc/mdstat
# [=>...................]  recovery = 5.4% ...
# 等几小时到几天,看盘大小

resync 完成后 [2/2] [UU],恢复完整冗余。

6. 监控 + 告警

# 邮件告警(前提是本机能寄信,参考 unattended-upgrades 那篇)
echo "MAILADDR [email protected]" | sudo tee -a /etc/mdadm/mdadm.conf
sudo systemctl restart mdmonitor

# 直接测试一封"假告警"
sudo mdadm --monitor --test --oneshot /dev/md0

或 Prometheus node_exporter 已经导 node_md_state 指标,PromQL:

node_md_state{state="failed"} > 0

7. 扩 RAID1 容量(替换两块盘为更大的)

# 1. 一块一块替换:fail + remove + 物理换新盘 + add
sudo mdadm /dev/md0 --fail /dev/sdb1 --remove /dev/sdb1
# 物理换更大新盘,分区 raid on,mdadm --add,等同步完
sudo mdadm /dev/md0 --add /dev/sdb1
# wait resync
# 2. 重复对 sdc1

# 3. 两块都换大盘后,扩 md 用满
sudo mdadm --grow /dev/md0 --size=max
sudo resize2fs /dev/md0

踩过的坑

  • 用不同型号 / 大小 / 转速的盘做 RAID1 不犯法但很糟:性能 = 慢盘,
    寿命差异大容易"双故障"。
  • 整盘做 RAID(不分区,直接 /dev/sdb)也行但碰到换不同型号盘时尺寸
    不能完全匹配。建议永远先分区给它(且留 100MB 余量)。
  • nofail 在 fstab 里很重要——RAID 同步还没完成或某块盘没认到,
    没 nofail 会进 emergency mode。
  • 软 RAID 替代不了备份。RAID 防硬件故障,不防误删 / 加密勒索 / FS 损坏。
    独立做异地备份。
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。