Bagaimana cara menghapus semua kecuali foto ZFS [n] terakhir?

25

Saya saat ini snapshotting NAS berbasis ZFS saya setiap malam dan mingguan, sebuah proses yang telah menyelamatkan pantat saya beberapa kali. Namun, sementara pembuatan snapshot bersifat otomatis (dari cron), penghapusan snapshot lama masih merupakan tugas manual. Jelas ada risiko bahwa jika saya tertabrak bus, atau tugas manual tidak dilakukan, NAS akan kehabisan ruang disk.

Adakah yang punya cara / skrip yang baik yang mereka gunakan untuk mengelola jumlah foto yang disimpan di sistem ZFS mereka? Idealnya, saya ingin script yang iterates melalui semua snapshot untuk ZFS diberikan filesystem dan menghapus semua tapi terakhir n snapshot untuk filesystem itu.

Misalnya saya punya dua filesystem, satu dipanggil tankdan satunya lagi dipanggil sastank. Snapshots dinamai dengan tanggal pembuatannya: sastank@AutoD-2011-12-13jadi sortperintah sederhana harus membuat daftar sesuai urutan. Saya mencari untuk menjaga snapshot harian bernilai 2 minggu terakhir tetap aktif tank, tetapi hanya snapshot senilai dua hari terakhir sastank.

menggeram
sumber

Jawaban:

35

Anda mungkin menemukan hal seperti ini sedikit lebih sederhana

zfs list -t snapshot -o name | grep ^tank@Auto | tac | tail -n +16 | xargs -n 1 zfs destroy -r
  • menampilkan daftar foto (hanya nama) dengan zfs list -t snaphot -o name
  • filter untuk hanya menyimpan yang cocok tank@Autodengangrep ^tank@Auto
  • membalikkan daftar (sebelumnya diurutkan dari yang terlama ke yang terbaru) dengan tac
  • membatasi output ke hasil tertua ke-16 dan diikuti dengan tail -n +16
  • kemudian hancurkan bersama xargs -n 1 zfs destroy -vr

menghapus snapshot dalam urutan terbalik seharusnya lebih efisien.

atau urutkan secara terbalik urutan penciptaan

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

Uji dengan ...|xargs -n 1 echo

tahu
sumber
1
Saya pikir ini perlu sort -rsebelum sedperintah. sedtampaknya menampilkan bagian bawah daftar di luar 15 baris pertama, yang dalam jenis default adalah yang terbaru. Membalik daftar berarti saya mendapatkan snapshot tertua di bagian bawah.
growse
1
Dia menyatakan "menghapus snapshot dalam urutan terbalik seharusnya lebih efisien", demikian urutannya.
tgunr
19

Kasus yang lebih umum tentang mendapatkan snapshot terbaru berdasarkan tanggal pembuatan, bukan dengan nama.

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

Mencakup ke nama sistem file tertentu TestOne

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

-H: Tidak ada tajuk sehingga baris pertama adalah nama snapshot

-t snapshot: Daftar snapshot (daftar dapat mendaftar hal-hal lain seperti kumpulan dan volume)

-o name: Menampilkan properti nama snapshot.

-S creation: Modal Smenunjukkan jenis menurun , berdasarkan waktu pembuatan. Ini menempatkan snapshot terbaru sebagai baris pertama.

-d1 TestOne: Mengatakan termasuk anak-anak, yang tampaknya membingungkan tetapi karena sejauh menyangkut perintah ini, snapshot dari TestOne adalah anak-anak. Ini TIDAK akan mencantumkan snapshot volume dalam TestOne seperti TestOne/SubVol@someSnapshot.

| head -1: Pipa ke kepala dan hanya mengembalikan baris pertama.

AaronLS
sumber
1
Terima kasih untuk -d1. Itulah kunci pertanyaan "Bagaimana saya mendapatkan semua foto untuk dataset yang diberikan?"
Jonathon Reinhart
9

Ini sama sekali tidak menjawab pertanyaan itu sendiri, tetapi jangan lupa Anda dapat menghapus rentang foto.

zfs menghancurkan zpool1 / dataset @ 20160918% 20161107

Akan menghancurkan semua foto dari inklusif "20160918" hingga "20161107". Kedua ujungnya dapat dibiarkan kosong, berarti "tertua" atau "terbaru". Jadi Anda bisa memasak sesuatu yang angka "n" lalu hancurkan "...% n" ..

Maaf menghidupkan kembali pertanyaan lama.

lundman
sumber
1
Ini berfungsi seperti pesona dan 100 kali lebih cepat dari jawaban yang diterima!
NeilWang
5

growse tidak bekerja pada OpenIndiana untukku. Itu tidak mengerti -0 untuk xargs.

Jika menggunakan sortir, ketahuilah bahwa sortir itu abjad yang mungkin tidak diinginkan karena Anda mungkin ingin mencari yang terbaru.

Berikut adalah kode yang akan menghapus semua kecuali snapshot terakhir.

Hapus 'gema' untuk ditayangkan.

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

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

Dan Buhler
sumber
2
Terpilih karena siapa pun yang dapat menggunakan sed seperti itu pantas mendapatkannya.
growse
2
Setelah pembaruan perangkat lunak baru-baru ini, string sed berhenti bekerja untuk saya dan mulai menghapus semua foto! sed buruk! Untungnya server produksi sudah tua dan tetap aman. Saya sekarang menggunakan sed -n -e: a -e '1, $ {RETENTION}! {P; N; D;}; N; ba'
Dan Buhler
Saya belum pernah melihat seseorang yang seperti itu.
Jason
3

Saya mungkin telah memecahkan ini dengan beberapa 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"

Wow. Rasanya sangat salah.

menggeram
sumber
1

Jalur untuk kepala diperlukan di Solaris, tetapi harus bekerja tanpa jalur di distro lain.

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
sumber