只针对相同大小的文件进行Rsync校验和

30

有许多关于rsync校验和的线程,但似乎没有解决我的需求,这将是最有效和最快速的同步方式,至少在我的情况下:

  • 相同时和大小相同时 ► 跳过文件(不传输,不校验和)
  • 大小不同时 ► 传输文件(不校验和)
  • 时间不同且大小相同时 ► 执行校验和 ► 仅在校验和不同时传输

我注意到选项--checksum可以真正花费很长时间来镜像一个文件夹,如果有很多文件的话。仅使用此选项将对每个文件运行校验和,这非常安全但非常慢。此外,它会引入读取访问开销以计算校验和。
选项--ignore-times不是我想要的,如果时间和大小都匹配,则文件不同的几率微不足道,我愿意冒险不传输。
选项--size-only不完整,因为具有相同大小但时间不同的文件可能实际上是不同的文件(例如,在另一个文件中更改一个字符可能不会影响大小,只会影响编辑时间)。

是否有一种方法可以按照上述组合使用rsync进行镜像,或使用任何其他Linux工具?
谢谢。


1
很棒的问题!一个非常实际的用例是在使用Git时。当在具有更改文件的分支之间切换时,它会不断更改您不打算从特定分支发送的文件的更新时间。通常会出现在您确定不想传输的相同文件上有不同的时间的情况。因此,只有在不同的时间和相同的大小时,我才希望它执行校验和以确保进行传输的文件是不同的。 - OCDev
2个回答

25

在决定是否传输文件(或使用--dry-run时列出文件)时,rsync将始终传输大小不同的文件。然而,当文件大小相同时,rsync有几个选项:

  • 使用--size-only: 从不传输文件。
  • 使用--ignore-times: 始终传输文件。
  • 默认: 如果时间戳不同,则传输文件。
  • 使用--checksum: 计算校验和并在校验和不同时传输文件。

您想要的行为将是最后两个选项的结合:“如果时间戳不同,则计算校验和并在校验和也不同时传输文件”。目前rsync中没有这个选项。

不幸的是,查看rsync源代码,似乎添加此功能是非常困难的。目前,如果使用校验和,远程rsync会收集大小、时间戳和校验和信息,并一起发送。所需的行为将要求远程rsync首先发送大小和时间戳,当本地rsync确定需要校验和时,返回到文件以获取校验和。但是整个“远程rsync返回到文件”的方面在当前代码中不存在,因此需要先编写它。

当您运行实际传输时,第二步可以在传输过程中有效地完成:不不同的文件传输非常高效。因此,rsync的默认行为就足够了。当使用--dry-run时,最好的方法可能是首先使用默认行为运行rsync,收集--dry-run输出,然后再次运行rsync,在第一次运行中找到的文件上使用--checksum


先使用默认行为运行 rsync,收集 --dry-run 输出,然后再次运行 rsync,并在第一次运行中找到的文件上加上 --checksum。这样是否也会对大小不同(显然应该传输)的文件进行校验和?期望的行为是仅对具有相同大小但时间戳不同的文件使用校验和。 - johnraff

5
简短的回答是,它确实有用。
same time and same size ► skip file (no transfer, no checksum)

rsync默认提供了良好和快速的功能,但不精确。即使文件被修改,时间/大小仍然相同(时间可以被重置)。如果过于谨慎,可以使用-c选项。

different sizes ► transfer file (no checksum)

简单来说,如果有一个2GB的文件,只有最后一行内容不同,那么校验和可以识别出这个差异,并节省网络流量。如果您信任时间/大小比较,可以使用-c选项。

different times and same size ► perform checksum ► transfer only if checksums differ

当然。


我没有看到过,但我记得rsync曾经有一个问题,如果有超过……我想大约是13万个文件。也许这个问题已经解决了。
如果您在一个目录中有那么多的文件,您可能会遇到更大的问题……将它们分散到不同的目录中,并对这些多个目录进行多次rsync同步操作。
大量小文件(在大多数文件系统上)存在许多内部碎片化问题,您可能最好将文件归档并同步归档……您需要一个允许更新归档而不是一直重新创建它的存档程序。

如果没有很多这些文件被更新……找到日期之后更改的文件(find --newer file),然后仅同步这些文件。(如果您信任时间)

为什么这个问题被忽视了这么长时间?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接