GNU/Linux >> Tutoriels Linux >  >> Linux

répertoire rsync pour que toutes les modifications apparaissent de manière atomique

Vous pouvez utiliser le --link-dest= option. Fondamentalement, vous créeriez un nouveau dossier, tous les fichiers sont liés en dur au nouveau. Lorsque tout est terminé, vous pouvez simplement échanger les noms de dossier et supprimer l'ancien.

Il est impossible de faire cela à 100% atomique sous Linux car il n'y a pas de support noyau/VFS pour cela. Cependant, l'échange des noms n'est en fait qu'à 2 appels système, il devrait donc prendre moins d'une seconde pour le terminer. Cela n'est possible que sur Darwin (MAC/OSX) avec l'appel système exchangedata sur les systèmes de fichiers HFS.


Je fais quelque chose de similaire avec rsync sauvegardes [sur disque] et j'ai rencontré le même problème en raison d'un démon mettant à jour les fichiers pendant l'exécution de la sauvegarde.

Contrairement à de nombreux programmes, rsync en a beaucoup différents codes d'erreur [Voir la page de manuel en bas]. D'intérêt sont deux :

23 -- transfert partiel en raison d'une erreur
24 -- transfert partiel en raison de fichiers sources disparus

Lorsque rsync effectue un transfert et rencontre l'une de ces situations, il ne s'arrête pas immédiatement. Il saute et continue avec les fichiers qu'il peut transférer. A la fin, il présente le code de retour.

Donc, si vous obtenez l'erreur 23/24, relancez simplement le rsync. Les exécutions suivantes iront beaucoup plus rapidement, généralement en transférant simplement les fichiers manquants de l'exécution précédente. Finalement, vous obtiendrez [ou devriez obtenir] une course sans faute.

Quant à être atomique, j'utilise un répertoire "tmp" lors du transfert. Ensuite, lorsque rsync run est propre, je le renomme [atomiquement] en <date>

J'utilise aussi le --link-dest option, mais je l'utilise pour conserver les sauvegardes delta (par exemple, --link-dest=yesterday pour tous les jours)

Bien que je ne l'ai pas utilisé moi-même, le --partial-dir=DIR peut empêcher les fichiers cachés d'encombrer le répertoire de sauvegarde. Assurez-vous que DIR est sur le même système de fichiers que votre répertoire de sauvegarde afin que les noms soient atomiques

Pendant que je fais cela en perl, j'ai écrit un script qui résume ce que j'ai dit avec un peu plus de détails/précision pour votre situation particulière. C'est dans une syntaxe de type tcsh, [non testé et un peu grossier], mais traitez-le comme un pseudo-code pour écrire votre propre bash , perl , python script que vous choisissez. Notez qu'il n'y a pas de limite de tentatives, mais vous pouvez l'ajouter assez facilement, selon vos souhaits.

#!/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 :Comment définir la prison chroot pour vsftp pour tous les utilisateurs

  2. Les barres obliques et la commande rsync

  3. Docker ne met pas à jour les modifications dans le répertoire

  4. rsync N fichiers les plus récents dans un répertoire

  5. Bash ne change plus de répertoire

Comment exécuter tous les scripts dans un répertoire sous Linux

Comment utiliser Rsync

Exemples de commandes Linux rsync

Comment configurer un démon Rsync sur votre serveur Linux

Obtenir la taille de tous les dossiers du répertoire

Comment définir les autorisations de fichier par défaut pour tous les dossiers/fichiers d'un répertoire ?