directory rsync afin que tous les changements apparaissent atomiquement

Je fais des rétroviseurs nocturnes et hebdomadaires de référentiels fréquemment utilisés pour le réseau local. À quelques resockets, quelqu'un a essayé de faire une mise à jour alors que le rsync se déroule et échoué car les files attendus ne sont pas tous là encore.

Est-il possible de faire un rsync de sorte que tous les files modifiés n'apparaissent qu'avec les noms corrects à la fin? Je sais que rsync utilise des files temporaires .hidden pendant que chaque transfert est en cours, mais puis-je reporter les renommes jusqu'à ce qu'il soit terminé de quelque façon?

Alternativement, il me semble que je pourrais utiliser l'option –backup pour déplacer toutes les modifications dans un directory et les déplacer atomiquement après, mais je voudrais que la fonction fonctionne en sens inverse de ce qu'elle fait maintenant.

Je suis sur Linux pour ce qu'il vaut.

4 Solutions collect form web for “directory rsync afin que tous les changements apparaissent atomiquement”

Vous pouvez utiliser l' --link-dest= . Fondamentalement, vous créez un nouveau dossier, tous les files sont liés à la nouvelle. Lorsque tout est terminé, vous pouvez simplement échanger les noms de dossiers et supprimer l'ancien.

Il est impossible de le faire 100% atomique dans Linux car il n'y a pas de support kernel / VFS pour celui-ci. Cependant, échanger les noms n'est en fait que 2 syscalls, donc il faudrait less de 1 seconde pour le compléter. Il est possible uniquement sur Darwin (MAC / OSX) avec l'appel du système échangé sur les filesystems HFS.

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

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

23 – transfert partiel en raison d'une erreur
24 – transfert partiel en raison de files source disparus

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

Donc, si vous obtenez une erreur 23/24, relancez le rsync. Les courses suivantes vont beaucoup plus rapidement, généralement en transférant les files manquants de la course précédente. Finalement, vous obtiendrez [ou devriez] une course propre.

En ce qui concerne l'atomisation, j'utilise un dir "tmp" pendant le transfert. Ensuite, lorsque rsync s'exécute est propre, je le renomme [atomiquement] à <date>

J'utilise aussi l'option --link-dest , mais j'utilise cela pour garder les sauvegardes delta (par exemple, – --link-dest=yesterday pour tous les jours)

Même si je ne l'ai pas utilisé moi-même, le --partial-dir=DIR peut empêcher les files cachés d'encombrer le directory de sauvegarde. Assurez-vous que DIR est sur le même système de files que votre directory de sauvegarde, donc les renommer seront atomiques

Alors que je fais cela dans Perl, j'ai écrit un script qui résume ce que j'ai dit avec un peu plus de détails et de précision pour votre situation particulière. C'est dans la syntaxe de type tcsh, [non testé et un peu brutal], mais considérez-le comme un pseudo-code pour écrire votre propre script bash , perl , python , comme vous le souhaitez. Notez qu'il n'y a pas de limite sur les tentatives, mais vous pouvez l'append 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 

Je ne sais pas si cela va vous aider, mais …

Si cela ne vous dérange pas de copyr l'set du jeu de données à chaque fois et si vous pouvez utiliser des liens symboliques pour se référer au directory cible, vous devriez pouvoir rsync tout dans un directory temporaire, puis échangez ( renommez () ) l'ancien et le nouveau liens symboliques atomiques, comme ça:

 % mkdir old_data new_data % ln -s old_data current % ln -s new_data new % strace mv -T new current 

qui fonctionne

rename("new", "current") = 0

et donne

 current -> new_data 

Même pour que cela fonctionne, tous les clients essayant de lire à partir de cette configuration devraient être dans le directory référencé par le lien symbolique avant d'essayer des lectures, sinon ils risquent de charger certaines parties du code / données de l'ancienne copy et certaines de celles-ci.

Le miroir se synchronise-t-il automatiquement (une tâche cron ou similaire)? Si c'est le cas, vous utilisez probablement un user OS spécialisé pour cela, n'est-ce pas? Donc, la solution pourrait être, au lieu de simplement copyr:

  1. Définissez les permissions de directory de destination de sorte que seul rsync puisse y accéder.
  2. Procéder à la synchronisation.
  3. Changez les permissions de la cible (inconditionnellement) afin que les autres puissent y accéder à nouveau.

L'inconvénient est que pendant le process de synchronisation (pas sûr de la durée nécessaire), le directory cible ne sera pas accessible. Vous devez vous décider si c'est correct ici.

  • client rsync freebsd, server rsync linux
  • Xen: convertit l'image en lvm avec un time d'arrêt minimal
  • Sauvegarde des files cpanel dans le directory personnel. Quels problèmes peuvent survenir?
  • Comment faire une copy ISO du système de files Linux et des files user de VPS Debian basés?
  • Transition de rsync vers ZFS envoyer / recevoir
  • Comment organiser mes sauvegardes?
  • Puis-je sauvegarder un count dovecot via rsync?
  • RSYNC et SCP différences
  • Cwrsync sur Server 2008 R2 comme tâche planifiée
  • Transférer un file du server distant A vers le server distant B du server C
  • rsync: transfert de files dans une seule direction
  • Les astuces du serveur de linux et windows, tels que ubuntu, centos, apache, nginx, debian et des sujets de rĂ©seau.