我需要以一种可以轻松恢复数据和系统的方式创建 Ubuntu 系统的备份,因为它完全处于就绪状态。所以,我决定去dd
创建一个完整的 HHD 图像。
我创建的图像如下:
dd if=/dev/current_drive of=/dev/backup_drive/backup.img conv=sync status=progress
图像已完成,没有错误。之后,我决定将映像恢复到测试新驱动器:
dd if=/backup_drive/backup.img of=/dev/new_drive conv=sync status=progress
到目前为止,一切都很好。图像恢复没有错误。但是当我尝试从恢复映像的新硬盘启动时,我遇到了initramfs
错误:
因此,在手动操作后,fsck
错误被清除,我能够从新的硬盘驱动器启动。但我尝试了几次将映像恢复到驱动器的过程,每次都遇到启动问题。根据我的原始系统驱动器和新系统驱动器完全相同
sudo fdisk -l
:
/dev/sda/
是新硬盘。
/dev/sdb/
是创建图像的原始图像。
Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xf11c2eb5
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 455024639 455022592 217G 83 Linux
/dev/sda2 455026686 488396799 33370114 15.9G 5 Extended
/dev/sda5 455026688 488396799 33370112 15.9G 82 Linux swap / Solaris
Disk /dev/sdb: 232.9 GiB, 250059350016 bytes, 488397168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xf11c2eb5
Device Boot Start End Sectors Size Id Type
/dev/sdb1 * 2048 455024639 455022592 217G 83 Linux
/dev/sdb2 455026686 488396799 33370114 15.9G 5 Extended
/dev/sdb5 455026688 488396799 33370112 15.9G 82 Linux swap / Solaris
那么,您知道我做错了什么以及为什么在映像恢复后出现启动错误吗?我不希望在实际情况下,在原始硬盘出现故障的情况下必须修复最终的新硬盘。
顺便说一句,原始驱动器是 SSD,而新驱动器是 HDD(如果这很重要的话)。
答案1
当你dd
,
基本上,成功且一致的直接磁盘复制只能通过像 Live CD 这样的独立系统来实现,并且即使那样你也必须小心关于文件系统在您不知情的情况下自动安装的问题。
此外,如果您预计会出现读取错误(因此sync
、noerror
和其他conv
选项),那么使用它会更可靠ddrescue
。它可以正确处理读取错误,甚至具有重试和恢复的能力。
总而言之,块级副本往往不可靠,因为很容易出错。这样做的唯一原因是,这是生成副本的唯一方法完美的一致性(仅当做得正确时)。
所有其他方法都只是够好了在实践中,永远不会完美。对于将一半数据保留在内存中、另一半数据保留在磁盘上的正在运行的进程,无法制作完美的副本。您必须将其关闭才能获得完整图像。 (或者虚拟化所有内容并冻结它。)
还有其他选择:
- 使用 cp、rsync 或专用备份程序进行基于文件的备份博格
- 文件系统特定工具(xfsdump、btrfs 发送/快照...)
- 左心室容量快照(但不使用 btrfs)
- 数据库需要特殊处理并提供自己的备份工具
如果它必须是块级副本,您还可以滥用 mdadm 系统在源驱动器上放置 RAID 1 层,并通过添加目标驱动器使用它从正在运行的系统中生成一致的副本。 RAID 使双方保持完美同步,从而在很大程度上避免了不一致问题(前提是您允许在删除目标驱动器之前完成同步)。
# RAID creation (before installing Linux)
mdadm --create /dev/md0 --level=1 --raid-devices=1 --force /dev/source
# /proc/mdstat
md0 : active raid1 sda2[3]
134306472 blocks super 1.2 [1/1] [U]
# Add the target drive.
mdadm --grow /dev/md0 --raid-devices=2 --force
mdadm --manage /dev/md0 --add --write-mostly /dev/target
# Wait for RAID resilvering.
mdadm --wait /dev/md0
sync
# Remove the target drive.
mdadm /dev/md0 --fail /dev/target
mdadm /dev/md0 --remove /dev/target
mdadm --grow /dev/md0 --raid-devices=1 --force
但这是一种黑客攻击,副本仍然会显示为未正确卸载的文件系统。这比断电稍微糟糕一些,因为sync
当您意外断电时您无法执行此操作。但比dd
图像前半部分的状态落后后半部分几个小时的情况要好几个数量级。
我每周都会使用这种方法将单个 SSD 驱动器镜像到 HDD,而不会妨碍 HDD 待机。如果 SSD 出现故障,HDD 可以轻松启动。
当然,使用基于文件的副本也可以实现相同的目的。
既然您提到了 UUID,那么在块级别克隆驱动器将克隆 UUID,这反过来可能会导致灾难。 (在上述 RAID 攻击的情况下,它们很方便地隐藏在 RAID 层后面。)
基于文件的复制到新文件系统将具有新的 UUID,但解决起来相当简单:
chroot
,编辑/etc/fstab
,更新 initramfs,重新安装引导加载程序(基本上每个 Linux wiki 中都可以找到 chroot 方法)- 否则,通过使用 更改旧的 UUID 来恢复旧的 UUID
tune2fs -U <UUID>
,其他文件系统也有类似的工具(需要文档,否则您将不知道所需的 UUID)。再次强调,小心不要重复它们,只有在旧设备完全消失时才这样做。