rsync 被中断后还能恢复吗?

Tim*_*Tim 255 rsync

我曾经rsync复制大量文件,但我的操作系统(Ubuntu)意外重启。

重启后,我rsync再次运行,但是从终端上的输出中,我发现rsync仍然复制了之前已经复制的那些。但是我听说rsync可以找到源和目标之间的差异,因此只需复制差异即可。所以我想知道在我的情况下是否rsync可以恢复上次剩下的东西?

Dan*_*uus 367

首先,关于你的问题的“恢复”部分,--partial如果发送端消失了,就好像它们被完全传输一样,只是告诉接收端保留部分传输的文件。

在传输文件时,它们会临时保存为目标文件夹(例如.TheFileYouAreSending.lRWzDC)中的隐藏文件,或者如果您设置了--partial-dir开关,则是专门选择的文件夹。当传输失败--partial且未设置时,此隐藏文件将保留在此隐含名称下的目标文件夹中,但如果--partial设置,该文件将重命名为实际目标文件名(在本例中为TheFileYouAreSending),即使文件不完整。关键是您可以稍后通过使用--append或再次运行 rsync 来完成传输--append-verify

因此,--partial本身不会恢复失败或取消的传输。要恢复它,您必须在下次运行时使用上述标志之一。因此,如果您需要确保目标永远不会包含看起来很好但实际上不完整的文件,则不应使用--partial. 相反,如果您想确保永远不会留下隐藏在目标目录中的杂散失败文件,并且您知道以后可以完成传输,--partial那么有什么可以帮助您的。

关于--append上面提到的开关,这是实际的“恢复”开关,无论您是否也使用--partial. 实际上,当您使用 时--append,不会创建任何临时文件。文件直接写入其目标。在这方面,--append给出与--partial失败传输相同的结果,但不创建那些隐藏的临时文件。

因此,总而言之,如果您正在移动大文件,并且希望选择从rsync停止的确切点恢复已取消或失败的 rsync 操作,则需要在下次尝试时使用--append--append-verify开关。

正如@Alex 在下面指出的那样,由于 3.0.0 版rsync现在有一个新选项--append-verify,它的行为与--append该开关存在之前的行为类似。您可能总是想要 的行为--append-verify,因此请使用rsync --version. 如果您使用的是 Mac 并且不使用rsyncfrom homebrew,您(至少直到并包括 El Capitan)将拥有旧版本并且需要使用--append而不是--append-verify. 为什么他们不保持这种行为--append而是命名新人--append-no-verify有点令人费解。无论哪种方式,--appendrsync前3版相同--append-verify的新版本。

--append-verify并不危险:它总是会读取和比较两端的数据,而不仅仅是假设它们相等。它使用校验和来完成此操作,因此在网络上很容易,但它确实需要读取线路两端的共享数据量,然后才能通过附加到目标来实际恢复传输。

其次,您说您“听说 rsync 能够找到源和目标之间的差异,因此只需复制差异。”

这是正确的,它被称为增量传输,但它是另一回事。要启用此功能,请添加-c, 或--checksum开关。使用此开关后,rsync 将检查线路两端存在的文件。它以块的形式执行此操作,比较两端的校验和,如果它们不同,则只传输文件的不同部分。但是,正如@Jonathan 在下面指出的那样,只有在两端的文件大小相同时才会进行比较——不同的大小会导致 rsync 上传整个文件,覆盖具有相同名称的目标。

这最初需要在两端进行一些计算,但如果您经常备份非常大的文件,固定大小的文件通常包含微小更改,则可以非常有效地减少网络负载。想到的例子是虚拟机或 iSCSI 目标中使用的虚拟硬盘驱动器映像文件。

值得注意的是,如果您使用--checksum将一批全新的文件传输到目标系统,rsync 仍会在传输它们之前在源系统上计算它们的校验和。为什么我不知道:)

所以,简而言之:

