Skip to main content

系统盘恢复

· 6 min read

喜欢使用 闪存盘/U 盘 作为 Linux 系统盘,但 U 盘 使用寿命有限,当异常后需要对系统盘进行更换。

现状#

使用 SanDisk CZ430 作为 系统盘/Root 分区

lsblk

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTsda      8:0    1 114.6G  0 disk├─sda1   8:1    1   128M  0 part /boot└─sda2   8:2    1 114.4G  0 part /

df -h /

Filesystem      Size  Used Avail Use% Mounted on/dev/sda2       113G  2.2G  106G   2% /

在使用一段时间后, U 盘 异常,系统被重新挂载为只读。

touch ~/test
touch: cannot touch '/home/admin/test': Read-only file system

dmesg 可看到异常信息,几个月前已经出问题了,因为系统还能正常使用暂且没管。

dmesg -T
[Tue Sep  7 16:48:16 2021] sd 2:0:0:0: [sda] tag#0 UNKNOWN(0x2003) Result: hostbyte=0x00 driverbyte=0x08 cmd_age=0s[Tue Sep  7 16:48:16 2021] sd 2:0:0:0: [sda] tag#0 Sense Key : 0x7 [current][Tue Sep  7 16:48:16 2021] sd 2:0:0:0: [sda] tag#0 ASC=0x27 ASCQ=0x0[Tue Sep  7 16:48:16 2021] sd 2:0:0:0: [sda] tag#0 CDB: opcode=0x2a 2a 00 00 04 16 90 00 00 08 00[Tue Sep  7 16:48:16 2021] blk_update_request: critical target error, dev sda, sector 267920 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0[Tue Sep  7 16:48:16 2021] Buffer I/O error on dev sda2, logical block 466, lost async page write

备份恢复方案#

将现在数据完整备份到新的 U 盘,重启即可,但恢复备份有好几种方式。

  1. 全盘 dd
  • 速度慢
  • 简单暴力
  • 需要提供至少现在磁盘大小的存储
  1. 重装 - 仅拷贝数据
  • 麻烦
  1. 恢复分区、恢复数据
  • 高效
  • 需要多一点操作
  • 新磁盘只需要已用空间大小即可

恢复#

因为这是已经第三四次恢复了,之前都是 dd,但这次打算用更高效的方式,且这次的系统盘为 128G,但目前只有 64G 的空闲 U 盘,故选择方案 3。

恢复过程

  1. 准备备份盘
  2. 分区表备份 & 启动分区备份
  3. root 分区 备份 & 修复
  4. 验证
  5. 关机
  6. 取掉坏的 U 盘
  7. 开机
恢复备份注意事项
  • 选择一个可写目录 - tmpfs,shm - 例如: /run, /var/run, /tmp, /dev/shm

准备备份盘#

  • 备份盘 /dev/sdb 64G,同 SanDisk CZ430
lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTsda      8:0    1 114.6G  0 disk├─sda1   8:1    1   128M  0 part /boot└─sda2   8:2    1 114.4G  0 part /sdb      8:16   1  57.3G  0 disk

分区表&启动分区备份#

# 确保使用 root 用户操作sudo su# 进入可写目录cd /run
# 正常情况分区表的备份恢复# sfdisk -d /dev/sda | sfdisk -f /dev/sdb
# 选择简单方式备份后再修改最后分区# 这里 dd 130MB - 同时把 boot 分区备份了dd if=/dev/sda of=/dev/sdb bs=1M count=130 status=progress
# 转储分区表sfdisk -d /dev/sda > sda.partition.table.txt# 删除第二个分区的大小sed -r '$ s/size=\s*\d+,//' -i sda.partition.table.txt# 重建分区sfdisk -f /dev/sdb < sda.partition.table.txt# 现在分区大小正常fdisk -l /dev/sdb
# 分区变化重新扫描mdev -spartprobe# 出现分区ls /dev/sdb*

root 分区备份#

  • root 分区一般较大,直接 dd 慢且伤 U 盘
  • 直接 dd 需要目标相同大小,否则丢数据
  • 这里使用 clone 数据方式
由于目标分区更小,不能直接复制
# ext4 数据拷贝 - 基于 ext4 block,只拷贝使用部分# 也可以用于生成 img 备份镜像之后用e2image -ra -p /dev/sda2 /dev/sdb2
  • 如果分区大小足够,直接复制即可

因为 root 分区为 120G,但实际只用了 2.2G, 先镜像分区,缩小分区,然后恢复到新的分区。

索性内存有 4G,因此直接在 /dev/shm 操作,否则需要外置存储。

# 从新挂载为 3G - 默认 2Gmount -o remount,size=3G /dev/shm# 制作镜像e2image -rap /dev/sda2 sda2.raw
# 修复分区 - 一般 U盘 损坏都会导致 fs 异常e2fsck -y sda2.raw# 缩小分区resize2fs sda2.raw 4G# 恢复e2image -rap sda2.raw /dev/sdb2# 扩展分区resize2fs /dev/sdb2

验证#

fsck /dev/sdb1fsck /dev/sdb2
mount /dev/sdb2 /mntmount /dev/sdb1 /mnt/boot# 不应该有变化rsync -vna /boot/ /mnt/boot/
# 由于 fsck 修复,可能 root 分区大小不同df / /mnt /boot /mnt/boot

如果装有 qemu,还可以直接启用 qemu 验证,目前就简单确认文件没问题即可。

# 准备关机重启umount -R /mnteject /dev/sdb
poweroff

取掉 坏的 U 盘,启动。

一切恢复正常。🎉

总结#

系统盘恢复还是相当容易,但 CZ430 确实有点老了,在 2017 年左右上市,相同规格已经卖 4、5 年了,性能各方面有所欠缺,之后会尽量选择 Lexar S47。

此外使用 U 盘 做系统盘的时候,一定注意修改 docker 之类的数据目录为其他存储,因为跑实际应用的时候 U 盘 性能是不足的,且数据库类型应用的小 BlockSize IO 不适合 U 盘。