OK I am running the following script from cron (snapshot_retention.sh "\-1h" "\-10d" ) every 12 hours on my replication array which appears to be achieving what I want ie retaining 10 days worth of 12 hourly snaps on the replication array but only 48 hours worth of hourly snaps on the primary (the script should also be able able to amend retention on primary array eg to 24 hours of hourly snaps and 4 days of 6 hourly snaps - but I want more testing before I let loose on my primary array)
Comments:
1) I am new to FreeNAS so would appreciate anyone pointing out the errors in my script/logic
2) There is minimal error handling, my biggest concern is that there is no link between actions on primary and replication array eg if replication or cron fails for any reason snapshots will simply roll off the primary array and I won't achieve my 10 day protection. A better solution would be to force all scripts from the primary array such that hourly snapshots are not removed if 12 hourly snaps are not created - I have some ideas on this which I will work through
3) Rather than write my own snapshot deletion routine as per
http://forums.freenas.org/showthrea...imilar-to-Apple-s-TimeMachine&highlight=state I am using autosnap.py. However there is a limitation in this script. It will not delete expired snaps unless it first has a snap to create.
?Freenas Developers - is there a reason for this? Rather than creating a dummy snap on the replication array and linking to cron schedule I have created modified version of autosnap.py with the following lines commented out
4) I wanted to edit name of retained snaps from 'auto' to 'retained' however this would prevent autosnap.py from deleting expired snaps
# Do not proceed further if we are not going to generate any snapshots for this run
if len(mp_to_task_map) == 0:
exit()
My script
cat ./snapshot_retention.sh
#!/bin/sh
# script to be run from cron to retain the oldest snapshot on a replication SAN longer than on the primary array
# Note must not set "Recursively replicate and remove stale snapshot on remote side" on primary SAN as this removes all snapshots on replication array which are not on primary unless keep hold set
# To remove stale snapshots on replicaiton array (which does not have periodic snapshots) need to call modified version of autosnap.py. Modification is to remove the line which exits the routine if no snapshots to create; deletions happen after the creation
# input paramaters $1 = oldretentionperiod (eg "\-2h"), $2 = new retention period (eg "\-2d"), [optional] $3 recurse depth (defaults to 1) and $4 maxsnapstoretain (defaults to 1)
pools="Repl" #list of pools to be processes, space seperated list
datasets="home VM Installs" #list of datasets to be processes, space seperated list
oldretentionperiod=$1 #Original value of Snapshot Retention Period.
newretentionperiod=$2 #Required value of Snapshot Retention Period
recurse=${3:-1} # 1= top level dataset ie no recurse, 2= recurse into 2nd level dataset etc
maxsnapstoretain=${4:-1} # max number of snaps to retain
python /mnt/Repl/modified_autosnap.py # Need to remove stale snapshots before determining which to retain
for pool in $pools
do
for dataset in $datasets
do
snapnum=`zfs list -Hr -o name -s creation -t snapshot -d $recurse $pool/$dataset | wc -l`
if [ $snapnum -gt 1 ] ; then # can't amend LATEST (freenas:state) snapshot else next replication fails
oldsnaps=`zfs list -Hr -o name -s creation -t snapshot -d $recurse $pool/$dataset | grep "$oldretentionperiod" | head -n $maxsnapstoretain`
for snapshot in $oldsnaps
do
if echo $snapshot | grep -q "auto"; then
newsnapname=`echo $snapshot | sed "s/$oldretentionperiod/$newretentionperiod/g"`
zfs rename $snapshot $newsnapname
fi
done
fi
done
done