题 使用DD进行磁盘克隆


有关磁盘克隆工具的问题有很多 dd 有人建议至少一次。我已经考虑过使用了 dd 我自己,主要是因为易于使用,并且几乎所有可启动的Linux发行版都可以使用它。

什么是最好的使用方式 dd 用于克隆磁盘?我做了一个快速的谷歌搜索,第一个结果很明显 尝试失败。使用后我还需要做些什么 dd,即是否有任何无法阅读使用 dd


176
2018-05-05 18:21




我知道dd是如何工作的,我的问题更多的是在克隆磁盘时与dd相关的任何已知问题的方向(如链接所述),也许这不是很清楚。他的答案包含的内容和你的答案不是“我从来没有遇到任何问题”。我也提出了你的答案,因为你确实提出了一些有趣的观点(我喜欢没有进展指示的那一点)。 - falstro
看起来你得到了Spolsky Bump: joelonsoftware.com/items/2009/05/29.html - Kyle Cronin
当我向超级用户询问(并回答)类似的问题时,我没有在这里看到这一点 - superuser.com/questions/11453/... - warren
具有讽刺意味的是,Joel将这个问题作为服务器故障的一个很好的例子,虽然没有一个答案是好的。有权利的25个(不包括评论)中没有一个答案 dd 跳过坏块的选项 - 在克隆磁盘进行恢复时这是必不可少的。我添加了一个更好的答案,可以克隆具有坏块的磁盘: dd if=/dev/sda of=/dev/sdb bs=4096 conv=sync,noerror - Sam Watkins
我认为如果谈论驱动器几何相关的文件系统并在非相同的硬盘驱动器上进行恢复,dd恢复可能会“失败”吗?我在dd恢复方面经历了一些失败,我认为这是我的问题。 - Marco


答案:


dd肯定是最好的克隆工具,它只需使用以下命令即可创建100%的副本。我从来没有遇到任何问题。

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

请注意,在克隆每个字节时,不应在正在使用的驱动器或分区上使用它。特别是像数据库这样的应用程序无法很好地应对这种情况,您最终可能会遇到损坏的数据。


152
2018-05-05 18:31



当然,只要/ dev / sdb至少和/ dev / sda一样大...... - Eddie
添加一个“bs = 100M conv = notrunc”,这在我的体验中要快得多。 - Tim Williscroft
只要小心'i'和'o'字母...... - bandi
似乎没有人知道这个技巧...... dd是一个不对称的复制程序,意味着它会首先读取,然后写入,然后返回。您可以将dd管道传递给自己并强制它以对称方式执行复制,如下所示: dd if=/dev/sda | dd of=/dev/sdb。在我的测试中,运行没有管道的命令给了我~112kb / s的吞吐量。使用管道,我得到~235kb / s。我从来没有遇到过这种方法的任何问题。祝好运! - Mistiry
@Mistiry,这不是对称这个词的意思。 - psusi


为了节省空间,您可以使用gzip压缩dd生成的数据,例如:

dd if=/dev/hdb | gzip -c  > /image.img

您可以使用以下命令恢复磁盘:

gunzip -c /image.img.gz | dd of=/dev/hdb

为了节省更多空间,请事先对要克隆的驱动器/分区进行碎片整理(如果适用),然后将所有剩余的未使用空间清零,以便gzip更容易压缩:

mkdir /mnt/hdb
mount /dev/hdb /mnt/hdb
dd if=/dev/zero of=/mnt/hdb/zero

等一下,dd最终会因“磁盘已满”消息而失败,然后:

rm /mnt/hdb/zero
umount /mnt/hdb
dd if=/dev/hdb | gzip -c  > /image.img

此外,您可以在后台运行一个dd进程,通过使用kill命令向其发送信号来报告状态,例如:

dd if=/dev/hdb of=/image.img &
kill -SIGUSR1 1234

检查你的系统 - 上面的命令适用于Linux,OSX和BSD dd命令在它们接受的信号上有所不同(OSX使用 SIGINFO  - 你可以按 Ctrl键+Ť 报告状态)。


