为什么无法通过 ddrescue 动态压缩图像?

为什么无法通过 ddrescue 动态压缩图像?

我正在尝试使用 GNU 的救援。该驱动器相当大(1TB),而我存储图像所需的只是另一个 1TB 驱动器。

ddrescue 接近尾声时失败,出现磁盘空间错误,即使使用了 -S 选项。

为什么不能在创建图像时对其进行压缩?可以使用dd_救援

还,人力救援说 -S 选项并不在所有系统上都起作用,但我怎么知道它是否在我的系统上起作用?

答案1

gddrescue 不会按顺序对文件进行映像处理 - 它会返回并重试,并填补空白,我怀疑这就是为什么你不能有效地将它传输到其他东西中。手册页对此进行了详细介绍

GNU ddrescue 可以高效地管理正在进行的救援状态,并尝试首先救援好的部分,将读取坏的(或慢的)区域安排在稍后进行。这样可以最大限度地增加最终可以从故障驱动器中恢复的数据量。

标准 dd 实用程序可用于保存故障驱动器中的数据,但它会按顺序读取数据,如果错误发生在驱动器的开头,这可能会磨损驱动器而无法挽救任何东西。

其他程序在发现错误时会切换到小尺寸读取,但它们仍按顺序读取数据。这是一个坏主意,因为这意味着在错误区域花费更多时间,损坏表面、磁头和驱动器机械装置,而不是尽快摆脱它们。这种行为降低了挽救剩余好数据的机会。

这是设计使然,不幸的是,解决方案是获得更大的驱动器。为了使 -S 参数起作用,我相信源驱动器上的已用空间必须小于目标驱动器。

答案2

可以压缩使用ddrescue即时创建的图像。问题是,ddrescue需要一个可搜索的目的地,因为它将经过几个过程(因此必须能够向后跳转以填补早期的空白,正如@JourneymanGeek 在他的回答)。这意味着您不能使用管道作为输出,因为管道不可寻址。因此您无法通过管道传输到压缩程序。

解决这个问题的一种方法是使用透明压缩。一些文件系统(尤其是 Btrfs 等)提供内置功能。或者,您可以使用文件系统驱动程序来提供透明、可寻址的压缩存储,例如保险丝压缩

答案3

这里有一篇很好的文章brashear.me这会创建一个存储为文件的 btrfs 分区。该分区支持压缩,并可由 ddrescue 透明地使用。如果博客文章不可用,请在下面重现。

随着磁盘大小的激增,我发现自己不得不镜像没有足够存储空间的磁盘。我选择的工具是 ddrescue。但是,它不支持压缩,因为它需要能够在恢复数据时查找输出。我发现的一个解决方案是创建一个稀疏文件,将其格式化为 btrfs,并使用压缩选项挂载它。这允许 ddrescue 正常运行,同时为我提供快速且不错的压缩。

创建一个比源磁盘更大的稀疏文件:

dd if=/dev/zero bs=1 count=0 seek=4T of=image-repository.img

将此文件挂载为循环设备:

sudo losetup /dev/loop0 image-repository.img

对循环设备进行分区:

sudo gdisk /dev/loop0 

按下 创建新的 GPT,o然后按y

n通过按下并按几次回车键来接受默认设置,从而创建新的分区。

w按下然后写入表格y

从循环设备重新读取分区:

sudo partprobe /dev/loop0

格式化loop0p1分区:

sudo mkfs.btrfs /dev/loop0p1

在启用压缩的情况下挂载文件系统。有效的压缩选项包括 zlib, lzo, zstd

mkdir /mnt/img-repo
sudo mount -o compress=zstd /dev/loop0p1 /mnt/img-repo

在挂载目录上设置 c 属性:

sudo chattr +c /mnt/img-repo

现在,当您在文件夹ddrescue内创建图像时/mnt/img-repo/ ,它将被透明压缩!

稍后,您可以使用以下方式访问 ddrescue 的图像:

losetup --find --show image-repository.img
partprobe /dev/loopX     //where X is the output of the previous command
mkdir /mnt/img-repo
mount -o compress=zstd /dev/loopXp1 /mnt/img-repo
chattr +c /mnt/img-repo
cd /mnt/img-repo

您可以使用以下命令检查 ddrescue 图像的内容:

losetup --read-only --find --show /mnt/img-repo/disk.img
mkdir /mnt/recovered_files/
mount /dev/loopXp1 /mnt/recovered_files/     //where X is the output of the previous command

相关内容