为什么“rsync --delete-before”会从目标中删除源中仍然存在的文件?

为什么“rsync --delete-before”会从目标中删除源中仍然存在的文件?

我有一台装有 rsync 3.1.1 的 centOS 7.1 Linux 机器。那里有一些文件我想传输到 FreeNAS 9.10 机器。为此,我在 freeNAS 上设置了一个 rsync 守护进程,文件传输工作正常。但是当文件在源端被删除时,我希望它们也从目标端被删除。所以我在 Linux 机器上运行的 rsync 命令中添加了 --delete-before。为什么是“before”而不是正常的删除?因为我过去parallel通过同时运行多个 rsync 来加快同步速度。并行 rsync 不能与删除结合使用,因为每个 rsync 实例只能看到文件集的一小部分,如果与删除命令结合使用,则会删除大量文件,甚至可能删除其他线程刚刚放在那里的文件。因此,我首先使用 --delete-before 运行 rsync,在几秒钟后终止 rsync,以便它有足够的时间进行删除,然后运行并行 rsync 命令。这有点像 hack,但应该可以工作。但是,当使用 --dry-run 运行 rsync 命令时,我可以看到它将从目标中删除仍存在于源中的文件。

这是我正在运行的 rsync 命令:

rsync -av --delete-before --dry-run -P /some/folder/structure/ remotebackup.machine.com::backup/somefolder/

其输出为:

building file list ...
415 files to consider
deleting fiFI.20150914.1317
deleting fiFI.20150914.1316
deleting my.20150914.1317
./
bareos/
bareos/my.20150917.1230
bareos/prod.20150918.0530
bareos/front01.20151101.0545
bareos/my.20160224.1504
bareos/fiFI.20150914.1316
bareos/fiFI.20150914.1317
bareos/fiFI.20150915.1311
bareos/fiFI.20150920.1230
bareos/fiFI.20150921.1231
bareos/fiFI.20150922.1230
bareos/fiFI.20151101.1230
<snip>

如您所见,rsync 打算删除一些 fiFI 文件,但稍后它打算传输这些文件。这与 rsync 手册中似乎所述的 --delete-before 应该做的事情不同(仅当文件不再存在于源中时才删除),而且效率很低 -> 需要传输更多数据。

我已经验证文件确实仍然存在于源文件和目标文件中,因此我预计它应该只传输更新,而不是先删除目标文件。

由于我尝试传输的数据量(5TB)以及需要并行传输(因为吞吐量),因此无法使用非并行 rsync 运行常规删除。我研究过同步数据的其他方法,但最终还是放弃了。Rsync 是一个非常强大的工具,应该能够很好地完成这项工作。它的行为与我预期的不同,而且似乎与手册中所说的不同。

这是正常现象吗?我做错了什么吗?为什么会这样(传输前删除)?

有趣的是,如果我运行初始 rsync 删除文件并同步它们,然后再次运行相同的 rsync,文件就会被删除再次并转移再次

答案1

我搞明白了,rsync 没有问题。在第二步中,我并行传输数据时使用了以下命令:

find /some/folder/structure/ -type f -mmin +60 | parallel -j4 'echo "starting `date` {}";rsync -av --no-compress --no-whole-file --quiet {} somehost.com::backup/somefolder/;echo "done `date` {}"'

这会导致所有文件都写入目标的“某个文件夹”,而不管目录结构如何。下次运行脚本时,第一步会在文件不应该出现的位置找到文件,因此会删除它们。然后它会传输它们。第一个 rsync 会将它们传输到正确的位置,但该步骤仅用于删除不存在并被杀死的文件。然后第二个 rsync 运行,但由于它不正确,它会将文件放在错误的位置。重复上述操作。

解决方法是使用如下相对路径:

find /some/folder/structure/ -type f -mmin +60 | sed 's/\some\/folder\/structure\/\(.*\)/\some\/folder\/structure\/.\/\1/g' | parallel -j4 'echo "starting `date` {}";rsync -av --no-compress --no-whole-file --quiet {} somehost.com::backup/somefolder/;echo "done `date` {}"'

然后文件就到了正确的地方。下次运行时不会删除任何文件(除非文件不再存在),毕竟猪也能飞。

相关内容