rsync が呼び出しごとに同じファイルを送信し続けるのはなぜですか?

rsync が呼び出しごとに同じファイルを送信し続けるのはなぜですか?

SSH 経由で Linux から Mac にファイルをコピーするために rsync を使用しています。

私のコマンドは次のようになります:

rsync \
    --exclude FOO \
    --exclude BAR \
    -e ssh \
    -rclpvih \
    --delete \
    --stats \
    /local/dir/ \
    host:/remote/dir/

出力は次のようになります。

building file list ... done
...
<fc.T...... core/FileRecordingProcessor.cpp
<fc.T...... core/Pipeline.hpp
...

Number of files: 4,910 (reg: 4,401, dir: 509)
Number of created files: 0
Number of regular files transferred: 35
Total file size: 332.34M bytes
Total transferred file size: 2.62M bytes
Literal data: 0 bytes
Matched data: 2.62M bytes
File list size: 196.59K
File list generation time: 0.457 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 209.72K
Total bytes received: 12.03K

sent 209.72K bytes  received 12.03K bytes  147.83K bytes/sec
total size is 332.34M  speedup is 1,498.70

ローカルで何も変更されていない場合でも、rsync は呼び出しごとに同じ (サブ) ファイル セットを転送します。

これらのファイルはツリー全体の小さなサブセットにすぎません。他のファイルは実際に変更されない限り再送信されません。再送信されるファイルの数は常に 35 です。それらすべてに<fc.T......フラグがあります。

ファイルはローカル マシンとリモート マシンで同一に見えます。

地元:

$ ll core/Pipeline.hpp
-rw-r--r-- 1 victor victor 5.1K Nov  2 18:24 core/Pipeline.hpp
$ md5sum core/Pipeline.hpp
7604940d777322a587d2fe2fa12c1183  core/Pipeline.hpp

リモート:

$ ll core/Pipeline.hpp
-rw-r--r-- 1 victor staff 5.1K Nov  3 18:20 core/Pipeline.hpp
$ md5sum core/Pipeline.hpp
7604940d777322a587d2fe2fa12c1183  core/Pipeline.hpp

所有者、グループ、時刻は同じではありませんが、rsyncはそれらを保存するように設定されておらず、チェックサムを使用する

2 台のマシンの時刻は同期されていません。

答え1

これが発生する可能性があるケースの 1 つは、rsync が大文字と小文字を区別するファイルシステム (通常は Linux) と大文字と小文字を区別しないファイルシステム (通常は Windows と MacOS) の間でファイルを転送する場合です。

同期された 2 つのパス (たとえば、d/xd/X) が、たとえば小文字への概念的な変換後も同じである場合、rsync はそれを認識せず、 を転送しd/x、同じ宛先ファイルを で上書きする可能性がありますd/X

ファイルに同じデータが含まれず、タイムスタンプが同じである場合、ファイルは将来の rsync 実行時に常に更新されます。

大文字と小文字の違いが原因で rsync が誤ってファイルを再転送していないか確認することをお勧めします。便利な Linux コマンドは次のとおりです。

find . | tr '[:upper:]' '[:lower:]' | LC_ALL=C sort | LC_ALL=C uniq -d

ソース

答え2

--archive( -a) または--times( ) フラグのいずれかが欠落しています-t。どちらか一方がないとrsync変更時刻を追跡できず、すでにコピーされているように見えるファイルをバイパスできません。

rsyncまた、ファイルがコピーされたことを検証するためにチェックサムを使用するように明示的に指示しているので、それがrsync実行されます。

一般的に言えば、--archive( -a) フラグは必要なことのほぼすべてを実行します。

rsync --exclude FOO --exclude BAR -avi --delete --stats /local/dir/ host:/remote/dir/

-Hハードリンク (ある場合) を保持し、-AXACL と拡張属性 (ある場合) を保持するように追加する必要があるかもしれません。

答え3

TL;DR: macOS を使用している場合は、「brew」や「nix」などのシステムによってインストールされるオープンソースの rsync ではなく、/usr/bin/rsync を使用してみてください。ネイティブ rsync は Apple の特殊なファイルシステムをより適切に理解し、変更されていないファイルを再コピーしません。

長いバージョン...

これが起こる可能性があるのは、使用している のバージョンがrsyncOS 固有の状況をサポートしていない場合です。変更されたと認識されているが実際には変更されていないファイルを再コピーします。

たとえば、私の Mac には の 2 つのバージョンがありますrsync:

$ which -a rsync
/usr/local/bin/rsync
/usr/bin/rsync

/usr/local/bin/rsyncプロトコルバージョン 31 をサポートするバージョン 3.2.4 です。私はこれを「brew」を使用してインストールしました。

/usr/bin/rsyncこれは Apple 提供のバージョンで、バージョン 2.6.9 (かなり古い) からフォークされ、プロトコル バージョン 29 をサポートしています。Apple はこのバージョンを拡張して、macOS 固有のファイル システム機能をサポートするようにしました。

オープンソース版を使用すると、-c変更されていないファイルが再コピーされます。Apple 提供の rsync ではこの問題は発生しません。

プロトコル バージョン 29 と 31 の間には多くの最適化が行われていますが、おそらくそれらに気付かないことはないでしょう。Apple の rsync を使用して正しく動作させることはおそらく重要です。

答え4

私は最終的にユニゾンLinux と macOS (および Windows) 間の同期の場合:

unison \
    -servercmd /usr/local/bin/unison
    -ignore "Name FOO" \
    -ignore "Name BAR" \
    -auto \
    -batch \
    -force /local/dir/ \
    /local/dir/ \
    ssh://host/remote/dir/

関連情報