Apache が何らかのファイルを 1 つの場所に書き込んでいて、その書き込みが完了していない場合 そして rsync
開始、rsync
そこにあるものは何でもコピーします。
つまり、Apache が 5MB のファイルを処理している場合、2MB だけが書き込まれ、rsync
が書き込まれます。 開始すると、部分的な 2MB ファイルがコピーされます。そのため、そのファイルは宛先サーバーで「破損」しているように見えます。
使用しているファイルのサイズに応じて、--inplace
を使用できます。 rsync
のオプション 次のことを行います:
このオプションは、ファイルのデータを更新する必要がある場合に rsync がファイルを転送する方法を変更します。ファイルの新しいコピーを作成し、完了時にそれを所定の位置に移動するデフォルトの方法の代わりに、rsync は更新されたデータを宛先ファイルに直接書き込みます。
これの利点は、最初の実行で 5MB のファイルが 2MB しかコピーされない場合、次の実行では 2MB で取得され、5MB が完全に配置されるまでファイルのコピーが続行されることです。
欠点は、ファイルのコピー中に誰かが Web サーバーにアクセスし、部分的なファイルが表示されるという状況を引き起こす可能性があることです。私の意見では rsync
「見えない」ファイルをキャッシュし、すぐに移動するというデフォルトの動作で最適に機能します。しかし --inplace
大きなファイルと帯域幅の制約が、大きなファイルを最初から簡単にコピーするのを妨げる可能性があるシナリオに適しています。
つまり、あなたはこれを述べています。強調は私のものです:
<ブロック引用>5分ごと cron で rsync を実行しています…
では、この cron ジョブを管理するための bash スクリプトが用意されていると思いますか?さて、問題は rsync
です コピーする必要があるファイルのみをコピーするのに十分スマートです。また、5 分ごとに実行されるスクリプトがある場合は、 rsync
を回避しようとしているように見えます 速くなったらお互いに踏む。つまり、毎分実行すると、 rsync
の 1 つ以上が失敗するリスクがあります。 ファイル サイズやネットワーク速度が原因でプロセスがまだ実行されていて、次のプロセスが競合しているだけです。競争状態。
これを回避する 1 つの方法は、rsync
全体をラップすることです。 ファイルロックをチェックするbashスクリプトのコマンド。以下は、このような場合に使用するボイラープレートの bash スクリプト フレームワークです。
flock
の使用を推奨する人もいることに注意してください。 しかし flock
以来 は、私が使用している一部のシステムにはインストールされていません。また、Ubuntu (インストールされている) と Mac OS X (インストールされていない) の間を頻繁に行き来しています。この単純なフレームワークを実際の問題なしに使用しています。
LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'
if mkdir ${LOCK_DIR} 2>/dev/null; then
# If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
echo $$ > ${PID_FILE}
echo "Hello world!"
rm -rf ${LOCK_DIR}
exit
else
if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
# Confirm that the process file exists & a process
# with that PID is truly running.
echo "Running [PID "$(cat ${PID_FILE})"]" >&2
exit
else
# If the process is not running, yet there is a PID file--like in the case
# of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
rm -rf ${LOCK_DIR}
exit
fi
fi
アイデアは、echo "Hello world!"
がある一般的なコアです。 —スクリプトの心臓部です。残りの部分は、基本的に mkdir
に基づくロック メカニズム/ロジックです。 .概念の適切な説明は、この回答にあります:
mkdir ディレクトリがまだ存在しない場合は作成し、存在する場合は終了コードを設定します。さらに重要なことは、これらすべてを 1 つのアトミック アクションで実行できるため、このシナリオに最適です。
rsync
の場合 echo
を変更するだけでこのスクリプトを使用することをお勧めします rsync
へのコマンド 指図。また、 LOCK_NAME
を変更します RSYNC_PROCESS
のようなものに
rsync
で今すぐ このスクリプトにラップされているため、2 つ以上の rsync
が競合状態になるリスクなしに、cron ジョブを毎分実行するように設定できます。 プロセスは同じことをしようと戦っています。これにより、速度または rsync
を上げることができます 部分的なファイルが転送される問題を解消するものではありませんが、全体的なプロセスを高速化するのに役立つため、ある時点で完全なファイルを適切にコピーできます。
はい - rsync がファイルへの書き込みと同時にファイルの読み取りを行っている場合、ファイルが破損している可能性があります。
これを試すことができます:https://unix.stackexchange.com/a/2558
lsof でスクリプト化することもできます:
lsof /path/to file
終了コード 0 はファイルが使用中であることを意味し、終了コード 1 はそのファイルにアクティビティがないことを意味します。