rsync 是否验证在两个本地驱动器之间复制的文件?

Fre*_*rez 86 rsync verification

我想从一个本地驱动器到另一个本地驱动器制作大量文件的全新副本。

我读过 rsync 在通过网络将文件发送到远程机器时对文件进行校验和比较。

  1. 在两个本地驱动器之间复制文件时,rsync 会进行比较吗?

  2. 如果它确实进行了验证 - 这是一个安全的赌注吗?还是逐字节比较更好?

Kyl*_*nes 100

rsync 总是使用校验和来验证文件是否正确传输。如果目标文件已经存在,如果修改时间和大小与源文件匹配,rsync 可能会跳过更新文件,但如果 rsync 决定需要传输数据,则始终对发送和接收 rsync 进程之间传输的数据使用校验和. 这验证了接收到的数据与以高概率发送的数据相同,而没有通过网络进行字节级比较的大量开销。

接收到文件数据后,rsync 将数据写入文件并相信如果内核指示成功写入,则数据已写入磁盘而不会损坏。rsync 不会重新读取数据并与已知校验和进行比较作为附加检查。

至于验证本身,对于协议 30 及更高版本(在 3.0.0 中首次支持),rsync 使用MD5。对于较旧的协议,使用的校验和是MD4

虽然长期以来被认为对于安全加密哈希已经过时,但 MD5 和 MD4 仍然足以检查文件损坏。

来源:手册页并查看 rsync 源代码进行验证。

  • @clint 不,答案是正确的。从手册页对 `-c` 标志的解释:“请注意,rsync 始终通过检查文件传输时生成的整个文件校验和来验证每个传输的文件是否在接收端正确重建,但在-传输验证与此选项的传输前“此文件是否需要更新?”检查无关。 (33认同)
  • 这个答案并没有说明它是否在复制后实际验证了文件。如果在接收文件时计算校验和,则它不是复制后校验和,您无法确定文件是否正确写入。然后,您需要执行额外的比较。 (13认同)
  • 投反对票,因为我不喜欢这样一个事实,即这个答案写得很详细,技术上是正确的,同时又离题太多以至于误导了读者。问题是答案非常详细地描述了_传输_期间发生的事情,而提问者特别指出他关心_本地副本_和_不_网络传输。我很确定凯尔·琼斯不想误导任何人,但这个答案(恕我直言)确实如此。 (10认同)
  • 我不想打破每个人的泡沫,但是如果添加了 -c 标志,rsync 只会进行校验和验证! (7认同)
  • 凯尔我不相信你的回答是错误的。我已经注意到它_“写得很好,技术上正确”_,但它需要读者不必要地集中注意力和小心。为什么在117个单词重复描述另一个无关的验证过程之后,在回答中途被质疑的磁盘数据缺乏验证?无论如何,感谢您在此讨论中花费的时间和兴趣。我真诚地感谢它。 (5认同)
  • @AndreMiller 感谢您的评论。我已经更新了解决这个问题的答案。 (3认同)
  • 差不多四年后,但我有点同意@ndemou。我认为最好用一句话来开头,指出“校验和始终用于传输,而不是用于磁盘写入”。我读了整个答案,直到评论才意识到我读错了第二段。 (3认同)
  • @ndemou“始终使用校验和”表示本地副本和远程副本。rsync 在本地复制时的行为没有太大不同;它仍然使用两个进程并使用相同的协议在它们之间进行通信和传输文件。这些进程恰好在同一台机器上运行。 (2认同)
  • 嗨,凯尔,我相信这个问题会问:“1)在本地复制时,rsync 是否添加检查以验证副本与原始副本是否相同,2)这些检查的可信度如何?”。您注意到 rsync 产生 2 个进程:一个读取原始进程,一个写入副本,您还注意到这些进程之间的字节传输是校验和的。但这在保证副本的正确性方面略有帮助(如果有的话),因为磁盘相关问题破坏数据的可能性远远高于 CPU/RAM 问题的可能性。 (2认同)
  • @ndemou 答案涵盖了磁盘数据写入后缺乏验证。OP接受了答案。 (2认同)

