GNU/Linux >> Belajar Linux >  >> Linux

direktori rsync sehingga semua perubahan muncul secara atomik

Anda dapat menggunakan --link-dest= pilihan. Pada dasarnya Anda akan membuat folder baru, semua file ditautkan dengan keras ke yang baru. Setelah semuanya selesai, Anda tinggal menukar nama folder dan menghapus yang lama.

Tidak mungkin melakukan 100% atomik ini di Linux karena tidak ada dukungan kernel/VFS untuk itu. Namun, menukar nama sebenarnya hanya berjarak 2 syscall sehingga perlu waktu kurang dari 1 detik untuk menyelesaikannya. Ini hanya mungkin di Darwin (MAC/OSX) dengan panggilan sistem pertukaran data pada sistem file HFS.


Saya melakukan sesuatu yang mirip dengan rsync backup [ke disk] dan saya mengalami masalah yang sama karena daemon memperbarui file saat pencadangan sedang berjalan.

Tidak seperti kebanyakan program, rsync memiliki banyak kode kesalahan yang berbeda [Lihat bagian bawah halaman manual]. Yang menarik adalah dua:

23 -- pengalihan sebagian karena kesalahan
24 -- transfer sebagian karena file sumber hilang

Ketika rsync melakukan transfer dan menemukan salah satu situasi ini, itu tidak berhenti begitu saja. Itu melompati dan melanjutkan dengan file yang bisa transfer. Pada akhirnya, ini menampilkan kode pengembalian.

Jadi, jika Anda mendapatkan kesalahan 23/24, jalankan kembali rsync. Proses selanjutnya akan jauh lebih cepat, biasanya hanya mentransfer file yang hilang dari proses sebelumnya. Pada akhirnya, Anda akan mendapatkan [atau seharusnya] hasil yang bersih.

Untuk menjadi atom, saya menggunakan dir "tmp" selama transfer. Kemudian, ketika rsync run sudah bersih, saya mengganti namanya [atomically] menjadi <date>

Saya juga menggunakan --link-dest opsi, tetapi saya menggunakannya untuk menyimpan cadangan delta (mis. --link-dest=yesterday untuk harian)

Meskipun saya belum menggunakannya sendiri, --partial-dir=DIR dapat menjaga agar file tersembunyi tidak mengacaukan direktori cadangan. Pastikan bahwa DIR berada pada sistem file yang sama dengan direktori cadangan Anda sehingga penggantian nama akan bersifat atomik

Sementara saya melakukan ini di perl, saya menulis skrip yang merangkum apa yang telah saya katakan dengan sedikit lebih detail/presisi untuk situasi khusus Anda. Itu dalam sintaks mirip tcsh, [belum diuji dan agak kasar], tetapi perlakukan itu sebagai kode semu untuk menulis bash Anda sendiri , perl , python skrip sesuai pilihan Anda. Perhatikan bahwa ini tidak membatasi percobaan ulang, tetapi Anda dapat menambahkannya dengan cukup mudah, sesuai keinginan Anda.

#!/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. CentOS / RHEL :Cara mengatur chroot jail untuk vsftp untuk semua pengguna

  2. Garis miring dan perintah rsync

  3. Docker tidak memperbarui perubahan dalam direktori

  1. rsync N file terbaru dalam direktori

  2. Dapatkan Ukuran Semua Folder di Direktori

  3. Bagaimana cara mengatur izin file default untuk semua folder/file dalam direktori?

  1. Filter Rsync:Menyalin Satu Pola Saja?

  2. Huruf Kecil Semua Direktori Di Bawah Direktori?

  3. Bash Tidak Lagi Mengubah Direktori