Linux

為什麼’rsync –delete-before’從目標中刪除仍然存在於源中的文件?

  • May 4, 2016

我有一個帶有 rsync 3.1.1 的 centOS 7.1 linux 機器。那裡有我想傳輸到 FreeNAS 9.10 機器的文件。為此,我在 freeNAS 上設置了一個 rsync 守護程序,並且傳輸文件工作正常。但是當文件在源中被刪除時,我希望它們也從目標中刪除。所以我在 Linux 機器上執行的 rsync 命令中添加了 –delete-before。為什麼是“之前”而不是正常的刪除?因為我用parallel通過同時執行多個 rsync 來加速同步。並行化的 rsync 不能與 delete 結合使用,因為每個 rsync 實例只能看到文件集的一小部分,如果與 delete 命令結合使用,則會刪除大量文件,甚至可能刪除其他執行緒擁有的文件就放在那裡。因此,我首先使用 –delete-before 執行 rsync,幾秒鐘後終止 rsync,以便它有足夠的時間進行刪除,然後執行並行 rsync 命令。這有點像黑客,但它應該可以工作。但是,當使用 –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 來刪除文件並 sycs ,然後再次執行相同的 rsync,文件會再次被刪除並**再次傳輸。

我想通了,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` {}"'

然後文件最終在正確的位置。下次執行時不會刪除任何內容(除非它不再存在),畢竟豬可以飛。

引用自:https://serverfault.com/questions/774514