小智 48

rsync没有做本地文件副本后副本验证。您可以通过使用rsync将大文件复制到慢速(即 USB)驱动器,然后使用 复制同一文件来验证它没有cp,即:

time rsync bigfile /mnt/usb/bigfile

time cp bigfile /mnt/usb/bigfile
Run Code Online (Sandbox Code Playgroud)

这两个命令花费的时间大致相同,因此rsync不可能进行校验和——因为这将涉及从慢速磁盘上重新读取目标文件。

man不幸的是,该页面在这方面具有误导性。我还验证了这一点strace- 在复制完成后,rsync不对read()目标文件发出任何调用,因此无法对其进行校验和。您还可以通过以下方式验证它iotop:您看到rsync同时进行读取和写入(从源复制到目标),然后它退出。如果它正在验证完整性,则会有一个只读阶段。

  • 本地或远程的任何副本都没有副本后验证。如果你想强制它检查,你再次运行 `rsync -c`。 (14认同)
  • 验证是在传入流上完成的。如果文件系统已经确认它已被写入,则没有必要从磁盘读回它。 (2认同)

Gil*_*il' 19

rsync复制之前进行校验和比较(在某些情况下),以避免复制已经存在的内容。校验和比较的重点不是验证复制是否成功。这是底层基础设施的工作:文件系统驱动程序、磁盘驱动程序、网络驱动程序等。诸如此类的个别应用程序rsync不需要为这种疯狂而烦恼。所有rsync需要做的(并且做!)就是检查系统调用的返回值以确保没有错误。

  • 好吧,在这种情况下,我同意它更有意义。所以_“校验和比较的重点不是验证复制是否成功”_仅对**本地**副本为真;和_“校验和始终用于发送和接收 rsync 进程之间传输的数据”_ 仅适用于 **transferred** 副本。我发现 [accepted answer](http://unix.stackexchange.com/a/30975/82895) 对该问题具有误导性,并相信您的答案应该是公认的答案(只有我的 2 美分)。 (3认同)
  • 这似乎与公认的答案相矛盾...... (2认同)
  • @djule5 以什么方式?接受的答案似乎主要是关于 rsync 如何检查 **transferred** 文件,但问题和我的答案是关于 **local** 副本。 (2认同)

小智 11

直接回答问题的快速而肮脏的答案。

问:rsync在两个本地驱动器之间复制文件时会进行比较吗?A:它会做比较以找出要复制的内容。

问:如果它确实进行了验证 - 这是一个安全的赌注吗?还是逐字节比较更好?答:与文件 MD5 校验和背后的数学一样安全。您可以尝试做简单的实验来学习和信任该工具。

长答案:我想,您想rsync在复制文件后进行文件比较(一点一点或校验和)。如果您是少数重视数据完整性的人之一,您可能会发现以下内容很有用:

rsync -avh [source] [destination] && rsync -avhc [source] [destination] 
Run Code Online (Sandbox Code Playgroud)

上面的代码rsync文件文件夹在第一次运行时,如果完成没有问题,将rsync立即再次运行,同时使用整个文件的哈希值执行相同的文件名比较。


nob*_*bar 8

使用 rsync 验证副本的完整性

为了保证此测试从驱动器介质中物理重新读取文件,我建议在运行此测试之前关闭两个驱动器的电源并重新启动它们。这将清除其内部易失性缓存。

如果不重新启动 Linux,您至少应该使用以下命令删除缓存 ( * ):

sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
Run Code Online (Sandbox Code Playgroud)

然后重新读取两棵树并比较它们的校验和:

rsync --dry-run --checksum --itemize-changes --archive SRC DEST
Run Code Online (Sandbox Code Playgroud)

现代rsync校验和使用MD5,它是128位。未能检测到单个文件中的错误的可能性非常低(这里有一些讨论),但并非不可能。

  • 祝你好运,正确处理尾部斜杠。 (2认同)