¿Cómo borrar todas las instantáneas de ZFS excepto las últimas?

25

Actualmente estoy tomando instantáneas de mi NAS basado en ZFS todas las noches y semanalmente, un proceso que me ha salvado el culo varias veces. Sin embargo, aunque la creación de la instantánea es automática (desde cron), la eliminación de instantáneas antiguas sigue siendo una tarea manual. Obviamente, existe el riesgo de que si me atropella un autobús o no se realiza la tarea manual, el NAS se quedará sin espacio en disco.

¿Alguien tiene buenas formas / scripts que usan para administrar la cantidad de instantáneas almacenadas en sus sistemas ZFS? Idealmente, me gustaría un script que repita todas las instantáneas para un sistema de archivos ZFS determinado y elimine todas las últimas instantáneas n para ese sistema de archivos.

Por ejemplo, tengo dos sistemas de archivos, uno llamado tanky otro llamado sastank. Las instantáneas se nombran con la fecha en que se crearon: sastank@AutoD-2011-12-13por lo tanto, un sortcomando simple debe enumerarlas en orden. Estoy buscando mantener las últimas 2 semanas de instantáneas diarias tank, pero solo los últimos dos días de instantáneas sastank.

crecer
fuente

Respuestas:

35

Puede encontrar algo como esto un poco más simple

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • generar la lista de instantáneas (solo nombres) con zfs list -t snaphot -o name
  • filtrar para mantener solo los que coinciden tank@Autocongrep ^tank@Auto
  • invertir la lista (previamente ordenada de la más antigua a la más nueva) con tac
  • Limite la salida al resultado número 16 más antiguo y siga con tail -n +16
  • luego destruir con xargs -n 1 zfs destroy -vr

Suprimir instantáneas en orden inverso es supuestamente más eficiente.

o ordenar en orden inverso de creación

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

Pruébalo con ...|xargs -n 1 echo

dnozay
fuente
1
Creo que esto necesita un sort -rantes del sedcomando. sedparece salir al final de la lista más allá de las primeras 15 líneas, que en el orden predeterminado es la más reciente. Voltear la lista significa que obtengo las instantáneas más antiguas en la parte inferior.
growse
1
Afirmó que "eliminar instantáneas en orden inverso es supuestamente más eficiente", por lo tanto, el orden de clasificación.
Jueves
19

Caso más general de obtener la instantánea más reciente basada en la fecha de creación, no por nombre.

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

Alcanzado a un nombre de sistema de archivos específico TestOne

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

-H: Sin encabezado, por lo que la primera línea es un nombre de instantánea

-t snapshot: Lista de instantáneas (la lista puede enumerar otras cosas como grupos y volúmenes)

-o name: Muestra la propiedad del nombre de la instantánea.

-S creation: Capital Sdenota orden descendente , basado en el tiempo de creación. Esto coloca la instantánea más reciente como la primera línea.

-d1 TestOne: Dice incluir niños, lo que parece confuso pero es porque, en lo que respecta a este comando, las instantáneas de TestOne son niños. Esto NO listará instantáneas de volúmenes dentro de TestOne como TestOne/SubVol@someSnapshot.

| head -1: Canalice a la cabeza y solo regrese la primera línea.

AaronLS
fuente
1
Gracias por el -d1. Esa fue la clave de la pregunta "¿Cómo obtengo todas las instantáneas para un conjunto de datos dado?"
Jonathon Reinhart
9

Esto no responde totalmente a la pregunta en sí, pero no olvide que puede eliminar rangos de instantáneas.

zfs destruye zpool1 / conjunto de datos @ 20160918% 20161107

Destruiría todas las instantáneas desde "20160918" hasta "20161107" inclusive. Cualquiera de los dos extremos puede dejarse en blanco para significar "más antiguo" o "más nuevo". Entonces podrías cocinar algo que descubra la "n" y luego destruir "...% n" ...

Lamento resucitar una vieja pregunta.

lundman
fuente
1
¡Esto funciona de maravilla y 100 veces más rápido que la respuesta aceptada!
NeilWang
5

growse's no funcionó en OpenIndiana para mí. No entendió -0 para xargs.

Si usa sort, tenga en cuenta que ordena alfabéticamente lo que puede no ser deseado, ya que probablemente desee encontrar el más reciente.

Aquí hay un código que eliminará todas las instantáneas excepto las últimas.

Elimina el 'eco' para ir a vivir.

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

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

Dan Buhler
fuente
2
Vota porque cualquiera que pueda usar sed así se lo merece.
growse
2
Después de una actualización de software reciente, ¡esa cadena sed dejó de funcionar para mí y comenzó a eliminar todas las instantáneas! mal sed! Afortunadamente, el servidor de producción era viejo y se mantenía a salvo. Ahora uso sed -n -e: a -e '1, $ {RETENTION}! {P; N; D;}; N; ba'
Dan Buhler
Nunca he visto a nadie SED así.
Jason
3

Puede que haya resuelto esto con un poco de 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"

Guau. Se siente tan mal.

crecer
fuente
1

La ruta para head es necesaria en Solaris, pero debería funcionar sin la ruta en otras distribuciones.

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
Josh Simon
fuente