如果你经常使用rsync只是“移动的东西从A到B”,并希望该选项取消该操作并在以后继续,使用--checksum,但--append-verify

如果您经常使用 rsync 来备份内容,那么使用--append-verify可能对您没有多大帮助,除非您习惯于发送大小不断增长但一旦写入就很少修改的大文件。作为额外提示,如果您要备份到支持快照的存储,例如btrfszfs,添加--inplace开关将帮助您减少快照大小,因为不会重新创建更改的文件,而是将更改的块直接写入旧的块。如果您想避免 rsync 在仅发生较小更改时在目标上创建文件副本,则此开关也很有用。

使用 时--append-verify, rsync 的行为就像它在所有相同大小的文件上总是一样。如果它们的修改或其他时间戳不同,它将用源覆盖目标,而无需进一步检查这些文件。--checksum将比较每个具有相同名称和大小的文件对的内容(校验和)。

更新 2015-09-01更改以反映@Alex 提出的观点(谢谢!)

更新 2017-07-14已更改以反映@Jonathan 提出的观点(谢谢!)

  • [这](http://stackoverflow.com/a/32094804/819417) 说`--partial` 就足够了。 (9认同)
  • @DanielSmedegaardBuus 我自己在慢速连接上进行了测试,这就是我在 _only_ `--partial` 中看到的:rsync 将文件复制到临时名称中,连接中断,远程 rsync 最终将该文件移动到常规名称并退出,然后在使用 `--partial` 和 _without_ `--append` 重新运行时,使用部分传输的远程文件的副本初始化新的临时文件,然后副本从连接中断的地方继续。(Ubuntu 14.04 / rsync 3.1) (5认同)
  • 您对“--checksum”的描述行为的信心程度如何?根据 [`man`](https://linux.die.net/man/1/rsync),它与决定要标记哪些文件进行传输的关系比使用 delta-transfer(大概是` rsync` 的默认行为)。 (4认同)
  • @CMCDragonkai 实际上,请查看下面亚历山大关于`--partial-dir` 的回答 - 看起来它是完美的子弹。我可能完全错过了一些东西;) (3认同)
  • *打开选项卡 526* [使用 --partial 选项告诉 rsync 保留部分文件,这将使文件的其余部分的后续传输速度更快。](https://download.samba.org/pub/rsync/ rsync.html) [更简单的文档](http://explainshell.com/explain?cmd=rsync+--partial) (2认同)
  • 似乎较新版本的 rsync:*版本 3.1.1 协议版本 31* 默认删除部分传输的临时文件(例如 `.TheFileYouAreSending.lRWzDC`)。IIRC 旧版本的行为按照此答案,默认情况下,失败的传输会留下“.TheFileYouAreSending.lRWzDC”类型文件。如今,rsync 似乎会自行清理。这是有道理的,如果这些临时文件不能用于恢复操作,那么它们实际上就很混乱。请参阅“man rsync | less '+/默认情况下,rsync会删除'` (2认同)
  • 我希望“所以,简而言之”部分位于答案的顶部,这样我就不必每次查找这篇文章时都通读一遍(我一直忘记要使用的开关)。你会在顶部添加一个“TL;DR”吗? (2认同)
  • 根据 man: `-W, --whole-file 使用此选项,不使用 rsync 的增量传输算法 (...) 当源和目标都指定为本地路径时,这是默认值。(...) --stats 这告诉 rsync 打印一组有关文件传输的详细统计信息,让您了解 rsync 的增量传输算法对数据的有效性。` 这往往意味着增量传输是默认的。事实上,“-checksum”是关于确定文件是否已更改(通过在两端进行校验和,从而在文件大小和日期相同时从磁盘读取所有文件)。 (2认同)
  • 添加 TL;DR 并附上简短的答案。 (2认同)
  • 哦,你好老朋友,新年同样重温这个问题和答案。它像酒一样陈年 (2认同)

小智 81

特尔;博士:

只需按照 rsync 手册页的建议指定部分目录:

--partial-dir=.rsync-partial
Run Code Online (Sandbox Code Playgroud)

更长的解释:

实际上有一个使用该--partial-dir选项执行此操作的内置功能,它比--partial--append-verify/--append替代方案有几个优点。

摘自 rsync 手册页:

--partial-dir=DIR
      A  better way to keep partial files than the --partial option is
      to specify a DIR that will be used  to  hold  the  partial  data
      (instead  of  writing  it  out to the destination file).  On the
      next transfer, rsync will use a file found in this dir  as  data
      to  speed  up  the resumption of the transfer and then delete it
      after it has served its purpose.

      Note that if --whole-file is specified (or  implied),  any  par-
      tial-dir  file  that  is  found for a file that is being updated
      will simply be removed (since rsync  is  sending  files  without
      using rsync's delta-transfer algorithm).

      Rsync will create the DIR if it is missing (just the last dir --
      not the whole path).  This makes it easy to use a relative  path
      (such  as  "--partial-dir=.rsync-partial")  to have rsync create
      the partial-directory in the destination file's  directory  when
      needed,  and  then  remove  it  again  when  the partial file is
      deleted.

      If the partial-dir value is not an absolute path, rsync will add
      an  exclude rule at the end of all your existing excludes.  This
      will prevent the sending of any partial-dir files that may exist
      on the sending side, and will also prevent the untimely deletion
      of partial-dir items on the receiving  side.   An  example:  the
      above  --partial-dir  option would add the equivalent of "-f '-p
      .rsync-partial/'" at the end of any other filter rules.
Run Code Online (Sandbox Code Playgroud)

默认情况下,rsync 使用随机临时文件名,当传输失败时该文件名会被删除。如前所述,使用--partial您可以使 rsync 保留不完整的文件,就好像它已成功传输一样,以便以后可以使用--append-verify/--append选项附加到它。然而,这是次优的有几个原因。

  1. 您的备份文件可能不完整,如果不检查必须仍保持不变的远程文件,就无法知道。

  2. 如果您尝试使用--backupand --backup-dir,则您刚刚在您的版本历史记录中添加了此文件的新版本,该版本之前甚至从未退出过。

但是,如果我们使用--partial-dir,rsync 将保留临时部分文件,并在下次运行时使用该部分文件继续下载,并且我们不会遇到上述问题。

  • 关于 `--partial-dir` 和 I/O 量和/或磁盘写入操作(CF、SSD 等)的问题很少: **1.** 当路径_不在_同一分区(另一个磁盘、RAM)中时驱动器等)当文件被同步时,完成后将在指定目录和目标之间进行文件复制;**2.** 当涉及大文件时,建议使用相对路径(位于_same_分区 - 而不是符号链接等);**3.** 使用临时存储(例如 RAM 驱动器)时,还应该注意要同步的文件将受到临时存储可用空间的限制。 (3认同)

小智 46

您可能希望将该-P选项添加到您的命令中。

man页面:

--partial By default, rsync will delete any partially transferred file if the transfer
         is interrupted. In some circumstances it is more desirable to keep partially
         transferred files. Using the --partial option tells rsync to keep the partial
         file which should make a subsequent transfer of the rest of the file much faster.

  -P     The -P option is equivalent to --partial --progress.   Its  pur-
         pose  is to make it much easier to specify these two options for
         a long transfer that may be interrupted.
Run Code Online (Sandbox Code Playgroud)

所以而不是:

sudo rsync -azvv /home/path/folder1/ /home/path/folder2
Run Code Online (Sandbox Code Playgroud)

做:

sudo rsync -azvvP /home/path/folder1/ /home/path/folder2
Run Code Online (Sandbox Code Playgroud)

当然,如果你不想要进度更新,你可以使用--partial,即:

sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2
Run Code Online (Sandbox Code Playgroud)

  • @Flimm 和 @gaoithe,我的回答不太准确,而且绝对不是最新的。我已经更新它以反映 `rsync` 的版本 3 +。但是,重要的是要强调,`--partial` **不** 本身恢复失败的传输。有关详细信息,请参阅我的答案:) (2认同)
  • @DanielSmedegaardBuus 我试过了,在我的情况下,`-P` 就足够了。版本:客户端有 3.1.0,服务器有 3.1.1。我用 ctrl-c 中断了单个大文件的传输。我想我错过了一些东西。 (2认同)

小智 5

迟到了,但我有同样的问题,我找到了不同的答案。

中的--partial标志(“保留部分传输的文件” rsync -h)对大文件很有用--append(“将数据附加到较短的文件上”),但问题是关于大量文件。

为避免使用已复制的文件-u(或--update:“跳过接收器上较新的文件”)。

  • 自我注意:不要将 `--ignore-existing` 与 `--append` 结合使用。Rsync 会保留您中断的文件,因为它认为您对此感到满意,即使它不完整。这让我有点头疼才意识到。这就是拥有大量日常使用的预配置选项的缺点。 (3认同)

wea*_*ing 5

几个重要规则:

  1. rsync使用 delta-xfer 算法来确定是否重新发送不同的块,除非有-W, --whole-file选项。
  2. rsync将数据写入临时目录并在完成后移动到目标,除非有--inplace选项。
  3. 当启用 delta-xfer 时,如果您想跳过部分发送数据块的校验和计算,您可以添加--append选项,但需要自行保证部分发送数据的相同性。
  4. --append意味着--inplace,这本身意味着--partial

就我而言,我想在没有太多 CPU 和磁盘负载的情况下发送增量文件,命令是

rsync -avPL --inplace --append --bwlimit 30m -e 'ssh -o StrictHostKeyChecking=no' <src> <dst>
Run Code Online (Sandbox Code Playgroud)

  • 仅当在两个系统之间传输时才是您的#1。如果您在同一文件系统的两个部分之间传输,则整个增量事物将被禁用 (2认同)

小智 0

我认为您正在强制调用rsync,因此当您再次回忆时,所有数据都会被下载。使用--progress选项仅复制那些未复制的文件,并--delete使用选项删除任何文件(如果已复制且现在源文件夹中不存在该文件)...

rsync -avz --progress --delete -e  /home/path/folder1/ /home/path/folder2
Run Code Online (Sandbox Code Playgroud)

如果您使用 ssh 登录其他系统并复制文件,

rsync -avz --progress --delete -e "ssh -o UserKnownHostsFile=/dev/null -o \
StrictHostKeyChecking=no" /home/path/folder1/ /home/path/folder2
Run Code Online (Sandbox Code Playgroud)

如果我对这个概念的理解有任何错误,请告诉我......

  • “使用 --progress 选项仅复制那些未复制的文件” 什么? (5认同)
  • @Fabien他告诉rsync设置两个ssh选项(rsync使用ssh进行连接)。第二个告诉 ssh 如果他连接的主机尚不已知(通过存在于“已知主机”文件中),则不要提示确认。第一个告诉 ssh 不要使用默认的已知主机文件(〜/.ssh/known_hosts)。他使用 /dev/null 来代替,当然它总是空的,并且由于 ssh 在那里找不到主机,所以通常会提示确认,因此是选项二。连接后,ssh 将现在已知的主机写入 /dev/null,实际上立即忘记了它:) (3认同)
  • ...但是您可能想知道它对 rsync 操作本身有什么影响(如果有的话)。答案是否定的。它仅用于不将您要连接的主机添加到您的 SSH 已知主机文件中。也许他是一名系统管理员,经常连接到大量新服务器、临时系统或诸如此类的东西。我不知道 :) (2认同)
  • 这里有几个错误;其中一个非常严重:“--delete”将删除目标中不存在于源中的文件。不太严重的一点是 `--progress` 不会修改复制内容的方式;它只是为您提供每个文件复制时的进度报告。(我修复了严重错误;将其替换为“--remove-source-files”。) (2认同)