Назад | Перейти на главную страницу

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

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

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

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

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

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • Выведите список снимков (только имена) с zfs list -t snapshot -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.

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

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: Труба к голове и возврат только первой строки.

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

zfs destroy zpool1 / dataset @ 20160918% 20161107

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

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

Growse's не работал с 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

Возможно, я решил это с помощью какого-нибудь баш-фу.

 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"

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

Путь для head необходим в 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

Вы также можете проверить zfs-prune-снимки.

Удалите снимки из одного или нескольких zpools, которые соответствуют заданным критериям

Он имеет довольно надежный механизм, основанный на времени, для удаления снимков, пример из документации:

Удалите из пула резервуаров снимки старше двух месяцев, которые заканчиваются строкой "_frequent"

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

Просто хотел узнать, как я это делаю во FreeBSD и OmniOS:

Получите количество снимков:

zfs list -t snapshot -o name | grep ^tank@Auto | wc -l
141

Вычтите число, которое вы хотите оставить на n (например, 30 за месяц последних ежедневных снимков):

zfs list -t snapshot -o name | grep ^tank@Auto |  head -n +111 | xargs -n 1 zfs destroy -vr

Обратите внимание, как я заменил tail с участием head удалять по порядку от самого старого к самому новому, так как нет tac команда на FreeBSD

Это оно! У меня отлично работает ...