我想将大量文件从一个本地驱动器复制到另一个本地驱动器。
我读到 rsync 在通过网络将文件发送到远程计算机时会对文件进行校验和比较。
在两个本地驱动器之间复制文件时,rsync 会进行比较吗?
如果它确实进行了验证——这是一个安全的选择吗?还是逐字节比较更好?
答案1
rsync 始终使用校验和来验证文件是否已正确传输。如果目标文件已经存在,如果修改时间和大小与源文件匹配,rsync 可能会跳过更新文件,但如果 rsync 决定需要传输数据,则校验和总是用于发送和接收 rsync 进程之间传输的数据。这验证了接收到的数据与发送的数据以高概率相同,而无需通过网络进行字节级比较的沉重开销。
收到文件数据后,rsync 会将数据写入文件,并相信如果内核指示写入成功,则数据会写入磁盘而不会损坏。 rsync 不会重新读取数据并与已知校验和进行比较作为附加检查。
至于验证本身,对于协议 30 及更高版本(在 3.0.0 中首先支持),rsync 使用MD5。对于较旧的协议,使用的校验和是MD4。
虽然长期以来人们认为 MD5 和 MD4 对于安全加密哈希来说已经过时,但它们仍然足以检查文件损坏。
来源:手册页并查看 rsync 源代码进行验证。
答案2
rsync
做不是对本地文件副本进行复制后验证。您可以通过使用rsync
将大文件复制到慢速(即 USB)驱动器,然后使用复制相同的文件来验证它是否没有cp
,即:
time rsync bigfile /mnt/usb/bigfile
time cp bigfile /mnt/usb/bigfile
两个命令花费的时间大约相同,因此rsync
不可能执行校验和,因为这将涉及从慢速磁盘重新读取目标文件。
不幸的是,该man
页面对此有误导性。我还验证了这一点strace
- 复制完成后,rsync
不对read()
目标文件发出任何调用,因此无法对其进行校验和。您还可以通过以下方式验证它iotop
:您看到rsync
同时进行读取和写入(从源复制到目标),然后退出。如果它正在验证完整性,则会有一个只读阶段。
答案3
rsync
进行校验和比较前复制(在某些情况下),以避免复制已有的内容。校验和比较的目的不是验证复制是否成功。这是底层基础设施的工作:文件系统驱动程序、磁盘驱动程序、网络驱动程序等。诸如此类的单个应用程序rsync
不需要为这种疯狂的事情而烦恼。所有rsync
需要做的(并且确实是!)就是检查系统调用的返回值以确保没有错误。
答案4
使用 rsync 验证副本的完整性
为了保证此测试从驱动器介质中物理重新读取文件,我建议在运行此测试之前关闭两个驱动器的电源并重新启动它们。这将清除其内部易失性缓存。
如果不重新启动 Linux,您至少应该删除缓存(*) 和:
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
然后重新读取两棵树并比较它们的校验和:
rsync --dry-run --checksum --itemize-changes --archive SRC DEST
现代rsync校验和使用MD5,它是128位。未能检测到单个文件中的错误的可能性非常低(一些讨论这里),但并非不可能。