web-dev-qa-db-fra.com

Comment supprimer tous les instantanés ZFS sauf les derniers [n]?

Je suis actuellement en train de prendre un instantané de mon NAS nocturne et hebdomadaire basé sur ZFS, un processus qui a sauvé mon cul plusieurs fois. Cependant, bien que la création de l'instantané soit automatique (à partir de cron), le la suppression des anciens instantanés est toujours une tâche manuelle. Évidemment, il y a un risque que si je suis frappé par un bus, ou si la tâche manuelle n'est pas exécutée, le NAS manquera d'espace disque) .

Quelqu'un a-t-il de bons moyens/scripts qu'il utilise pour gérer le nombre d'instantanés stockés sur ses systèmes ZFS? Idéalement, je voudrais un script qui répète tous les instantanés d'un système de fichiers ZFS donné et supprime tous les instantanés n sauf le dernier pour ce système de fichiers.

Par exemple. J'ai deux systèmes de fichiers, l'un appelé tank et l'autre appelé sastank. Les instantanés sont nommés avec la date à laquelle ils ont été créés: sastank@AutoD-2011-12-13 donc une simple commande sort devrait les lister dans l'ordre. Je cherche à conserver la valeur des instantanés quotidiens des 2 dernières semaines sur tank, mais uniquement les deux derniers jours des instantanés sur sastank.

27
growse

Vous pouvez trouver quelque chose comme ça un peu plus simple

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • Sortez la liste de l'instantané (noms uniquement) avec zfs list -t snapshot -o name
  • Filtrez pour ne conserver que ceux qui correspondent à tank@Auto avec grep ^tank@Auto
  • Inversez la liste (précédemment triée du plus ancien au plus récent) avec tac
  • Limiter la sortie au 16e résultat le plus ancien et suivre avec tail -n +16
  • Détruisez ensuite avec xargs -n 1 zfs destroy -vr

Supprimer des instantanés dans l'ordre inverse est censé être plus efficace ou trier dans l'ordre inverse de la création.

zfs list -t snapshot -o name -S creation | grep ^tank@Auto | tail -n +16 | xargs -n 1 zfs destroy -vr

Testez-le avec ...|xargs -n 1 echo.

37
user9517

Cas plus général d'obtention de l'instantané le plus récent en fonction de la date de création, pas par nom.

zfs list -H -t snapshot -o name -S creation | head -1

Portée vers un nom de système de fichiers spécifique TestOne

zfs list -H -t snapshot -o name -S creation -d1 TestOne | head -1

-H: Pas d'en-tête, donc la première ligne est un nom de capture instantanée

-t snapshot: Liste des instantanés (la liste peut lister d'autres choses comme les pools et les volumes)

-o name: Affiche la propriété du nom de l'instantané.

-S creation: Majuscule S indique décroissant tri, basé sur le temps de création. Cela place l'instantané le plus récent en première ligne.

-d1 TestOne: Dit inclure les enfants, ce qui semble déroutant mais c'est parce qu'en ce qui concerne cette commande, les instantanés de TestOne sont des enfants. Cela PAS liste les instantanés des volumes dans TestOne tels que TestOne/SubVol@someSnapshot.

| head -1: Pipe to head et retourne uniquement la première ligne.

20
AaronLS

Cela ne répond pas totalement à la question elle-même, mais n'oubliez pas que vous pouvez supprimer des plages d'instantanés.

zfs destroy zpool1/jeu de données @ 20160918% 20161107

Détruirait tous les instantanés de "20160918" à "20161107" inclus. L'une ou l'autre extrémité peut être laissée en blanc, pour signifier "la plus ancienne" ou "la plus récente". Vous pouvez donc préparer quelque chose qui calcule le "n" puis détruire "...% n" ..

Désolé de ressusciter une vieille question.

13
lundman

growse n'a pas fonctionné sur OpenIndiana pour moi. Il ne comprenait pas -0 pour xargs.

Si vous utilisez le tri, sachez qu'il trie par ordre alphabétique, ce qui peut ne pas être souhaité, car vous souhaitez probablement trouver le plus récent.

Voici le code qui supprimera tous les instantanés sauf les derniers.

Supprimez l '"écho" pour aller en direct.

RETENTION=5
FS=tank1/test
SNAPNAME=daily-

zfs list -t snapshot -o name | grep ^$FS@${SNAPNAME} |  sed -n -e :a -e '1,${RETENTION}!{P;N;D;};N;ba' | xargs -n 1 echo zfs destroy -r

Sources: http://sed.sourceforge.net/sed1line.txt

5
Dan Buhler

J'ai peut-être résolu cela avec du bash-fu.

 zfs list -t snapshot -o name | grep ^tank@AutoD- | sort -r | wc -l | xargs -n 1 expr -$NUM_TO_KEEP + | tr -d '\n' | xargs -0 -i bash -c "zfs list -t snapshot -o name | grep ^tank@AutoD- | sort -r | tail -n{} | sort |xargs -t -n 1 zfs destroy -r"

Sensationnel. Ça fait tellement mal.

3
growse

Vous pourriez également vouloir vérifier zfs-Prune-snapshots .

Supprimer des instantanés d'un ou plusieurs zpools qui correspondent à des critères donnés

Il dispose d'un mécanisme basé sur le temps assez robuste pour supprimer les instantanés, un exemple de la documentation:

Supprimez les instantanés de plus de deux mois sur le pool de réservoirs qui se terminent par la chaîne "_frequent"

zfs-Prune-snapshots -s '_frequent' 2M tank

1
DRAD

Le chemin pour la tête est nécessaire sur Solaris, mais devrait fonctionner sans le chemin sur les autres distributions.

retention=14
dataset=vmstorage-17/824

zfs list -rt snap -H -o name ${dataset} | \
/usr/gnu/bin/head -n -${retention} | xargs -n 1 zfs destroy -r
1
Josh Simon