Como excluir todos os snapshots do ZFS, exceto os últimos [n]?

24

Atualmente, estou capturando instantaneamente meu NAS baseado em ZFS todas as noites e semanalmente, um processo que me salvou algumas vezes. No entanto, enquanto a criação do instantâneo é automática (do cron), a exclusão de instantâneos antigos ainda é uma tarefa manual. Obviamente, existe o risco de que, se eu for atropelado por um barramento, ou a tarefa manual não for realizada, o NAS ficará sem espaço em disco.

Alguém tem boas maneiras / scripts que eles usam para gerenciar o número de snapshots armazenados em seus sistemas ZFS? Idealmente, eu gostaria de um script que itere através de todos os instantâneos para um determinado sistema de arquivos ZFS e exclua todos, exceto os últimos n instantâneos para esse sistema de arquivos.

Por exemplo, eu tenho dois sistemas de arquivos, um chamado tanke outro chamado sastank. Os instantâneos são nomeados com a data em que foram criados: sastank@AutoD-2011-12-13portanto, um sortcomando simples deve listá-los em ordem. Estou procurando manter as últimas 2 semanas em instantâneos diários tank, mas apenas os últimos dois dias em instantâneos sastank.

crescer
fonte

Respostas:

35

Você pode achar algo assim um pouco mais simples

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • envie a lista de instantâneos (apenas nomes) com zfs list -t snaphot -o name
  • filtro para manter apenas os que combinam tank@Autocomgrep ^tank@Auto
  • inverter a lista (classificada anteriormente do mais antigo para o mais recente) com tac
  • limitar a saída ao 16º resultado mais antigo e seguir com tail -n +16
  • então destrua com xargs -n 1 zfs destroy -vr

excluir instantâneos na ordem inversa é supostamente mais eficiente.

ou classificar na ordem inversa da criação

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

Teste com ...|xargs -n 1 echo

dnozay
fonte
1
Eu acho que isso precisa de um sort -rantes do sedcomando. sedparece exibir o final da lista além das 15 primeiras linhas, que na classificação padrão é a mais recente. Virar a lista significa que recebo os instantâneos mais antigos na parte inferior.
growse
1
Ele afirmou que "excluir instantâneos na ordem inversa é supostamente mais eficiente", portanto, a ordem de classificação.
tgunr
19

Caso mais geral de obtenção do instantâneo mais recente com base na data de criação, não pelo nome.

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

Escopo para um nome de sistema de arquivos específico TestOne

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

-H: Sem cabeçalho para que a primeira linha seja um nome de captura instantânea

-t snapshot: Listar instantâneos (a lista pode listar outras coisas, como conjuntos e volumes)

-o name: Exibe a propriedade do nome da captura instantânea.

-S creation: Capital Sindica classificação decrescente , com base no tempo de criação. Isso coloca o instantâneo mais recente como a primeira linha.

-d1 TestOne: Diz incluir filhos, o que parece confuso, mas é porque, no que diz respeito a este comando, os instantâneos do TestOne são filhos. Isso NÃO listará instantâneos de volumes no TestOne, como TestOne/SubVol@someSnapshot.

| head -1: Tubo na cabeça e retornar apenas a primeira linha.

AaronLS
fonte
1
Obrigado pelo -d1. Essa foi a chave da pergunta "Como obtenho todos os instantâneos para um determinado conjunto de dados?"
Jonathon Reinhart
8

Isso totalmente não responde à pergunta em si, mas não esqueça que você pode excluir intervalos de instantâneos.

O zfs destrói o zpool1 / conjunto de dados @ 20160918% 20161107

Destruiria todos os instantâneos de "20160918" a "20161107", inclusive. Qualquer extremidade pode ser deixada em branco, para significar "mais antiga" ou "mais nova". Então você pode preparar algo que descubra o "n" e destrua "...% n" ..

Desculpe ressuscitar uma pergunta antiga.

lundman
fonte
Isso funciona como charme e 100 vezes mais rápido que a resposta aceita!
NeilWang 18/09
5

growse não funcionou no OpenIndiana para mim. Não entendeu -0 para xargs.

Se estiver usando a classificação, lembre-se de que classifica em ordem alfabética, o que pode não ser o desejado, pois você provavelmente deseja encontrar as mais recentes.

Aqui está o código que excluirá todos, exceto os últimos instantâneos.

Remova o 'eco' para entrar no ar.

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

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

Dan Buhler
fonte
2
Voto positivo porque quem pode usar o sed assim merece isso.
growse
2
Após uma atualização recente do software, essa sequência sed parou de funcionar para mim e começou a excluir todos os instantâneos! mau sed! Felizmente, o servidor de produção era antigo e permanecia seguro. Agora eu uso sed -n -e: a -e '1, $ {RETENTION}! {P; N; D;}; N; ba' #
49530 Dan Buhler
Eu nunca vi ninguém do SED assim.
Jason
3

Eu posso ter resolvido isso com algum 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"

Uau. Parece tão errado.

crescer
fonte
1

O caminho para a cabeça é necessário no Solaris, mas deve funcionar sem o caminho em outras distros.

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
fonte