ZFS snapshot auto-destroy onliner
Posted by NiTRo | Filed under ZFS
MAJ 23.05.2013 : Et voici un cas d’usage réel en production.
Tous ceux qui ont eu à affronter un manque d’espace critique sur un zpool se sont au moins une fois posé la question suivante : Pourquoi ZFS n’est il pas capable de supprimer automatiquement les plus anciens snapshot pour libérer de l’espace en cas de besoin ?
La réponse est évidement parce que ce n’est pas (encore) intégré à ZFS mais peut être que le futur principe de “feature flags” (qui remplacera la fameuse “version” de ZFS) facilitera la naissance de cette fonctionnalité tant espérée. En attendant, il y a toujours la bonne vielle crontab toujours très pratique et si on pimente à la sauce oneliner, ça donne quelque chose d’un peu trash mais fonctionnel :
for zpool in `zpool list -H -o name,capacity | sed "s/%//g" | awk '{ if ( $2 > 80 ) { print $1; } }'`; do zfs list -H -o name -t snapshot | grep -E "^$zpool" | head -n $[$(zfs list -H -o name -t snapshot | grep -E "^$zpool"|wc -l) / 5 + 1] | xargs -n1 zfs destroy -R ; done
Ce oneliner détruira récursivement 25% des plus vieux snapshots (+1 pour éviter les cas ou 25% feraient moins d’1 snapshot) d’un zpool si le remplissage dépasse les 80%.
Voici une démo de ce script sur un zpool soumis à remplissage perpétuel (dd en boucle + snapshot toutes les minutes) :
Observations du graphique : jusqu’à 10h nous avons programmé le script toutes les minutes, puis toutes les 5min jusqu’à 15h30, puis nous l’avons désactivé et le zpool sature presque immédiatement après.
Voici l’extrait de la crontab de notre nexenta de test :
* * * * * for zpool in `zpool list -H -o name,capacity | sed "s/\%//g" | awk '{ if ( \$2 > 80 ) { print \$1; } }'`; do zfs list -H -o name -t snapshot | grep -E "^$zpool" | head -n $[$(zfs list -H -o name -t snapshot | grep -E "^$zpool"|wc -l) / 5 + 1] | xargs -n1 zfs destroy -R ; done