104
2018-05-06 22:47



这也适用于“现代”fs,如BTRFS,NILFS,[无论你能想到什么]? - Steve Schnepp
DD适用于块设备,抽象级别低于文件系统,所以它应该是,是的。不过,我还没有尝试过。嗯,NILFS看起来很有趣,我将不得不看一看。 - David Hicks
+1为 kill -SIGUSR1 %1,OSX dd命令愉快地接受SIGUSR1 ...超级有用,谢谢! - stuartc
+1为 Kill -SIGUSR1 1234 我在找那个。 - hot2use
应该是: dd if=/dev/hdb | gzip -c > /image.img.gz ? - Mike Causer


警告:dd'ing一个实时文件系统可以破坏文件。原因很简单,它不了解可能正在进行的文件系统活动,并且没有尝试减轻它。如果写入部分正在进行,您将获得部分写入。这通常对事物不利,对数据库而言通常是致命的。而且,如果你搞砸了错字 如果 和  参数,对你有祸了。在多数情况下, rsync的 是一个同样有效的工具,在它出现后写成 多任务处理,并将提供单个文件的一致视图。

但是,DD应准确捕获未安装驱动器的位状态。 Bootloader,llvm卷,分区UUID和标签等。只需确保您有一个能够镜像目标驱动器位的驱动器。


37
2018-05-05 20:20



我怀疑 sync 不是文件损坏问题的答案。如果一个deamon或其他东西写入更多文件后会发生什么 sync, 在此期间 dd 操作? - Deleted
首先卸载驱动器(或以只读方式重新安装)是个好主意,但并不总是可行 - Alex Bolotov
在这种情况下,您使用rsync并让它执行文件句柄魔术以获得一致的文件,并让Copy On Write语义处理传入的写入。 - jldugger
我想补充一点,在挂载的文件系统上运行dd不会破坏已挂载文件系统上的文件,但这里的含义是文件系统的副本必须处于已知的良好状态。 - 3molo
运用 rsync 将确保 内部数据 在目标文件系统中是一致的。它 将不会 确保文件中的数据是一致的 - 为此,您需要锁定文件,并且写入文件的任何程序都需要遵守这些锁。 - Martin Geisler


使用dd克隆可能包含坏扇区的磁盘时,请使用“conv = noerror,sync”以确保它在遇到错误时不会停止,并使用空字节填充缺少的扇区。这通常是我尝试从失败或失败的磁盘恢复时采取的第一步 - 在执行任何恢复尝试之前获取副本,然后在良好(克隆)的磁盘上执行恢复。我将它留给恢复工具来处理任何无法复制的空白扇区。

此外,您可能会发现dd的速度可能受bs(块大小)设置的影响。我通常尝试使用bs = 32768,但您可能希望在自己的系统上测试它,看看哪种方法对您来说最快。 (这假设您不需要因特殊原因而使用特定的块大小,例如,如果您正在写入磁带。)


26
2018-05-07 02:42



如果你有一个坏扇区的磁盘,你真的应该使用'ddrescue'而不是dd。它效率更高,并且有更好的机会恢复更多数据。 (不要把它与dd_rescue混淆,这不是很好) - davr
如果试图跳过坏块,则不应使用大块大小,否则会跳过太多。 4096足够大了。 - Sam Watkins


要克隆磁盘,您真正需要做的就是将输入和输出指定为dd:

dd if=/dev/hdb of=/image.img

当然,请确保您具有直接从/ dev / hdb读取的适当权限(我建议以root身份运行),以及/ dev / hdb 没有安装 (您不希望在更改磁盘时进行复制 - 也可以以只读方式挂载)。完成后,image.img将是整个磁盘的逐字节克隆。

使用dd克隆磁盘有一些缺点。首先,dd将复制整个磁盘,甚至是空白空间,如果在大磁盘上完成,则会导致图像文件非常大。其次,dd绝对没有进展指示,这可能令人沮丧,因为副本需要很长时间。第三,如果将此映像复制到其他驱动器(同样,使用dd),它们必须与原始磁盘一样大或大,但是在您之前,您将无法使用目标磁盘上的任何额外空间。调整分区大小。

