Rsyncを使用してファイルサーバーを削除ファイルサーバーにバックアップしようとしています。転送が中断された場合、Rsyncは正常に再開されません。部分的なオプションを使用しましたが、rsyncは一時ファイルに名前を変更し、再開すると新しいファイルを作成して最初から開始するため、すでに開始されているファイルを検出しません。
これが私のコマンドです:
rsync -avztP -e "ssh -p 2222" /volume1/ myaccont@backup-server-1:/home/myaccount/backup/ --exclude "@spool" --exclude "@tmp"
このコマンドを実行すると、ローカルマシンにあるOldDisk.dmgという名前のバックアップファイルが。OldDisk.dmg.SjDndj2のようなものとしてリモートマシンに作成されます。
インターネット接続が中断されて転送を再開する必要がある場合、。OldDisk.dmg.SjDndj2のような一時ファイルを見つけてrsyncが中断した場所を見つけ、名前をOldDisk.dmg再開できるファイルがすでに存在することを確認します。
毎回手動で介入する必要がないように、これを修正するにはどうすればよいですか?
TL; DR:デフォルトのrsyncサーバーのタイムアウトを変更するには、--timeout=X
ではなく--inplace
(X秒)を使用します。
問題は、rsyncサーバープロセス(2つあり、レシーバーのps
出力のrsync --server ...
を参照)が実行を続け、rsyncクライアントがデータを送信するのを待つことです。
Rsyncサーバープロセスが十分な時間データを受信しない場合、一時ファイルを「適切な」名前(たとえば、一時的なサフィックスがない)に移動することで、タイムアウト、自動終了、クリーンアップが実行されます。その後、再開することができます。
デフォルトの長いタイムアウトが発生してrsyncサーバーが自己終了するのを待たない場合は、インターネット接続が回復したときにサーバーにログインし、rsyncサーバープロセスを手動でクリーンアップします。ただし、 丁寧に終了する必要があります rsync-それ以外の場合は、部分ファイルを適切な場所に移動しません。むしろ、それを削除します(したがって、再開するファイルはありません)。 rsyncに終了を丁寧に要求するには、SIGKILL
(例:-9
)ではなくSIGTERM
(例:pkill -TERM -x rsync
-例にすぎないので、注意する必要がありますクライアントに関係するrsyncプロセスのみに一致します)。
幸い、もっと簡単な方法があります。--timeout=X
(X秒)オプションを使用します。 rsyncサーバープロセスにも渡されます。
たとえば、rsync ... --timeout=15 ...
を指定した場合、クライアントとサーバーの両方のrsyncプロセスは、15秒以内にデータを送受信しない場合、正常に終了します。サーバー上では、これは一時ファイルを所定の位置に移動し、再開できるようにすることを意味します。
さまざまなrsyncプロセスのデフォルトのタイムアウト値が死ぬ前にデータの送受信を試行するかどうかはわかりません(オペレーティングシステムによって異なる場合があります)。私のテストでは、サーバーのrsyncプロセスはローカルクライアントよりも長く実行されたままです。 「デッド」ネットワーク接続では、クライアントは約30秒後にパイプが壊れて(ネットワークソケットがないなど)終了します。ソースコードを実験したり確認したりできます。つまり、悪いインターネット接続を15〜20秒間「乗り切る」ことができます。
サーバーのrsyncプロセスをクリーンアップしない(またはプロセスが終了するのを待つ)のではなく、代わりに別のrsyncクライアントプロセスをすぐに起動すると、2つの追加サーバープロセスが起動します(新しいクライアントプロセスのもう一方の端)。具体的には、新しいrsyncクライアントは既存のrsyncサーバープロセスに再利用/再接続しません。したがって、2つの一時ファイル(および4つのrsyncサーバープロセス)があります-ただし、新しい2番目の一時ファイルのみが、新しいデータが(新しいrsyncクライアントプロセスから受信して)書き込まれます。
興味深いことに、すべてのrsyncサーバープロセスをクリーンアップした場合(たとえば、新しいrsyncサーバーを停止するクライアントを停止し、次に古いrsyncサーバーをSIGTERM
)、すべての部分ファイルをマージ(アセンブル)しているように見えます新しい適切な名前のファイルです。ですから、長時間実行される部分的なコピーが死ぬことを想像してください(そして、コピーされたすべてのデータが "失われた"と思います)。 2番目のクライアント、SIGTERM
最初のサーバー。データをマージし、再開できます。
最後に、いくつかの短いコメント:
--inplace
を使用しないでください。その結果、間違いなく他の問題が発生します。詳細についてはman rsync
をご覧ください。-t
は冗長です。これは、-a
によって暗示されます。--checksum
/-c
を理解している限り、この場合は役に立ちません。これは、rsyncがファイルを転送する必要があるかどうかを決定する方法に影響します。ただし、最初のrsyncが完了した後、-c
でsecondrsyncを実行してチェックサムを要求し、ファイルサイズとmodtimeが同じであるという奇妙なケースを防ぐことができます両側にありますが、不正なデータが書き込まれました。申し訳ありませんが、ここでの他の回答は複雑すぎます:-7。私のために働くより簡単な答え:(-e sshでrsyncを使用)
# optionally move rsync temp file, then resume using rsync
dst$ mv .<filename>.6FuChr <filename>
src$ rsync -avhzP --bwlimit=1000 -e ssh <fromfiles> <user@somewhere>:<destdir>/
中断されたscpから再開するときにも機能します。
Rsyncは一時ファイルを作成します...一時ファイルは、部分的に転送されたファイルのサイズまで急速に拡大します。転送が再開されます。
Scpは実際の最終宛先ファイルに書き込みます。転送が中断された場合、これは切り捨てられたファイルです。
引数の説明:
-avhz .. h = humanoid、v = verbose、a = archive、z = compression ..archiveは、time_t値を維持するように指示します。これにより、クロックが外れても、rsyncは各ファイルの実際の日付を認識します。
-Pは--partial --progressの略です。 --partialは、部分的に転送されたファイルを保持するようにrsyncに指示します(再開時に、rsyncはチェックサムが安全に行われた後は常に部分的に転送されたファイルを使用します)
Manページから: http://ss64.com/bash/rsync_options.html
--partial
By default, rsync will delete any partially transferred file if the transfer
is interrupted. In some circumstances it is more desirable to keep partially
transferred files. Using the --partial option tells rsync to keep the partial
file which should make a subsequent transfer of the rest of the file much faster.
--progress
This option tells rsync to print information showing the progress of the transfer.
This gives a bored user something to watch.
This option is normally combined with -v. Using this option without the -v option
will produce weird results on your display.
-P
The -P option is equivalent to --partial --progress.
I found myself typing that combination quite often so I created an option to make
it easier.
注:複数回中断される接続の場合: rsyncの後で(接続が中断された後で)再開する必要がある場合は、宛先の一時ファイルの名前を変更するのが最善です。 scpは、最終ファイルと同じ名前のファイルを宛先に作成します。 scpが中断された場合、このファイルはファイルの切り捨てられたバージョンです。 rsync(-avzhP)はそのファイルから再開しますが、.. Yhg7alのような一時ファイル名への書き込みを開始します。
Scpで開始する場合の手順:
scp; *interrupt*; rsync; [REPEAT_as_needed: *interrupt*; mv .destfile.tmpzhX destfile; rsync;].
Rsyncで開始する場合の手順:
rsync; [REPEAT_as_needed: *interrupt*; mv .destfile.tmpzhX destfile; rsync;].
--inplaceを追加すると修正されることがわかりました。 --partialがそれなしでどのように機能するかはわかりませんが、転送が再開されました。私のファイルはまだかなり大きいですが、転送が開始されて数時間後に別の転送が開始されても不完全なファイルが表示されるのではないかと思っていますが、不完全なファイルが表示され、現在アップロードされていることがわかりません。それ。誰か知ってる?たぶん、現在のプロセスIDをログに記録し、別の転送を開始しないbashスクリプトがありますか?
再開後に破損したファイルが怖い場合は、--checksum
毎回ファイル全体のチェックサムを強制します。実際には、いくらかのディスクIOとCPUサイクルがかかりますが、わずかなネットワークオーバーヘッドしかかかりません。