为什么 dd 需要太长时间?

KKD*_*KKD 23 dd hard-disk

我需要将一个磁盘复制到另一个磁盘。我尝试使用下面的命令,在 federo 中复制 1 TB 的磁盘需要将近一天的时间。

dd if=/dev/sda of=/dev/sdb 
Run Code Online (Sandbox Code Playgroud)

我已经使用以下命令在 Unix(HP-UX) 系统上尝试了相同的操作,并在几个小时内完成

dd if=/dev/sda of=/dev/rdsk
Run Code Online (Sandbox Code Playgroud)

我可以用什么替代方法来更快地从磁盘复制到磁盘?

Bas*_*tch 36

dd有许多(奇怪的)选项,请参阅dd(1)

您应该明确说明缓冲区大小,因此请尝试

dd if=/dev/sda of=/dev/sdb bs=16M
Run Code Online (Sandbox Code Playgroud)

IIRC,默认缓冲区大小仅为 512 字节。上面的命令将其设置为 16 兆字节。你可以尝试更小的东西(例如bs=1M),但你应该使用比默认值更多的东西(特别是在最近的具有 4KB 扇区的磁盘硬件上,即Advanced Format)。我天真地推荐一些至少为 1 兆字节的 2 的幂。

使用默认的 512 字节缓冲区大小,我猜(但我可能非常错误)硬件要求内核为每个 512 字节块传输 4K。

关于rdsksd(4)手册页说:

目前只提供块设备。原始设备尚未实现。

增加 dd 的缓冲区大小将为您提供更高的读写操作性能。现在所有磁盘都有硬件读/写缓冲区。但是如果你增加 dd 的缓冲区大小超过硬件缓冲区,它的性能会下降,因为当第二个磁盘从它自己的硬件缓冲区写入所有内容时,dd 将从第一个磁盘读取到缓冲区。您需要bs为不同的设备每次设置不同的 dd 命令选项。

  • 有趣的是,在 macOS(经过 SUS 认证,顺便说一句)中,执行时[使用 `/dev/rdiskX`](https://www.raspberrypi.org/forums/viewtopic.php?t=21995) 作为目标会更快`dd`。 (2认同)
  • 如果你想知道发生了什么(就像我做的那样)还添加 `status=progress`,它将打印整个操作进度。 (2认同)

roa*_*ima 22

多年前在 Unix 领域dd是复制块设备所需的方式。尽管(至少在基于 Linux 的系统上)cat几乎总是比dd.

然而,即使在历史上,适当的块大小也有助于减少(慢)系统调用的数量,因为每个系统调用都会触发一次 I/O 操作。默认块大小为 512 字节(一个磁盘扇区)。将多个磁盘块一起收集到单个读取中是 - 而且是 - 也是可以接受的。此示例使用 32MB 块大小:

dd bs=$((512*2048*32)) if=/dev/source of=/dev/target
Run Code Online (Sandbox Code Playgroud)

但是,在当前基于 Linux 的系统上,可以通过简单的方式最有效地复制磁盘 cat

cat /dev/source >/dev/target
Run Code Online (Sandbox Code Playgroud)

(如对您的问题的评论中所述,pv可以替换cat并为您提供进度和吞吐量的指示。)

  • (错误的细节:内核错误地报告了磁盘使用大小[导致 cp 得出每个源文件都是稀疏文件的结论],并且 cp 在从稀疏文件复制到设备目标时没有将块清零。所以任何零源中的块将有任何垃圾已经在磁盘上) (4认同)
  • 具体来说,必须使用 dd 的原因是 90 年代初 GNU cp 中的一个错误和 linux 内核中的一个错误。在历史的 unix 系统上使用 dd 的原因非常不同,想要复制整个块设备是一件不寻常的事情。 (3认同)
  • 我喜欢这样的答案。谢谢(你的)信息。这是你的updoot。 (2认同)

Rog*_*ote 8

一般来说,dd可以避免一些替代方案。使用 GNU 有几个很好的理由ddrescue。在 Ubuntu 中,您可以使用以下命令安装它:

sudo apt-get install gddrescue
Run Code Online (Sandbox Code Playgroud)

并且简单ddrescue易用。请注意,与包名称不同,可执行文件没有初始的g.

使用它很简单:

ddrescue inputFile outputFile logFile
Run Code Online (Sandbox Code Playgroud)

日志文件(命名为您选择的任何名称)让您可以暂停/停止和重新启动,而无需重做之前的工作,这在进行大型克隆或磁盘恢复时非常有用。默认情况下,它显示进度、当前复制速度、平均复制速度和找到的坏块数。

它对块大小使用合理的默认值,因此复制速度总是与设备可以处理的一样快,至少以我的经验(我已经用它克隆了数百个驱动器,所有大小和类型)。

很多时候,开始出现故障的驱动器会出现速度问题,例如偶尔出现缓慢的补丁、平均速度低、突然长暂停(坏扇区)或完全重置(严重的表面错误)。ddrescue即使您的驱动器正在自我重置,也可以帮助您识别上述所有内容并重新启动您的克隆(前提是您指定了一个日志文件)。


elb*_*rna 6

非常好的问题。原始接口在某些 unix 系统(tru64、hpux、solaris)上实现,但不在 linux 上实现。由于跳过了 unix I/O,原始接口使传输速度更快。块接口(/dev/dsk/dev/disk)较慢,因为它使用 unix I/O 系统。要加速dd(gnu dd 可以)使用bs=30Mbs=20M取决于您的硬件。简短的回答是:不,它没有实现,至少据我所知。我从内核版本 2.2 的旧时代开始使用 linux,从未见过rdsk在 unix 上使用过。

  • 为什么您建议的块大小不是 2 的幂? (6认同)
  • @Basile 磁盘块大小的倍数就足够了,所以 20MiB 就可以了。 (2认同)