GNU/Linux >> Tutoriels Linux >  >> Linux

Utilitaire de sauvegarde Linux pour les sauvegardes incrémentielles

Bien que tar dispose d'un mode incrémentiel, il existe quelques outils plus complets pour faire le travail :

  • Duplicité
  • Duplicata

Non seulement ils prennent en charge les sauvegardes incrémentielles, mais il est facile de configurer un calendrier sur lequel une sauvegarde complète doit être effectuée. Par exemple en duplicity :duplicity --full-if-older-than 1M s'assurera qu'une sauvegarde complète a été exécutée. Ils prennent également en charge le retour dans le temps vers un fichier spécifique, avec le tar ordinaire, vous devrez parcourir tous les fichiers incrémentiels jusqu'à ce que vous en trouviez un qui contient le bon fichier.

De plus, ils prennent en charge le cryptage et le téléchargement vers une variété de backends (comme sftp, le stockage blob, etc.). Evidemment si vous cryptez, n'oubliez pas de faire une bonne sauvegarde de vos clés sur une sauvegarde secondaire !

Un autre aspect important est que vous pouvez vérifier l'intégrité de vos sauvegardes, en vous assurant que vous pouvez restaurer, par exemple en utilisant duplicity verify .

Je conseillerais négativement une stratégie de sauvegarde basée sur git. Les grandes restaurations prennent beaucoup de temps.


J'ai essayé rsync, mais il ne semble pas pouvoir faire ce que je veux, ou plus probablement, je ne sais pas comment faire pour qu'il le fasse.

Je sais que je pourrais probablement créer un script qui exécute un diff, puis sélectionne les fichiers à sauvegarder en fonction du résultat (ou plus efficacement, obtenez simplement une somme de contrôle et comparez), mais je veux savoir s'il existe un utilitaire qui peut le faire un un peu plus facile :)

rsync est précisément ce programme qui copie sur la base d'un diff. Par défaut, il ne copie que lorsqu'il y a une différence dans l'heure ou la taille de la dernière modification, mais il peut même comparer par somme de contrôle avec -c .

Le problème ici est que vous avez tar 'ing les sauvegardes. Cela devient plus facile si vous ne le faites pas. Je ne sais même pas pourquoi tu fais ça. Cela peut avoir du sens si vous les compressez, mais vous ne le faites même pas.

L'article de Wikipédia sur les sauvegardes incrémentielles contient un exemple rsync commande qui va à peu près :

rsync -va \
  --link-dest="$dst/2020-02-16--05-10-45--testdir/" \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/"

Ce qu'il fait est de lier les fichiers de la sauvegarde précédente lorsqu'ils sont inchangés par rapport à la source. Il y a aussi --copy-dest si vous voulez qu'il copie à la place (c'est encore plus rapide quand $dst est une télécommande ou sur un lecteur plus rapide).

Si vous utilisez un système de fichiers avec des sous-volumes comme btrfs, vous pouvez également prendre un instantané de la sauvegarde précédente avant la synchronisation. Les instantanés sont instantanés et ne prennent pas d'espace supplémentaire[1].

btrfs subvolume snapshot \
  "$dst/2020-02-16--05-10-45--testdir" \
  "$dst/2020-02-17--03-24-16--testdir"

Ou si vous utilisez un système de fichiers qui prend en charge les reflinks, comme ext4, vous pouvez également le faire. Les reflinks sont effectués en créant un nouvel inode mais en se référant aux mêmes blocs que le fichier source, implémentant le support COW. C'est toujours plus rapide que la copie normale car il ne lit ni n'écrit les données, et il ne prend pas non plus d'espace supplémentaire[1].

cp --reflink -av \
  "$dst/2020-02-16--05-10-45--testdir" \
  "$dst/2020-02-17--03-24-16--testdir"

Quoi qu'il en soit, une fois que vous avez fait quelque chose comme ça, vous pouvez simplement faire un rsync normal pour copier les différences :

rsync -va \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/"

Cependant, vous voudrez peut-être ajouter --delete , ce qui entraînerait la suppression par rsync des fichiers de la destination qui ne sont plus présents dans la source.

Une autre option utile est -i ou --itemize-changes . Il produit une sortie succincte et lisible par machine qui décrit les modifications apportées par rsync. J'ajoute normalement cette option et un tuyau comme :

rsync -Pai --delete \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/" \
|& tee -a "$dst/2020-02-17--03-24-16--testdir.log"

pour garder une trace des changements via facilement grep fichiers capables. Le |& est de diriger à la fois stdout et stderr.

Le -P est l'abréviation de --partial et --progress . --partial conserve les fichiers partiellement transférés, mais surtout --progress rapporte la progression de chaque fichier.

Comment cela se compare à l'archivage des modifications avec tar

