私はソフトウェア配布用に (Linux ベースの) rsync サーバーを実行しています。私の管理外にある (Windows ベースの) ソース リポジトリ サーバーが rsync 経由でソフトウェア パッケージをプッシュし、世界中の約 100 台のサテライト サーバーが rsync 経由でそこからプルします。
ソース リポジトリには、大きな重複ファイルが多数含まれています。これらの重複ファイルをハードリンクに置き換えることで、サテライト サーバーのディスク領域と帯域幅の消費量を削減したいと考えています。ソース リポジトリの管理者はソースでこれを行うことを望まないか、または実行できないため、事後に配布サーバーで実行しようとしています。fdupes
重複ファイルのグループを見つけて、それらを 1 つのファイルへのハードリンクに置き換えるコマンドに基づいて、簡単な bash スクリプトを作成しました。サテライト サーバーへの rsync 転送では、-H オプションにより、これらのハードリンクが必要に応じて保持されます。ただし、ソース リポジトリからの転送では、一貫性のない結果が生成されます。重複排除が保持される場合もあれば、重複排除されたグループのすべてのファイルをソース サーバーが再送信し、ソース ファイルが変更されていなくても重複排除が壊れる場合もあります。
そこで質問です。同一だが別々の 2 つのファイルを同期するように要求され、そのファイルが正しい内容で宛先に既に存在しているが、同じファイルへのハードリンクである場合、rsync の正式な動作はどうなるのでしょうか。ファイルを再送信するための正確な基準は何ですか。ソースにハードリンクが存在しない場合でも、その状況で宛先のハードリンクが保持されるようにする方法はありますか。
答え1
tl;dr: 宛先のハードリンクを介してファイルレベルの重複排除を維持するには、オプションrsync
を指定して実行します--checksum
。
私が行った一連の実験に基づく完全な答えは次のとおりです。
2 つのファイルがソースでハードリンクされていない場合、rsync
は各ファイルを個別に宛先に同期します。ファイルが宛先でハードリンクされているかどうかは関係ありません。ファイルの 1 つ (または両方) が再転送された場合、宛先のハードリンクは解除されますが、それ以外の場合はそのままです。つまり、 の--hard-links
オプションを使用しても、rsync
ファイルがソースでハードリンクされていないという理由だけで宛先のハードリンクが解除されることはありません。
ファイルを再送信する基準は、--checksum
( -c
) および--ignore-times
( -I
) オプションによって異なります。
- このオプション
--checksum
が指定されている場合、送信元と送信先の間でサイズまたはチェックサムが異なるファイルのみが再送信されます。したがって、ファイルの内容が変更されていない場合は、送信元にハード リンクが存在しなくても、送信先のハード リンクは保持されます。 - このオプション
--ignore-times
が指定されると、すべてのファイルが再送信され、送信元に存在しないハードリンクが送信先で切断されます。 - これら 2 つのオプションのどちらも指定されていない場合は、
rsync
ソース ファイルと宛先ファイルの変更タイムスタンプを使用して決定します。その場合、2 つのソース ファイルのタイムスタンプが異なると、2 つのタイムスタンプのうち 1 つしか一致しないため、宛先のハード リンクは常に切断されます。
答え2
-Hまたは--hard-linksオプションを使用すると、ソースのハードリンクが保持されます。
それはないハードリンクを作成します。これは、同じチェックサムを持つファイルを探し、1 つを削除し、それを置き換えるハードリンクを追加することで、事後に行う必要があります。結局のところ、rsync によって、内容が重複するすべてのファイルが、同じファイルへのハードリンクになることは望ましくありません。長さが 0 のすべてのファイルがハードリンクであると想像してください。1 つのファイルに内容を追加すると、すべての内容が変更されます。