為什麼’rsync –delete-before’從目標中刪除仍然存在於源中的文件?
我有一個帶有 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` {}"'
然後文件最終在正確的位置。下次執行時不會刪除任何內容(除非它不再存在),畢竟豬可以飛。