BUG现象:两块4T硬盘,组raid1,其中一块硬盘故障,更换新硬盘后,在添加修复新硬盘时报错.如下图

1,一开始怀疑和缓存盘有关,删除后无效.
2,然后根据报错,发现与系统自带的 mdadm 有关.(mdadm是linux下用于创建和管理软件RAID的命令)
3,开启SSH,登录root账号.(自行搜索一下,root账号)
4,下面是一些mdadm的常用命令.
# 查看RAID状态
sudo mdadm --detail /dev/md0
# 重新激活阵列
sudo mdadm --run /dev/md0
# 如果设备丢失,重新添加
sudo mdadm --manage /dev/md0 --add /dev/sdb1
1. 如果RAID阵列掉线或降级
bash
# 查看RAID状态
sudo mdadm --detail /dev/md0
# 重新激活阵列
sudo mdadm --run /dev/md0
# 如果设备丢失,重新添加
sudo mdadm --manage /dev/md0 --add /dev/sdb1
2. 如果设备被标记为故障
bash
# 查看故障设备
cat /proc/mdstat
# 移除故障设备
sudo mdadm --manage /dev/md0 --remove /dev/sdb1
# 重新添加设备
sudo mdadm --manage /dev/md0 --add /dev/sdb1
3. 如果RAID无法启动
bash
# 停止阵列
sudo mdadm --stop /dev/md0
# 重新组装
sudo mdadm --assemble /dev/md0 /dev/sdb1 /dev/sdc1
# 或者强制组装
sudo mdadm --assemble --force /dev/md0 /dev/sdb1 /dev/sdc1
4. 如果配置文件有问题
bash
# 重新扫描阵列
sudo mdadm --assemble --scan
# 更新配置文件
sudo mdadm --detail --scan >> /etc/mdadm/mdadm.conf
sudo update-initramfs -u
5. 检查硬盘健康状况
bash
# 检查硬盘SMART信息
sudo smartctl -a /dev/sdb
# 检查硬盘坏道
sudo badblocks -sv /dev/sdb
1. 查看详细状态
bash
sudo mdadm --detail /dev/md0
2. 检查缺失的设备
bash
# 查看所有硬盘
lsblk
# 检查哪些设备应该属于这个阵列
sudo mdadm --examine /dev/sda1
sudo mdadm --examine /dev/sdb1
sudo mdadm --examine /dev/sdc1
3. 重新添加缺失的设备
假设缺失的设备是 /dev/sda1:
bash
# 如果设备存在但未加入阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1
# 如果设备有问题,先停止再重新添加
sudo mdadm --manage /dev/md0 --fail /dev/sda1 --remove /dev/sda1
sudo mdadm --manage /dev/md0 --add /dev/sda1
4. 监控重建进度
bash
# 实时监控重建进度
watch cat /proc/mdstat
# 或者查看详细进度
watch "sudo mdadm --detail /dev/md0 | grep -i rebuild"
5. 如果设备物理上不存在或损坏
如果另一个设备确实损坏或不存在,您可以:
bash
# 将阵列降级为单设备运行(临时方案)
# 或者添加一个新设备
sudo mdadm --manage /dev/md0 --add /dev/sdc1
6. 更新配置文件
修复完成后:
bash
# 更新mdadm配置
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
# 更新initramfs
sudo update-initramfs -u
1. 检查设备状态
bash
# 检查设备是否存在且可访问
ls -la /dev/sda1
sudo fdisk -l /dev/sda
# 检查设备是否已经被其他阵列使用
sudo mdadm --examine /dev/sda1
2. 检查设备上的 RAID 超级块
bash
# 检查是否有冲突的RAID信息
sudo mdadm --examine /dev/sda1
# 如果显示有旧的RAID信息,需要清除
sudo mdadm --zero-superblock /dev/sda1
注意: 执行 --zero-superblock 前请确认这个设备不包含重要数据!
3. 检查分区类型
bash
# 查看分区类型
sudo fdisk -l /dev/sda
# 确保分区类型是 Linux RAID (fd)
sudo fdisk /dev/sda
# 在fdisk中:输入 t → 选择分区1 → 输入 fd → w 保存
4. 检查设备大小是否匹配
bash
# 比较两个设备的大小
lsblk /dev/sda1 /dev/sdb1
sudo blockdev --getsize64 /dev/sda1
sudo blockdev --getsize64 /dev/sdb1
5. 完整的修复流程
bash
# 1. 停止阵列(可选,如果数据重要请先备份)
sudo mdadm --stop /dev/md0
# 2. 清除设备上的超级块
sudo mdadm --zero-superblock /dev/sda1
sudo mdadm --zero-superblock /dev/sdb1
# 3. 重新创建阵列
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
# 或者如果不想丢失数据,尝试强制添加
sudo mdadm --manage /dev/md0 --add /dev/sda1 --force
6. 如果设备有物理问题
bash
# 检查硬盘健康状态
sudo smartctl -a /dev/sda
# 检查硬盘错误
dmesg | grep sda
# 测试读写
sudo badblocks -sv /dev/sda1
7. 替代方案:使用不同的设备
如果有其他可用硬盘:
bash
# 使用 /dev/sdc1 替代
sudo mdadm --manage /dev/md0 --add /dev/sdc1
建议的执行顺序
- 先执行第1步检查设备状态
- 执行第2步检查RAID超级块
- 执行第4步检查设备大小
解决方案
方案1:清除设备并重新添加(推荐)
bash
# 1. 确保设备没有挂载
sudo umount /dev/sda1
# 2. 清除设备上可能存在的残留RAID信息
sudo mdadm --zero-superblock /dev/sda1
# 3. 强制将设备添加到阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1
方案2:如果方案1失败,重新创建分区
bash
# 1. 创建与sdb1相同的分区布局
sudo sfdisk -d /dev/sdb | sudo sfdisk /dev/sda
# 2. 设置分区类型为Linux RAID
sudo parted /dev/sda set 1 raid on
# 3. 添加到阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1
方案3:使用特定元数据版本创建
bash
# 停止当前阵列(确保有备份!)
sudo mdadm --stop /dev/md0
# 重新创建阵列,指定元数据版本
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=1.2 /dev/sda1 /dev/sdb1
检查步骤
在执行上述方案前,请先确认:
1. 检查当前设备状态
bash
# 确认设备大小匹配
lsblk /dev/sda1 /dev/sdb1
# 检查sda1是否真的没有RAID信息
sudo mdadm --examine /dev/sda1
2. 检查分区表
bash
sudo fdisk -l /dev/sda
sudo fdisk -l /dev/sdb
如果以上方案都不工作
方案4:完全重新初始化设备
bash
# 1. 擦除设备开头部分(清除所有文件系统签名)
sudo dd if=/dev/zero of=/dev/sda1 bs=1M count=100
# 2. 重新添加到阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1
推荐执行顺序
- 先尝试方案1
- 如果失败,执行检查步骤确认设备状态
- 然后尝试方案2
- 最后考虑方案4
解决方案
方案1:强制添加设备
bash
# 强制将设备添加到阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1 --force
方案2:如果方案1失败,停止并重新组装阵列
bash
# 1. 停止当前阵列
sudo mdadm --stop /dev/md0
# 2. 重新组装阵列,包含两个设备
sudo mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1
# 3. 如果仍然有问题,强制组装
sudo mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1 --force
方案3:检查并修复设备状态
bash
# 检查设备是否有坏块
sudo badblocks -sv /dev/sda1
# 如果发现有坏块,尝试修复
sudo fsck -vcck /dev/sda1
方案4:手动指定设备角色
bash
# 停止阵列
sudo mdadm --stop /dev/md0
# 使用指定设备重新创建(会开始同步)
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sda1 --assume-clean
推荐执行顺序
-
首先尝试方案1(最简单且风险最低):
bash
sudo mdadm --manage /dev/md0 --add /dev/sda1 --force
-
如果方案1失败,尝试方案2:
bash
sudo mdadm --stop /dev/md0
sudo mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1 --force
-
监控重建进度:
bash
watch cat /proc/mdstat
深度解决方案
方案1:完全清除并重新初始化设备
bash
# 1. 完全擦除设备开头的所有元数据
sudo dd if=/dev/zero of=/dev/sda1 bs=1M count=1000
# 2. 重新扫描设备
sudo partprobe /dev/sda
# 3. 将设备添加到阵列
sudo mdadm --manage /dev/md0 --add /dev/sda1
方案2:使用低级设备访问(绕过分区)
bash
# 1. 停止阵列
sudo mdadm --stop /dev/md0
# 2. 直接使用整个磁盘而不是分区
sudo mdadm --assemble /dev/md0 /dev/sdb1 /dev/sda
# 或者如果上面不行,尝试:
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sda --force
方案3:检查分区对齐和大小
bash
# 检查两个设备的分区表是否完全相同
sudo sfdisk -d /dev/sdb | sudo sfdisk /dev/sda
# 重新设置分区类型
sudo parted /dev/sda set 1 raid on
# 重新扫描
sudo partprobe /dev/sda
方案4:手动修复超级块
bash
# 基于sdb1的信息手动创建超级块
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 missing --force
sudo mdadm --manage /dev/md0 --add /dev/sda1 --force
方案5:使用不同的元数据版本
bash
# 停止阵列
sudo mdadm --stop /dev/md0
# 使用默认元数据版本重新创建
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sda1 --metadata=default
1. 检查并卸载文件系统
bash
# 检查是否已挂载
mount | grep md0
df -h | grep md0
# 如果已挂载,卸载它
sudo umount /dev/md0
# 如果卸载失败,检查哪个进程在使用
sudo lsof /dev/md0
sudo fuser -v /dev/md0
2. 检查 LVM 使用情况
bash
# 检查是否有 LVM 卷组使用此设备
sudo pvs | grep md0
sudo vgs | grep md0
sudo lvs | grep md0
# 如果有,停用卷组
sudo vgchange -an <卷组名>
3. 停止使用 RAID 的进程
bash
# 强制终止使用设备的进程
sudo fuser -k /dev/md0
# 或者使用 lsof 找到并手动终止进程
sudo lsof /dev/md0
4. 如果以上方法都不行,尝试强制停止
bash
# 强制停止 RAID 设备
sudo mdadm --stop /dev/md0 --force
完整的修复流程
一旦您获得了对设备的独占访问权:
bash
# 1. 确保设备未挂载且未被使用
sudo umount /dev/md0 2>/dev/null || true
# 2. 停止阵列
sudo mdadm --stop /dev/md0
# 3. 清除 sda1 的超级块
sudo dd if=/dev/zero of=/dev/sda1 bs=1M count=1000
sudo partprobe /dev/sda
# 4. 重新创建阵列
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sda1 --force
# 5. 监控重建进度
watch cat /proc/mdstat
替代方案:使用不同的设备名称
如果 /dev/md0 被系统锁定,可以尝试使用不同的设备名称:
bash
# 停止当前阵列
sudo mdadm --stop /dev/md0
# 使用不同的名称重新组装
sudo mdadm --assemble /dev/md1 /dev/sdb1 /dev/sda1 --force
紧急情况下的处理
如果数据非常重要且您无法停止使用中的设备:
bash
# 创建只读快照(如果使用 LVM)
sudo lvcreate -s -n raid_backup -L 1G /dev/md0
# 或者直接复制数据到安全位置
sudo dd if=/dev/md0 of=/path/to/backup.img bs=1M status=progress
推荐执行顺序
-
首先检查并卸载文件系统:
bash
mount | grep md0
sudo umount /dev/md0
-
检查并处理 LVM:
bash
sudo pvs | grep md0
sudo vgchange -an <卷组名> # 如果找到卷组
-
停止阵列:
bash
sudo mdadm --stop /dev/md0
-
如果常规停止失败,使用强制停止:
bash
sudo mdadm --stop /dev/md0 --force