Skip to content

Instantly share code, notes, and snippets.

@openfirmware
Created December 13, 2016 17:31
Show Gist options
  • Save openfirmware/902560756224383041de32f823ee5ba9 to your computer and use it in GitHub Desktop.
Save openfirmware/902560756224383041de32f823ee5ba9 to your computer and use it in GitHub Desktop.
Snapshot and backup a ZFS filesystem to a secondary pool

ZFS Backup Script

I use this script to backup a ZFS filesystem used for PostgreSQL and OpenStreetMap data. The script creates a new snapshot with the current date (YYYY-MM-DD), estimates the size between this snapshot and the previous snapshot, then transfers the snapshot to a secondary backup pool using ZFS send. The progress of the transfer is displayed with pv.

This script will not destroy snapshots. It will print out the destroy command if you want to remove the old snapshot from the primary pool to free up space.

This was created for ZFS on Linux; BSD users may have to replace some of the tools.

Requirements

License

MIT License

Authors

James Badger ([email protected])

#!/bin/bash
set -e
base="data/postgresql"
receive_pool="work"
now=$(date "+%Y-%m-%d")
zfs snapshot "$base@$now"
snapshots=$(zfs list -t snapshot -s name -H | grep "$base" | awk '{ print $1 }')
previous=""
current="$base@$now"
for snapshot in $snapshots; do
if [[ "$snapshot" == "$current" ]]; then
break
else
previous=$snapshot
fi
done
if [[ "$previous" == "" ]]; then
echo "Previous snapshot not found."
exit 1
fi
size=$(zfs send -nvDLepP -i "$previous" "$current" | awk '/^size/{ print $2 }')
human_size=$(numfmt --to=iec-i --suffix=B $size)
echo "Backup is estimated to be $human_size"
zfs send -DLep -i "$previous" "$current" | pv -s ${size} | zfs receive -F -d $receive_pool
echo "Run this yourself:"
echo "zfs destroy $previous"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment