私はbtrfsスナップショットをrsyncと組み合わせて、履歴のある効率的なバックアップソリューションを作成する方法について、いくつかのガイドを読んでいました。ただし、すべてがrsync --inplace
は、実際に変更されたファイルの部分のみを変更するか、ファイル全体を順次上書きするかどうかを変更します。ファイル全体を書き込む場合、btrfsは常にファイルの新しいコピーを作成するため、アイデアの効率が大幅に低下します。
Rsyncに2つのローカルパスを渡す場合、デフォルトでは "--whole-file"が使用され、デルタ転送は使用されません。したがって、探しているのは「--no-whole-file」です。 「-c」を要求した場合は、デルタ転送も取得します。
確認方法は次のとおりです。
$ mkdir a b
$ dd if=/dev/zero of=a/1 bs=1k count=64
$ dd if=/dev/zero of=a/2 bs=1k count=64
$ dd if=/dev/zero of=a/3 bs=1k count=64
$ rsync -av a/ b/
sending incremental file list
./
1
2
3
sent 196831 bytes received 72 bytes 393806.00 bytes/sec
total size is 196608 speedup is 1.00
次に、ファイルをタッチして再同期します
$ touch a/1
$ rsync -av --inplace a/ b/
sending incremental file list
1
sent 65662 bytes received 31 bytes 131386.00 bytes/sec
total size is 196608 speedup is 2.99
「ls -li」でiノードが再利用されたことを確認できますが、64Kバイト全体を送信したことに注意してください。 --no-whole-fileで再試行してください
$ touch a/1
$ rsync -av --inplace --no-whole-file a/ b/
sending incremental file list
1
sent 494 bytes received 595 bytes 2178.00 bytes/sec
total size is 196608 speedup is 180.54
これで、送信したのは494バイトだけです。 straceを使用して、ファイルが書き込まれたかどうかをさらに確認することもできますが、これは、少なくともデルタ転送が使用されていることを示しています。
ローカルファイルシステムの場合、--whole-file
が想定されていることに注意してください(コメントを参照)(rsyncのマニュアルページを参照)。一方、ネットワーク全体では--no-whole-file
が想定されているため、--inplace
自体は--inplace --no-whole-file
として動作します。
ここで私が推測する明確な答えは、マニュアルの正しい部分を引用しています:
--inplace
[...]
This option is useful for transferring large files
with block-based changes or appended data, and
also on systems that are disk bound, not network
bound. It can also help keep a copy-on-write
*************
filesystem snapshot from diverging the entire con‐
*******************
tents of a file that only has minor changes.
--inplace
は、変更された領域のみを上書きします。 Btrfsに書き込むときは常にそれを使用します。
rsyncのデルタ転送アルゴリズムは、ファイル全体が送信されるか、異なる部分のみが送信されるかを扱います。これは、帯域幅を節約するために2つのマシン間でファイルをrsyncするときのデフォルトの動作です。これを--whole-file
(または-W
)でオーバーライドして、rsync
にファイル全体を送信させることができます。
--inplace
は、転送中にrsync
が一時ファイルを作成するかどうかを扱います。デフォルトの動作では、一時ファイルが作成されます。これにより、転送が中断された場合、宛先マシンの既存のファイルはそのまま/変更されないままであるという点で、安全性の基準が提供されます。 --inplace
はこの動作を無効にし、rsync
に既存のファイルを直接更新するように指示します。これを使用すると、転送が中断された場合に、宛先マシンに一貫性のないファイルが存在する危険性があります。
Manページから:
This option changes how rsync transfers a file when its data
needs to be updated: instead of the default method of creating a
new copy of the file and moving it into place when it is com-
plete, rsync instead writes the updated data directly to the
destination file.
これにより、ファイル全体が上書きされると信じるようになります。rsyncが他の方法で動作することはほぼ不可能だと思います。
インプレースのrsyncに関する理論的な作業は この論文 で説明されています。
論文参照:D. RaschおよびR. Burns。インプレースRsync:モバイルデバイスとワイヤレスデバイスのファイル同期。 USENIX Annual Technical Conference、FREENIX track、91-100、USENIX、2003。
リンクから:
...既存のrsync実装を変更して、インプレース再構成をサポートしました。
要約:[...]スペースに制約のあるデバイスで動作するようにrsyncを変更しました。 ターゲットホスト上のファイルは、ファイルの現在のバージョンが使用しているのと同じストレージで更新されます。スペースに制約のあるデバイスは、ファイルの古いバージョンと新しいバージョンの両方にメモリまたはストレージを必要とするため、従来のrsyncを使用できません。例としては、メモリが小さい携帯電話やハンドヘルドPCでのファイルの同期があります。インプレースrsyncアルゴリズムは、グラフ内のファイルの圧縮表現をエンコードし、トポロジ的に並べ替えて、インプレースプロパティを実現します。 [...]
したがって、これはrsync --inplaceが行っていることの技術的な詳細のようです。論文の冒頭によると:
Rsyncを変更して、インプレース再構成でファイル同期タスクを実行できるようにしました。 [...]一時スペースを使用する代わりに、ターゲットファイルへの変更は、現在のバージョンですでに占有されているスペースで行われます。このツールは、スペースが限られているデバイスを同期するために使用されます。
@ datalessの答え から明らかになるように、これは--inplace
は同じストレージスペースを使用していますが、ファイル全体をそのスペースにコピーする場合があります。特に、ローカルファイルシステムとの間でコピーが作成されると、rsyncは--whole-file
オプション。ただし、ネットワークシステム全体の場合は、--no-whole-file
オプション。