为什么dd需要太长时间?


18

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

dd if=/dev/sda of=/dev/sdb 

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

dd if=/dev/sda of=/dev/rdsk

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


2
cp /dev/sda /dev/sdb或(pv /dev/sda > /dev/sdb 获取进度条)会更快。你为什么要dd在这里使用?dd只会在conv=sync,noerror处理带有错误的磁盘之类的东西时有用,但是即使那样,使用诸如此类之类的东西还是更有意义的ddrescue(另请参见pv-E选项)。
斯特凡Chazelas

1
@StéphaneChazelas cat可能更快,但区别并不那么明显(在设备间的设备可能比在实验中的文件到文件更大)。
吉尔斯(Gillles)“所以-别再作恶了”

8
“我已经在Unix系统上尝试过相同的方法” -那么,如果不是Unix,您尝试过哪种类型的系统?另外,什么硬件等,yaddayadda。
marcelm '16


使用了HP-UX(Integrity刀片式服务器)中的第一个,而更早使用Solaris机器。
KKD

Answers:


28

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

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

dd if=/dev/sda of=/dev/sdb bs=16M

IIRC,默认缓冲区大小仅为512字节。上面的命令将其设置为16兆字节。您可以尝试使用较小的值(例如bs=1M),但应使用比默认值更多的值(尤其是在扇区为4KB的最新磁盘硬件上,即Advanced Format)。我天真地建议使用至少为1 MB的2的幂。

在默认的512字节缓冲区大小的情况下,我猜(但我可能错了),硬件要求内核为每个512字节块传输4K。

至于rdsk,在SD(4)手册页说:

此时,仅提供块设备。原始设备尚未实现。

dd缓冲区大小的增加将为您提供更多的读写操作性能。现在所有磁盘都具有硬件读/写缓冲区。但是,如果您增加dd的缓冲区大小超过硬件缓冲区,则其性能将下降,因为当第二个磁盘都已从其自己的硬件缓冲区写入所有数据时,dd将从第一个磁盘读取到另一个磁盘。bs每次对于不同的设备使用不同的值时,都需要使用dd命令的set 选项。


rdsk在Linux系统中是否可用?我曾经在Unix系统上使用过。
KKD

1
无论执行什么操作,页面缓存都可能会处理4Kb块,但是您可以控制dd用来读取4Kb的系统调用数。我敢肯定有一些读取大小,超过该大小会导致写入停顿的成本比已保存的syscalls高,但不知道最佳位置在哪里。
没用的2016年

几MB的块大小比默认的512B好,但是当我对此进行基准测试时,我发现它cat也做得很好(对于文件系统到文件系统的传输,直接块到块可能具有不同的性能特征)。但是,无论如何,差异并不大。
吉尔斯(Gillles)“所以-别再邪恶了”

1
有趣的是,在macOS(经过SUS认证的btw)中,执行时将其用作目标的速度更快/dev/rdiskXdd
adib

1
如果您想知道发生了什么(就像我一样),还status=progress可以添加将打印整个操作进度的信息。
Aleksander Lech

17

几年前在Unix领域dd是复制块设备的必需方法。即使(至少在基于Linux的系统上)cat这几乎总是比快,但作为货真价实的知识却得以延续dd

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

dd bs=$((512*2048*32)) if=/dev/source of=/dev/target

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

cat /dev/source >/dev/target

(如对您的问题的评论中所述,pv可以代替该注释,cat并且可以向您指示进度和吞吐量。)


3
具体来说,必须使用dd的原因是90年代初GNU cp中的错误和linux内核中的错误。在历史上的unix系统上使用dd的原因非常不同,并且想要复制整个块设备是一件不寻常的事情。
Random832

1
@ Random832想要复制整个磁盘是不寻常的,但是我确实记得需要复制分区(大的-150甚至200MB)
roaima

3
(这些错误的细节:内核错误地报告了磁盘使用大小[导致cp得出结论,每个源文件都是稀疏文件],并且从稀疏文件复制到设备目标时cp不会将块清零。因此,任何零您的源中的块将具有已经发生在磁盘上的任何垃圾)
Random832 '16

我喜欢这种答案。谢谢(你的)信息。这是你的上流。
catbadger

7

通常,dd可以避免使用某些替代方法。有许多很好的理由ddrescue代替使用GNU 。在Ubuntu中,您可以使用以下命令进行安装:

sudo apt-get install gddrescue

并且简单ddrescue易用。请注意,与程序包名称不同,可执行文件没有 initial g

使用它很简单:

ddrescue inputFile outputFile logFile

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

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

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


6

非常好的问题。raw接口在某些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上使用过。


6
为什么您建议的块大小不是2的幂?
Basile Starynkevitch

2
@Basile磁盘块大小的倍数就足够了,所以20MiB就可以了。
roaima
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.