摘要

在 Raspberry Pi 上运行 Ubuntu 或 Raspberry Pi OS 时,如果发生异常断电或 SD 卡老化,常会导致 ext4 文件系统元数据损坏,表现为启动进入 initramfs、fsck 报错、甚至出现异常输出(如大量负数刷屏)。
当系统仍可启动时,最佳做法不是继续在原卡上修复,而是将当前系统整体迁移到一张健康的新存储介质。

本文记录了一次真实的灾难恢复流程:
在原 64GB SD 卡发生 ext4 元数据错误后,将系统无重装迁移到一张 8GB 新 SD 卡,并保证系统可以从新卡稳定启动。


问题背景

系统在一次强制断电后启动失败,进入 initramfs,并提示:

The root filesystem on /dev/mmcblk0p2 requires a manual fsck

执行 fsck 后虽然可以重新启动,但内核日志中出现:

EXT4-fs error: ext4_validate_block_bitmap: bad block bitmap checksum

这类错误并非单纯 journal 未回放,而是 ext4 从底层存储读到了不一致的数据,说明原 SD 卡已经出现 silent corruption(隐性数据损坏)。

此时继续在原卡上使用会导致未来随机文件损坏,因此必须迁移系统。


目标

  • 不重装系统
  • 保留所有用户数据、配置和服务
  • 将系统从 64GB 迁移到 8GB 新 SD 卡
  • 消除因 LABEL 启动导致的盘识别不确定性

环境

  • 原系统盘:/dev/mmcblk0(64GB,ext4 损坏过)
  • 新 SD 卡(通过 USB 读卡器):/dev/sda(8GB)
  • 系统:Ubuntu 24.04 LTS for Raspberry Pi

1. 对新 SD 卡重新分区

sudo parted /dev/sda

在 parted 交互中输入:

mklabel msdos
mkpart primary fat32 1MiB 512MiB
mkpart primary ext4 512MiB 100%
set 1 boot on
quit

2. 创建文件系统

sudo mkfs.vfat -F32 /dev/sda1
sudo mkfs.ext4 /dev/sda2

3. 挂载新系统盘

sudo mkdir -p /mnt/newroot
sudo mount /dev/sda2 /mnt/newroot
sudo mkdir -p /mnt/newroot/boot/firmware
sudo mount /dev/sda1 /mnt/newroot/boot/firmware

4. 复制整个系统

sudo rsync -aAXHv \
  --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
  / /mnt/newroot

这一步将当前运行的系统完整复制到新卡,包括:

  • /etc
  • /home
  • /var
  • Docker / 数据库
  • 所有用户数据

5. 获取新卡 UUID

sudo blkid /dev/sda1 /dev/sda2

示例:

/dev/sda1 UUID="A4C9-1F7B" TYPE="vfat"
/dev/sda2 UUID="0e043177-572f-45da-b348-76e0be64aa0c" TYPE="ext4"

6. 修改 fstab

编辑新系统的 fstab:

sudo nano /mnt/newroot/etc/fstab

改为:

UUID=0e043177-572f-45da-b348-76e0be64aa0c   /              ext4   defaults  0  1
UUID=A4C9-1F7B                            /boot/firmware  vfat   defaults  0  1

不再使用 LABEL,避免多盘环境下挂错根分区。


7. 修改启动参数

sudo nano /mnt/newroot/boot/firmware/cmdline.txt

将:

root=LABEL=writable

改为:

root=UUID=0e043177-572f-45da-b348-76e0be64aa0c

整行示例:

console=serial0,115200 multipath=off dwc_otg.lpm_enable=0 console=tty1 root=UUID=0e043177-572f-45da-b348-76e0be64aa0c rootfstype=ext4 rootwait fixrtc

8. 关机并切换存储卡

sync
sudo poweroff

操作:

  • 拔掉 64GB 原卡
  • 将 8GB 新卡插入树莓派内置 SD 槽
  • 开机

9. 验证启动介质

lsblk

应看到:

mmcblk0   7.5G
└─mmcblk0p2   /

说明系统已从新卡启动。


10. 对新卡做最终校验

sudo fsck.ext4 -f /dev/mmcblk0p2

应返回:

clean

这表示新介质上的文件系统是完整且可靠的。


技术要点总结

设计点说明
不使用 dd因为目标盘更小
使用 rsync避免读取原卡坏块
使用 UUID避免 LABEL 挂错盘
迁移后 fsck验证新介质稳定性

结语

当 Raspberry Pi 的 SD 卡发生 ext4 元数据错误时,最安全的做法不是反复 fsck,而是在文件系统仍可挂载时,将整个系统迁移到新的存储介质。
使用 rsync + UUID 启动可以在不重装系统的前提下完成灾难级恢复,并显著提升系统长期稳定性。

这套流程适用于 Ubuntu / Raspberry Pi OS 等所有使用 ext4 的树莓派系统。

Leave a Reply

Your email address will not be published. Required fields are marked *