GNU/Linux >> Linux の 問題 >  >> Linux

すべての変更がアトミックに表示される rsync ディレクトリ

--link-dest= を使用できます オプション。基本的に、新しいフォルダーを作成すると、すべてのファイルが新しいフォルダーにハードリンクされます。すべてが完了したら、フォルダ名を入れ替えて古いものを削除するだけです。

カーネル/VFS のサポートがないため、Linux でこの 100% アトミックを行うことは不可能です。ただし、名前の交換は実際には 2 syscall しかかからないため、完了するのに 1 秒もかからないはずです。 HFS ファイルシステムで exchangedata システム コールを使用する Darwin (MAC/OSX) でのみ可能です。


rsync で同様のことを行います [ディスクへの] バックアップを行っていましたが、バックアップの実行中にデーモンがファイルを更新するために、同じ問題に遭遇しました。

多くのプログラムとは異なり、rsync には 多くの さまざまなエラー コード [man ページの下部を参照]。興味深いのは次の 2 つです:

<ブロック引用>

23 -- エラーによる部分転送
24 -- ソースファイルが消失したため部分転送

rsync が転送を行っているときに、これらの状況のいずれかに遭遇した場合、ただちに停止するわけではありません。スキップして、できるファイルを続行します 移行。最後に、リターン コードを示します。

したがって、エラー 23/24 が発生した場合は、rsync を再実行してください。後続の実行ははるかに速くなり、通常は前回の実行で不足しているファイルを転送するだけです。最終的には、問題なく実行できる [または取得する必要がある] でしょう。

アトミックであるため、転送中に「tmp」ディレクトリを使用します。次に、rsync の実行がクリーンになったら、[アトミックに] 名前を <date> に変更します

--link-dest も使用しています オプションですが、私はそれを使用して差分バックアップを保持しています (例:--link-dest=yesterday 毎日)

私自身は使っていませんが、--partial-dir=DIR 隠しファイルがバックアップ ディレクトリを乱雑にするのを防ぐことができます。名前の変更がアトミックになるように、DIR がバックアップ ディレクトリと同じファイル システム上にあることを確認してください

私はこれを perl で行っていますが、あなたの特定の状況に合わせて、私が言ってきたことをもう少し詳細/正確に要約するスクリプトを書きました。これは tcsh に似た構文 [テストされておらず、少しラフ] ですが、独自の bash を作成するための疑似コードとして扱ってください。 、 perlpython 選択したスクリプト。再試行に制限はありませんが、必要に応じて簡単に追加できます。

#!/bin/tcsh -f
# repo_backup -- backup repos even if they change
#
# use_tmp -- use temporary destination directory
# use_partial -- use partial directory
# use_delta -- make delta backup

# set remote server name ...
set remote_server="..."

# directory on server for backups
set backup_top="/path_to_backup_top"
set backup_backups="$backup_top/backups"

# set your rsync options ...
set rsync_opts=(...)

# keep partial files from cluttering backup
set server_partial=${remote_server}:$backup_top/partial
if ($use_partial) then
    set rsync_opts=($rsync_opts --partial-dir=$server_partial)
endif

# do delta backups
if ($use_delta) then
    set latest=(`ssh ${remote_server} ls $backup_backups | tail -1`)

    # get latest
    set delta_dir="$backup_backups/$latest"

    if ($#latest > 0) then
        set rsync_opts=($rsync_opts --link-dest=${remote_server}:$delta_dir)
    endif
endif

while (1)
    # get list of everything to backup
    # set this to whatever you need
    cd /local_top_directory
    set transfer_list=(.)

    # use whatever format you'd like
    set date=`date +%Y%m%d_%H%M%S`

    set server_tmp=${remote_server}:$backup_top/tmp
    set server_final=${remote_server}:$backup_backups/$date

    if ($use_tmp) then
        set server_transfer=$server_tmp
    else
        set server_transfer=$server_final
    endif

    # do the transfer
    rsync $rsync_opts $transfer_list $server_transfer
    set code=$status

    # run was clean
    if ($code == 0) then
        # atomically install backup
        if ($use_tmp) then
            ssh ${remote_server} mv $backup_top/tmp $backup_backups/$date
        endif
        break
    endif

    # partial -- some error
    if ($code == 23) then
        continue
    endif

    # partial -- some files disappeared
    if ($code == 24) then
        continue
    endif

    echo "fatal error ..."
    exit(1)
end

Linux
  1. Rsyncフィルター:1つのパターンのみをコピーしますか?

  2. ディレクトリの下のすべてのディレクトリを小文字にしますか?

  3. Rsyncはディレクトリのアクセス許可を変更していますか?

  1. スラッシュと rsync コマンド

  2. Docker がディレクトリの変更を更新しない

  3. rsync ディレクトリ内の N 個の最新ファイル

  1. ディレクトリ内のすべてのフォルダーのサイズを取得する

  2. ディレクトリ内のすべてのフォルダ/ファイルにデフォルトのファイル権限を設定する方法は?

  3. Bash はディレクトリを変更しなくなりました