Les solutions ci-dessus se traduisent par des répertoires qui semblent tout contenir. Même si c'est le cas, au total pour n'importe quelle quantité/fréquence de sauvegardes, elles occuperaient à peu près la même quantité d'espace que d'avoir des archives tar simples avec seulement des changements. C'est à cause du fonctionnement des liens physiques, des liens de référence et des instantanés. L'utilisation de la bande passante lors de la création des sauvegardes serait également la même.

Les avantages sont :

  • les sauvegardes sont faciles à restaurer avec rsync et plus rapides, puisque rsync ne transfère que les différences de la sauvegarde.
  • ils sont plus simples à parcourir et à modifier si nécessaire.
  • les suppressions de fichiers peuvent être encodées naturellement comme l'absence du fichier dans les nouvelles sauvegardes. Lors de l'utilisation d'archives tar, il faudrait recourir à des hacks, comme supprimer un fichier foo , marquez-le foo.DELETED ou faire quelque chose de compliqué. Je n'ai jamais utilisé la duplicité par exemple, mais en regardant sa documentation, il semble qu'il encode les suppressions en ajoutant un fichier vide du même nom dans le nouveau tar et en conservant la signature originale du fichier dans un fichier .sigtar séparé. J'imagine qu'il compare la signature d'origine avec celle d'un fichier vide pour faire la différence entre une suppression de fichier et une modification vers un fichier vide réel.

Si l'on veut toujours configurer chaque sauvegarde comme ne contenant que les fichiers différents (ajoutés ou modifiés), alors on peut utiliser le --link-dest solution décrite ci-dessus, puis supprimez les liens physiques en utilisant quelque chose comme ceci :

find $new_backup -type f ! -links 1 -delete

[1] À proprement parler, ils utilisent de l'espace supplémentaire sous la forme de métadonnées en double, comme le nom de fichier et autres. Cependant, je pense que n'importe qui considérerait cela comme insignifiant.


Et pourquoi n'envisagez-vous pas git lui-même ?

La stratégie que vous décrivez, après une sauvegarde complète et deux sauvegardes incrémentielles, a ses complications lorsque vous continuez. Il est facile de faire des erreurs, et cela peut deviennent très inefficaces, en fonction des changements. Il faudrait qu'il y ait une sorte de rotation, c'est-à-dire que de temps en temps vous faites une nouvelle sauvegarde complète - et ensuite voulez-vous garder l'ancienne ou non ?

Étant donné un fonctionnement dir "testdir" contenant un projet (fichiers et sous-répertoires), git fait par défaut un .git masqué sous-répertoire pour les données. Ce serait pour le contrôle de version local supplémentaire Caractéristiques. Pour la sauvegarde, vous pouvez l'archiver/le copier sur un support ou le cloner via le réseau.

Le contrôle de révision vous obtenez (sans demander) est un effet secondaire du stockage différentiel de git.

Vous pouvez omettre toutes les bifurcations/branches et ainsi de suite. Cela signifie que vous avez une branche appelée "master".

Avant de pouvoir valider (en fait écrire dans l'archive/le dépôt git), vous devez configurer un utilisateur minimal pour le fichier de configuration. Ensuite, vous devez d'abord apprendre et tester dans un sous-répertoire (peut-être tmpfs). Git est parfois aussi compliqué que tar.

Quoi qu'il en soit, comme le dit un commentaire :la sauvegarde est facile, la partie la plus difficile est la restauration.

Les inconvénients de git ne seraient que le petit surcoût / surpuissance.

Les avantages sont :git tracks contenu et noms de fichiers. Il n'enregistre que ce qui est nécessaire, basé sur un diff (pour les fichiers texte au moins).

Exemple

J'ai 3 fichiers dans un répertoire. Après git init , git add . et git commit J'ai un .git 260K dir.

Puis j'ai cp -r .git /tmp/abpic.git (un bon endroit pour enregistrer une sauvegarde :). Je rm le jpg 154K, et aussi modifier un fichier texte. Moi aussi rm -r .git .

  ]# ls
    atext  btext

  ]# git --git-dir=/tmp/abpic.git/ ls-files
    atext
    btext
    pic154k.jpg

Avant de restaurer les fichiers, je peux obtenir les différences précises :

]# git --git-dir=/tmp/abpic.git/ status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   atext
        deleted:    pic154k.jpg

no changes added to commit (use "git add" and/or "git commit -a")

Ici, je veux suivre le git restore indice.

Après git --git-dir=/tmp/abpic.git/ restore \* :

]# ls -st
total 164
  4 atext  156 pic154k.jpg    4 btext

Le jpeg est de retour, et le fichier texte btext n'a pas été mis à jour (conserve l'horodatage). Les modifications en atext sont écrasés.

Pour réunir le référentiel et le répertoire (de travail), vous pouvez simplement le recopier.

]# cp -r /tmp/abpic.git/ .git
]# git status
On branch master
nothing to commit, working tree clean