您还可以执行直接的磁盘到磁盘复制:

dd if=/dev/hdb of=/dev/hdc

但是你仍然受到有关自由空间的上述限制。

至于问题或陷阱,dd,在大多数情况下,做得很好。然而,不久之前我有一个即将死亡的硬盘驱动器,所以我使用dd尝试在完全死亡之前复制我可以提供的信息。据了解,dd不能很好地处理读错误 - 磁盘上有几个扇区dd无法读取,导致dd放弃并停止复制。当时我找不到告诉dd继续尽管遇到读错误的方法(尽管如此 它出现 好像它确实有那个设置),所以我花了很多时间手动指定跳过并寻求跳过不可读的部分。

我花了一些时间研究这个问题的解决方案(在我完成任务之后),我发现了一个名为的程序 ddrescue根据网站的说法,它像dd一样运行,但即使遇到错误也会继续阅读。我从来没有真正使用过该程序,但值得考虑,特别是如果你要复制的磁盘是旧的,即使系统看起来很好也可能有坏扇区。


17
2018-05-05 18:26



...... dd完全没有进展指示......  - 这不是真的 - 如何显示进度有一种棘手的方法 - 你必须找出dd进程的pid('ps -a | grep dd')然后将信号USR1发送到这个进程 - 'kill -USR1 < dd_pid_here>'(不带<>)强制dd显示进度信息。 - Michal Bernhard
“dd无法读取的磁盘上的几个扇区”:我认为 conv=sync,noerror 有助于。 - Gauthier
该 conv=sync,noerror 选项是必不可少的,它们允许dd跳过坏块并在图像中将它们归零,以便正确对齐。支持极少数评论此事的人的道具。 - Sam Watkins
GNU ddrescue 提供没有任何特殊选项的进度指示器,您可以停止复制并从中断处继续。 - endolith
使用dd获得进步的一个不太棘手的方法是添加选项 status=progress - James


如果源驱动器完全损坏,您将有更多的运气使用 dd_rhelp 同 dd_rescue (我个人的偏好)或GNU ddrescue

这背后的原因是,在读取错误时, dd 不断尝试,尝试和尝试 - 可能等待很长时间才能发生超时。 dd_rescue 做一些聪明的事情,例如读取错误,然后在磁盘上进一步选择一个点并向后读回到最后一个错误,并且 dd_rhelp 基本上是一个 dd_rescue会话管理器 - 巧妙地启动和恢复 dd_rescue 跑来让它更快。

最终的结果 dd_rhelp 是在最短时间内恢复的最大数据。如果你走 dd_rhelp 运行,最终它完成相同的工作 dd 在同一时间。但是,如果 dd 在您的100Gb磁盘的字节100遇到读取错误,您必须等待很长时间才能恢复其他9,999,900字节*,而 dd_rhelp+dd_rescue 将更快地恢复大部分数据。


11
2018-05-31 02:12



一些帮助在dd_rescue和ddrescue之间进行选择: askubuntu.com/a/211579/50450 - Johann


源磁盘必须没有任何已安装的文件系统。 作为能够读取块设备(root works)的用户,运行'dd if = / dev / sda ....'

现在,这里的一个巧妙的事情是你正在创建一个字节流......你可以做很多事情:压缩它,通过网络发送它,将它分成更小的blob等等。

例如:

dd if=/dev/sda | ssh user@backupserver "cat > backup.img"

但更有力:

dd if=/dev/sda | pv -c | gzip | ssh user@backupserver "split -b 2048m -d - backup-`hostname -s`.img.gz"

上面将源硬盘的压缩映像复制到远程系统,在远程系统中使用源主机的名称将其存储在编号为2G的块中,同时保持更新进度。

请注意,取决于磁盘的大小,源上的CPU速度,目标上的CPU速度,网络速度等。您可能希望跳过压缩,或在远程端进行压缩,或启用ssh的压缩。


7
2018-05-29 19:23



