Rotera ZFS snapshots i FreeBSD

From Peters wiki
Revision as of 14:15, 4 March 2012 by Peter (talk | contribs) (Crontab)
Jump to navigation Jump to search

Denna guide beskriver hur man automatiskt roterar snapshots på ZFS system.

Snapshot skript

Ny version av skriptet som inte kör rename för att rotera snapshots:en:

#!/bin/sh

usage() {
  cat <<EOF
usage: ${0##*/} <label>
  Rotates filesystem snapshots.  If filesystem has the property
  org.freebsd:snap:<label>=<count>, <count> snapshots will be kept
  until the oldest is destroyed when a new one is created.
  The snapshots are named <label>-<timestamp>, where <timestamp>
  is the UTC time in seconds.
EOF
  exit
}

# Default values
: ${PROP:=org.freebsd:snap}

# Parse command line
[ ${#} -ne 1 ] && usage
label=${1}

zfs_destroy_snapshot() {
  # Delete $1 only if classified as snapshot
  [ "$(zfs get -Ho value type "$1" 2>/dev/null)" = "snapshot" ] && zfs destroy "$1"
}

# Iterate over all filesystems with ${PROP}:${label} > 0
zfs list -Ho name,${PROP}:${label} -t filesystem | \
while read name value; do
  [ $value -gt 0 ] 2>/dev/null || continue

  # Iterate over all snapshots, sorted in descending creation order
  # count all matching names, and start delete snapshots
  # when we have reached the limit acoording to the snapshot
  # property
  counter=0
  zfs list -t snapshot -r -d 1 -Ho name,creation -S creation $name | \
  while read snapshot date; do
    if echo $snapshot | grep -q "@${label}" ; then
      counter=$(($counter + 1))
      # If limit is reached, then start delete older snapshots
      if [ $counter -ge $value ]; then
        zfs_destroy_snapshot "${snapshot}"
      fi
    fi
  done
  # Create a new snapshot
  new_snap="${name}@${label}-"$(date "+%Y-%m-%d-%H:%M")
  zfs snapshot "${new_snap}"
done

Skapa följande skript och spara som /root/bin/zfs-autosnap.sh:

#!/bin/sh

usage() {
  cat <<EOF
usage: ${0##*/} <label>
  Rotates filesystem snapshots.  If filesystem has the property
  org.freebsd:snap:<label>=<count>, increments all existing snapshots labeled
  <label>.<num> and creates a new snapshot called <label>.0.  Destroys snapshot
  numbered <label>.<count>.
EOF
  exit
}

# Default values
: ${PROP:=org.freebsd:snap}

# Parse command line
[ ${#} -ne 1 ] && usage
label=${1}

issnap() {
  [ "$(/sbin/zfs get -Ho value type "$1" 2>/dev/null)" = "snapshot" ]
}

# Iterate over all filesystems with ${PROP}:${label} > 0
/sbin/zfs list -Ho name,${PROP}:${label} -t filesystem | \
while read name value; do
  [ $value -gt 0 ] 2>/dev/null || continue

  # Destroy the oldest snapshot
  value=$((${value} - 1))
  snap="${name}@${label}"
  issnap ${snap}.${value} && /sbin/zfs destroy ${snap}.${value}

  # Increment existing snapshots
  while [ ${value} -gt 0 ]; do
    next=$((${value} - 1))
    issnap ${snap}.${next} && /sbin/zfs rename "${snap}.${next}" "${snap}.${value}"
    value=$next
  done

  # Make new snapshot
  /sbin/zfs snapshot ${snap}.0
done

Gör skriptet exekverbart av root:

root # chmod u+x /root/bin/zfs-autosnap.sh

Crontab

För att automatiskt rotera varje timme, dagligen och varje vecka, kör kommandot crontab och lägg till följande rader:

@hourly /root/bin/zfs-autosnap.sh hourly
@daily	/root/bin/zfs-autosnap.sh daily
@weekly /root/bin/zfs-autosnap.sh weekly

Kom ihåg att default PATH för cronjob är:

Template:META Error

Så för att kunna köra kommandon som zfs, krävs att även /usr/sbin finns med i PATH:en.

Rotera snapshots

För att rotera snapshots på ett ZFS filsystem, sätter man egenskapen: org.freebsd:snap:{hourly|daily|weekly}=<count>. Antal snapshots innan rotering, styrs via <count> variabeln. Sätts t.ex. värdet till 7, kommer snapshots 7 st snapshots sparas innan äldre raderas.

Exempel: Skapa snapshots av trunk/home/peter dagligen, spara 7 stycken innan den äldsta raderas:

root # zfs set org.freebsd:snap:daily=7 trunk/home/peter