GNU/Linux >> Linux Esercitazione >  >> Linux

directory rsync in modo che tutte le modifiche vengano visualizzate in modo atomico

Puoi usare il --link-dest= opzione. Fondamentalmente creeresti una nuova cartella, tutti i file sono collegati a quella nuova. Quando tutto è finito, puoi semplicemente scambiare i nomi delle cartelle e rimuovere quello vecchio.

È impossibile farlo al 100% atomico in Linux poiché non esiste un supporto kernel/VFS per questo. Tuttavia, lo scambio dei nomi richiede in realtà solo 2 chiamate di sistema, quindi dovrebbe essere necessario meno di 1 secondo per completarlo. È possibile solo su Darwin (MAC/OSX) con la chiamata di sistema exchangedata sui filesystem HFS.


Faccio qualcosa di simile con rsync backup [su disco] e ho riscontrato lo stesso problema a causa di un demone che aggiorna i file mentre il backup è in esecuzione.

A differenza di molti programmi, rsync ne ha molti diversi codici di errore [Vedere la parte inferiore della pagina man]. Di interesse sono due:

23 -- trasferimento parziale per errore
24 -- trasferimento parziale dovuto a file sorgente scomparsi

Quando rsync sta eseguendo un trasferimento e incontra una di queste situazioni, non si ferma immediatamente. Salta e continua con i file che può trasferimento. Alla fine presenta il codice di ritorno.

Quindi, se ricevi l'errore 23/24, esegui nuovamente rsync. Le esecuzioni successive andranno molto più velocemente, di solito solo trasferendo i file mancanti dall'esecuzione precedente. Alla fine, otterrai [o dovresti ottenere] una corsa pulita.

Per quanto riguarda l'essere atomico, durante il trasferimento utilizzo una directory "tmp". Quindi, quando l'esecuzione di rsync è pulita, la rinomino [atomicamente] in <date>

Uso anche il --link-dest opzione, ma la uso per mantenere i backup delta (ad es. --link-dest=yesterday per giornaliero)

Anche se non l'ho usato personalmente, il file --partial-dir=DIR può impedire ai file nascosti di ingombrare la directory di backup. Assicurati che DIR sia sullo stesso filesystem della tua directory di backup in modo che le rinominazioni siano atomiche

Mentre lo faccio in perl, ho scritto uno script che riassume ciò che ho detto con un po' più di dettaglio/precisione per la tua situazione particolare. È in sintassi simile a tcsh, [non testato e un po' approssimativo], ma trattalo come uno pseudo-codice per scrivere il tuo bash , perl , python script come si sceglie. Nota che non ha limiti ai tentativi, ma puoi aggiungerlo abbastanza facilmente, secondo i tuoi desideri.

#!/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. Filtro Rsync:copiare un solo pattern?

  2. Slash e il comando rsync

  3. Docker non aggiorna le modifiche nella directory

  4. Come impostare le autorizzazioni file predefinite per tutte le cartelle/file in una directory?

  5. Bash non modifica più la directory

Come eseguire tutti gli script in una directory in Linux

Come usare Rsync

Esempi di comandi Linux rsync

Come configurare un demone Rsync sul tuo server Linux

rsync N file più recenti in una directory

Ottieni la dimensione di tutte le cartelle nella directory