+1通过gzip管道可以节省大量的时间和带宽! - M. Dudley
我还应该注意,在dd命令中添加'bs = 1M'通常会大大提高速度。 - retracile


要克隆磁盘,您真正需要做的就是指定输入和输出 dd

dd if=/dev/hdb of=hdb.img

当然,请确保您具有直接读取的适当权限 /dev/hdb (我建议以root身份运行),那样 /dev/hdb 未安装(您不想在更改磁盘时进行复制)。一旦完成, hdb.img 将是整个磁盘的逐字节克隆。

使用有一些缺点 dd 克隆磁盘。第一, dd 将复制整个磁盘,甚至是空的空间,如果在大磁盘上完成,则会导致图像文件非常大。第二, dd 提供绝对没有进展指示,这可能令人沮丧,因为副本需要很长时间。第三,如果将此映像复制到其他驱动器(同样,使用dd),它们必须与原始磁盘一样大或大,但是在您之前,您将无法使用目标磁盘上的任何额外空间。调整分区大小。

您还可以执行直接的磁盘到磁盘复制:

dd if=/dev/hdb of=/dev/hdc

但是你仍然受到有关自由空间的上述限制。

第一个缺点可以通过在制作副本时压缩数据来解决。例如:

dd if=/dev/hdb | gzip -9 > hdb.img.gz

使用pipeview可以解决第二个缺点(pv)工具。例如:

dd if=/dev/hdb | (pv -s `fdisk -l /dev/hdb | grep -o '[0-9]*\{1\} MB' | awk '{print $1}'`m) | cat > hdb.img

我知道无法克服第三个缺点。

此外,您可以通过告诉加快复制时间 dd 使用更大的数据块。例如:

dd if=/dev/hdb of=hdb.img bs=1024

6
2018-05-29 22:03



你已经告诉了克服第三个缺点的方法......调整分区的大小。扩大分区通常是安全和快速的操作(相对于收缩或移动,这是缓慢且更危险的,因为它正在移动数据)。 - davr
gzipping将无法使用已经使用了一段时间的磁盘,因为它将填充当前或已删除的数据。 gzip仅在空白空间为零时才起作用,这只是全新磁盘的情况。 - Tozz
@Tozz:您可以通过使用填充为0的文件填充文件系统,将其同步到磁盘,然后将其删除来提高文件系统映像的可压缩性。 dd if=/dev/zero bs=1M of=/balloon; sync; rm /balloon  (在文件系统层中模数额外的智能。) - retracile


使用dd和rescue磁盘可以做的另一件好事是通过网络复制数据:

remote_machine$ nc -l -p 12345

local_machine$ dd if=/dev/sda | nc remote_machine 12345

如果网络不是本地网络,您可以在这两个管道中粘贴gzip。为了进步,请使用 pv。要在完成复制后使local_machine的netcat退出,您可以添加 -w 5 或者其他的东西。


5
2018-05-29 18:09



这不太正确。 'remote_machine'命令缺少某些内容,例如 > disk_backup.img 要么 |dd of=/dev/sdb 或其他什么,取决于你想做什么。我猜你不想把磁盘映像转储到stdout。 - davr
并在两端放入gzip以进一步减少发送的数据。 - 3molo


请记住,dd是一个 确切的副本,包括所有空白区域。

这意味着:

  1. 第二个驱动器必须至少与第一个驱动器一样大
  2. 如果第二个驱动器更大,将浪费额外的空间(文件系统 能够 要扩大思想你)
  3. 如果源驱动器未满,dd将浪费大量时间复制空白区域。
  4. 您可以通过这种方式复制整个驱动器或单个分区。
  5. 如果这是一个可引导的驱动器,我很确定你需要在使用dd后安装引导加载程序

希望有所帮助


4
2018-05-05 18:38



如果您要克隆整个硬盘,那么您还要克隆引导加载程序。 - Cristian Ciupitu
欢迎,只是一个thouhgt,但你不能只使用gparted重新分区/磁盘被复制到任何使用的 - 然后删除dd?假设它是一次性图像,它应该缓解这个问题。 - bbqchickenrobot