Как удалить все, кроме последних [n] снимков ZFS?

25

В настоящее время я делаю снимки своего ночного и еженедельного сетевого хранилища на базе ZFS, и этот процесс несколько раз спас мою задницу. Однако, хотя создание снимка происходит автоматически (из cron), удаление старых снимков остается ручным заданием. Очевидно, существует риск того, что, если меня ударит автобус, или ручное задание не будет выполнено, в NAS не хватит места на диске.

Есть ли у кого-нибудь хорошие способы / сценарии, которые они используют для управления количеством снимков, хранящихся в их системах ZFS? В идеале я хотел бы сценарий, который повторяет все снимки для данной файловой системы ZFS и удаляет все, кроме последних n снимков для этой файловой системы.

Например, у меня есть две файловые системы, одна называется, tankа другая называется sastank. Снимки именуются по дате их создания, sastank@AutoD-2011-12-13поэтому простая sortкоманда должна перечислить их по порядку. Я хочу сохранить ежедневные снимки за последние 2 недели tank, но только снимки за последние два дня sastank.

growse
источник

Ответы:

35

Вы можете найти что-то вроде этого немного проще

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • вывести список снимков (только имена) с zfs list -t snaphot -o name
  • фильтр , чтобы оставить только те , которые соответствуют tank@Autoсgrep ^tank@Auto
  • перевернуть список (ранее отсортированный от самого старого к новому) с tac
  • ограничить вывод 16-м самым старым результатом и следовать с tail -n +16
  • затем уничтожить с xargs -n 1 zfs destroy -vr

удаление снимков в обратном порядке предположительно более эффективно.

или отсортировать в обратном порядке создания

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

Проверьте это с ...|xargs -n 1 echo

dnozay
источник
1
Я думаю, что это нужно sort -rперед sedкомандой. sedкажется, выводит нижнюю часть списка за первые 15 строк, которые в сортировке по умолчанию являются самыми последними. Пролистывание списка означает, что я получаю самые старые снимки внизу.
Growse
1
Он заявил, что «удаление снимков в обратном порядке предположительно более эффективно», то есть порядок сортировки.
tgunr
19

Более общий случай получения последнего снимка на основе даты создания, а не по имени.

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

Области до определенного имени файловой системы TestOne

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

-H: Заголовок отсутствует, поэтому первая строка является именем снимка

-t snapshot: Список снимков (список может перечислять другие вещи, такие как пулы и тома)

-o name: Показать свойство имени снимка.

-S creation: Капитал Sобозначает нисходящий вид, основанный на времени создания. Это помещает самый последний снимок в качестве первой строки.

-d1 TestOneГоворят, включают в себя дочерние элементы, что кажется странным, но это потому, что для этой команды снимки TestOne являются дочерними. Это НЕ будет перечислять снимки томов в TestOne, такие как TestOne/SubVol@someSnapshot.

| head -1: Труба к голове и только возврат первой линии.

AaronLS
источник
1
Спасибо за -d1. Это был ключ к вопросу "Как получить все снимки для данного набора данных?"
Джонатон Рейнхарт
9

Это полностью не отвечает самому вопросу, но не забывайте, что вы можете удалять диапазоны снимков.

zfs уничтожить zpool1 / набор данных @ 20160918% 20161107

Уничтожит все снимки с «20160918» до «20161107» включительно. Любой конец может быть оставлен пустым, что означает «самый старый» или «самый новый». Таким образом, вы можете приготовить что-нибудь, что вычислит "n", а затем уничтожить "...% n" ..

Извините, что воскресил старый вопрос.

lundman
источник
1
Это работает как шарм и в 100 раз быстрее, чем принятый ответ!
НилВанг
5

Growse не работает на OpenIndiana для меня. Он не понял -0 для xargs.

При использовании сортировки помните, что она сортирует по алфавиту, что может быть нежелательно, так как вы, вероятно, хотите найти самые последние.

Вот код, который удалит все, кроме последних снимков.

Удалите «эхо», чтобы начать жить.

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

Источники: http://sed.sourceforge.net/sed1line.txt

Дэн Бюлер
источник
2
Upvote, потому что любой, кто может использовать sed таким образом, заслуживает этого.
Growse
2
После недавнего обновления программного обеспечения эта строка sed перестала работать для меня, и он начал удалять все снимки! плохой сед! К счастью, производственный сервер был стар и оставался в безопасности. Теперь я использую sed -n -e: a -e '1, $ {RETENTION}! {P; N; D;}; N; ba'
Дэн Бюлер
Я никогда не видел никого такого САС.
Джейсон
3

Возможно, я решил это с некоторой баш-фу.

 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"

Вау. Это так неправильно.

growse
источник
1

Путь к голове необходим в Solaris, но должен работать без пути в других дистрибутивах.

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
Джош Саймон
источник