January 7Jan 7 Hello all,I have enabled snapshots of a number of ZFS datasets. Now I want to monitor the space consumed by the snapshots and adjust the number of monthly snapshots I will keep so as to not run out of space.The command "zfs list -t snapshot" gives me the revelant information for individual snapshots, but I am looking for a way to get the consolidated used space of all snapshots.Thank you.
January 8Jan 8 Community Expert user script plugin cron monthly:https://forums.unraid.net/topic/178033-bmartino1-user-scripts/#findComment-1478664we can even edit it based on sanpshot size... Edited January 8Jan 8 by bmartino1
January 8Jan 8 Community Expert exampls updated script with size storage space restrictions.#!/usr/bin/env bash set -euo pipefail ######################## simple-snapshot-zfs ####################### ###################### User Defined Options ####################### DATASETS=("vm-zfs/Backups") SNAPSHOT_QTY=5 MAX_SNAPSHOT_SPACE="500G" # HARD LIMIT PER DATASET ################################################################## timestamp=$(date "+%Y-%m-%d-%H:%M") echo "Starting Snapshot ${timestamp}" echo "_____________________________________________________________" create_snapshot_if_changed() { local DATASET="$1" local WRITTEN WRITTEN=$(zfs get -H -o value written "${DATASET}") if [[ "${WRITTEN}" != "0" ]]; then local TS TS="$(date '+%Y-%m-%d-%H%M')" zfs snapshot -r "${DATASET}@${TS}" echo "Recursive snapshot created: ${DATASET}@${TS}" else echo "No changes detected in ${DATASET}. No snapshot created." fi } prune_by_count() { local DATASET="$1" local KEEP="${SNAPSHOT_QTY}" mapfile -t SNAPSHOTS < <( zfs list -t snapshot -o name -s creation -r "${DATASET}" | grep "^${DATASET}@" ) local COUNT=${#SNAPSHOTS[@]} echo "Snapshot count for ${DATASET}: ${COUNT}" if (( COUNT > KEEP )); then local TO_DELETE=$((COUNT - KEEP)) for snap in "${SNAPSHOTS[@]:0:${TO_DELETE}}"; do zfs destroy "${snap}" echo "Deleted snapshot (count limit): ${snap}" done fi } prune_by_space() { local DATASET="$1" while true; do local USED USED=$(zfs get -H -o value usedbysnapshots "${DATASET}") echo "Snapshot space used by ${DATASET}: ${USED}" if ! zfs get -H -o value usedbysnapshots "${DATASET}" \ | awk -v max="${MAX_SNAPSHOT_SPACE}" ' BEGIN { exit (system("numfmt --from=iec " $0) > system("numfmt --from=iec " max)) }' then break fi local OLDEST OLDEST=$(zfs list -t snapshot -o name -s creation -r "${DATASET}" | grep "^${DATASET}@" | head -n 1) [[ -z "${OLDEST}" ]] && break zfs destroy "${OLDEST}" echo "Deleted snapshot (space limit): ${OLDEST}" done } for dataset in "${DATASETS[@]}"; do create_snapshot_if_changed "${dataset}" prune_by_count "${dataset}" prune_by_space "${dataset}" echo "_____________________________________________________________" done echo "----------------------------Done!----------------------------" What This Script Now Guarantees✔ Snapshots only created if data changed✔ Snapshot count limit enforced✔ Snapshot space limit enforced✔ Oldest snapshots removed first✔ Fully recursive-safe✔ Uses correct ZFS accounting (usedbysnapshots)Per-snapshot USED is not additive → don’t sum it.The only authoritative metric is:zfs get usedbysnapshots DATASET Edited January 8Jan 8 by bmartino1
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.