プロセスAがファイルをlocのいくつかの場所にコピーし、プロセスBが定期的にlocから別の場所にファイルをコピーする場合、Bは現在Aがlocにコピーしているファイルを読み取ることができますか?
これが重要な場合は、Ubuntu Linux 12.04を使用しています。
背景情報:PostgreSQLクラスタを継続的にバックアップしたいと思います。 PostgreSQLはこの目的のためにWALアーカイブを提供します。データベースにWALファイル全体をバックアップ場所にコピーするスクリプトを呼び出すことで機能します。
バックアップされたWALファイルを定期的に別のサーバーにコピーする別のプロセスが必要です。データベースが現在WALファイルをコピーしている場合、ファイル全体がコピーされる前に、2番目のプロセスが一部のEOF条件に遭遇することなくファイルを読み続けることができますか?
つまり、AとBを同期せずに次のことができますか?
A B
cp pg_xlog/some_wal_file /backup/ scp /backup/* user@remote-machine:/backups/
答え1
この場合の唯一の保証は、Bがファイルまたはファイルのプレフィックスをコピーしないことです。 Bはファイルが作成されていることがわからないので、ファイルの(現在の)最後まで読み取ってから停止します。
このトラップを回避する一般的な方法は、ファイルを一時的な名前にコピーしてから名前を変更することです。
dest=$(TMPDIR=/backup mktemp)
trap 'rm -f "$dest"' INT HUP ERR
cp -p pg_xlog/some_wal_file "$dest"
mv "$dest" "/backup/some_wal_file"
消費者から一時ファイルがコピーされないように準備します。あなたのシナリオでは、dest=$(TMPDIR=/backup mktemp .XXXXXXXXXX)
上記の方法を使用してドットファイルにすることでこれを達成できます。より簡単なアプローチは、基本的にこの戦略を使用する代わりにをrsync
呼び出すcp
ことです。rsync
rsync -a pg_xlog/some_wal_file /backup/
手順Bでは、次の一時ファイルを除外する必要があります。
rsync -a --exclude='/.*' /backup/ user@remote-machine:/backups/
ドットファイルに依存したくない場合は、ステージングディレクトリを使用できます。両方のディレクトリが同じファイルシステム上にある限り、あるディレクトリから別のディレクトリにファイルを移動するのはアトミックです。
mkdir -p /backup/incoming
cp -p pg_xlog/some_wal_file /backup/incoming/
mv /backup/incoming/some_wal_file /backup/
rsync -a --exclude=/staging /backup/ user@remote-machine:/backups/
答え2
私の考えの最善の方法は、プロセスBがプロセスAが完全に転送したファイルだけをコピーすることです。これを達成する 1 つの方法は、プロセス A とcp
の組み合わせを使用することです。これは、そのプロセスがシステムコールを使用するmv
ため、アトミックです(ファイルが同じファイルシステムにある場合)。これは、プロセスBの観点から、ファイルが完全に形成されたことを示していることを意味する。mv
rename
これを行う1つの方法は、プロセスBpartial
で無視されるディレクトリにディレクトリを作成することです。/backup
プロセスAでは、次のことができます。
file="some_wal_file"
cp pg_xlog/"$file" /backup/partial
mv /backup/partial/"$file" /backup
プロセスBの場合(使用bash
):
shopt -s extglob
scp /backup/!(partial) user@remote-machine:/backups/
rsync
プロセスAとプロセスBが何をするのかを調べたいかもしれませんが、部分rsync
ファイルはデフォルトで作成され、自動的にその場所に移動されます(部分ファイルは通常、特定のディレクトリに配置されずに隠されたファイルです)。 Rsyncには、不要なファイル転送を防ぎ、ネットワーク経由で更新する必要があるファイルの関連部分のみを転送するための特別なデルタアルゴリズムもあります(転送はデフォルトでは引き続き発生しますが、両方のrsync
場所にインストールする必要があります)。プロセスAssh
の場合rsync
:
rsync -a --partial-dir=/backup/partial pg_xlog/some_wal_file /backup/
プロセスBの場合:
rsync -a --exclude=/partial/ /backup/ user@remote-machine:/backups/