Les fichiers du répertoire courant sont identiques au .git archive (après le restore ). Les nouvelles modifications seront affichées et pourront être ajoutées et validées, sans aucune planification. Vous n'avez qu'à le stocker sur un autre support, à des fins de sauvegarde.

Après la modification d'un fichier, vous pouvez utiliser status ou diff :

]# echo more >>btext 

]# git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   btext

no changes added to commit (use "git add" and/or "git commit -a")

]# git diff
diff --git a/btext b/btext
index 96b5d76..a4a6c5b 100644
--- a/btext
+++ b/btext
@@ -1,2 +1,3 @@
 This is file b
 second line
+more
#]

Et tout comme git connaît "+more" dans le fichier "btext", il ne stockera également cette ligne que de manière incrémentielle.

Après git add . (ou git add btext ) le status la commande passe du rouge au vert et le commit vous donne les infos.

]# git add .
]# git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   btext

]# git commit -m 'btext: more'
[master fad0453] btext: more
 1 file changed, 1 insertion(+)

Et vous pouvez vraiment accéder au contenu, d'une manière ou d'une autre :

]# git ls-tree @
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf    atext
100644 blob a4a6c5bd3359d84705e5fd01884caa8abd1736d0    btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d    pic154k.jpg

Et puis les 4 premiers chiffres de hachage hexadécimaux

]# git cat-file blob a4a6
This is file b
second line
more

Pour voyager dans le temps d'un commit, c'est :

]# git ls-tree @^
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf    atext
100644 blob 96b5d76c5ee3ccb7e02be421e21c4fb8b96ca2f0    btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d    pic154k.jpg

]# git cat-file blob 96b5
This is file b
second line

Le blob de btext a un hachage différent avant le dernier commit, les autres ont le même.

Un aperçu serait :

]# git log
commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4 (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 10:51:51 2020 +0000

    btext: more

commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date:   Sun Feb 16 08:45:16 2020 +0000

    added 3 files with 'add .'

Au lieu de fichiers tar horodatés manuellement, vous avez des commits avec un message et une date (et un auteur). Les listes de fichiers et leur contenu sont logiquement attachés à ces commits.

git simple est 20 % plus compliqué que tar , mais vous obtenez 50 % de fonctionnalités en plus.

Je voulais faire le troisième changement d'OP:changer un fichier plus deux nouveaux fichiers "image". Je l'ai fait, mais maintenant j'ai :

]# git log
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:56:18 2020 +0000

    didn't add the pics before :(

commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:54:03 2020 +0000

    Two new picture files
    Had to change btext...

commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4
Author: Your Name <[email protected]>
Date:   Sun Feb 16 10:51:51 2020 +0000

    btext: more

commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date:   Sun Feb 16 08:45:16 2020 +0000

    added 3 files with 'add .'
]# 

Alors qu'est-ce que Your Name Guy a fait exactement, dans ses deux commits, peu avant 18h ?

Les détails du dernier commit sont :

]# git show
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:56:18 2020 +0000

    didn't add the pics before :(

diff --git a/picture2 b/picture2
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/picture2
@@ -0,0 +1 @@
+1
diff --git a/picture3 b/picture3
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/picture3
@@ -0,0 +1 @@
+2
]# 

Et pour vérifier l'avant-dernier commit, dont le message annonce deux images :

]# git show @^
commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:54:03 2020 +0000

    Two new picture files
    Had to change btext...

diff --git a/btext b/btext
index a4a6c5b..de7291e 100644
--- a/btext
+++ b/btext
@@ -1,3 +1 @@
-This is file b
-second line
-more
+Completely changed file b
]# 

Cela s'est produit parce que j'ai essayé git commit -a au raccourci git add . , et les deux fichiers étaient nouveaux (non suivi). Il s'affichait en rouge avec git status , mais comme je l'ai dit, git n'est pas moins délicat que tar ou unix.

"Votre débutante sait juste ce dont vous avez besoin, mais je sais ce que vous voulez" (ou l'inverse. Le fait est que ce n'est pas toujours pareil)


Linux
  1. Comment utiliser rsync avancé pour les sauvegardes Linux volumineuses

  2. Comment sauvegarder l'intégralité de votre système Linux à l'aide de Rsync

  3. Apprivoiser la commande tar :conseils pour gérer les sauvegardes sous Linux

  4. FSearch - Un utilitaire de recherche autonome rapide pour Linux

  5. Comment fournir des sauvegardes appropriées pour plusieurs serveurs basés sur Linux ?

Exemples de commandes Linux Rsync pour les débutants

Comment choisir un outil de sauvegarde pour Linux

Comment configurer les sauvegardes pour WHM ?

Comment sauvegarder un hôte Linux distant à l'aide de l'utilitaire rsnapshot rsync

Grsync :outil de sauvegarde graphique rsync dans Ubuntu Linux

Les 15 meilleurs logiciels de sauvegarde pour Linux Desktop