В настоящее время я делаю моментальные снимки своего сетевого хранилища на базе ZFS еженедельно и ночью - процесс, который несколько раз спасал мою задницу. Однако, хотя создание снимков происходит автоматически (с помощью cron), удаление старых снимков по-прежнему выполняется вручную. Очевидно, есть риск, что если меня собьет автобус или если ручная задача не будет выполнена, на NAS закончится место на диске.
Есть ли у кого-нибудь хорошие способы / сценарии, которые они используют для управления количеством моментальных снимков, хранящихся на их системах ZFS? В идеале мне бы хотелось получить сценарий, который перебирает все снимки для данной файловой системы ZFS и удаляет все, кроме последних n снимков для этой файловой системы.
Например, у меня есть две файловые системы, одна называется 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 snaphot -o name
tank @ Auto
с grep ^ tank @ Auto
tac
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 -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's не работал на OpenIndiana для меня. Он не понимает -0 для xargs.
При использовании sort имейте в виду, что он сортирует в алфавитном порядке, что может быть нежелательно, поскольку вы, вероятно, хотите найти самые последние.
Вот код, который удалит все, кроме последние снимки.
Удалите «эхо», чтобы начать работу.
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
Путь для головы необходим в 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 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 создание
: заглавная S
обозначает сортировку по убыванию , основанную на времени создания. Это помещает самый последний снимок в первую строку.
-d1 TestOne
: Говорит, что включает детей, что кажется сбивающим с толку, но это связано с тем, что для этой команды снимки TestOne являются дочерними. При этом НЕ будут перечислены снимки томов в TestOne, такие как TestOne /SubVol @ someSnapshot
.
| head -1
: труба к голове и возврат только первой линии.
Это полностью не отвечает на сам вопрос, но не забывайте, что вы можете удалять диапазоны снимков.
zfs destroy zpool1 / dataset @ 20160918% 20161107
Уничтожит все снимки с «20160918» по «20161107» включительно. Любой конец может быть оставлен пустым, что означает «самый старый» или «самый новый». Так что вы можете придумать что-то, что вычисляет "n", а затем уничтожить "...% n" ..
Простите, что воскресил старый вопрос.
Вы также можете посмотреть zfs-prune-snapshots .
Удаление снимков из одного или нескольких 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
для удаления в порядке от самого старого к самому новому, так как во FreeBSD нет команды tac
Вот и все! У меня отлично работает...
Определить два последних моментальных снимка для заданного набора данных (создание, от новых к старым)
zfs_latest=`zfs list -H -t snapshot -o name -S creation | grep ^tank/example_dataset@ | head -2`
Определить ВСЕ снимки для данного набора данных (создание, от новых к старым)
zfs_delete=`zfs list -H -t snapshot -o name -S creation | grep ^tanks/example_dataset@`
Удалить последние снимки из всего набора; создание списка снимков для удаления.
for keep_snap in ${zfs_latest[@]}; do
zfs_delete=( "${zfs_delete[@]/$keep_snap}" );
done
Удалить старые снимки
for snap in ${zfs_delete[@]}; do
zfs destroy ${snap}
done