2013年2月15日金曜日

zfs のオートスナップショット

Solaris ならば、定期的にスナップショットを取ってくれる機能がついています。

ZFS on Linux を使っていている時に、同じようなことをやりたいな、と思って超簡単なシェルスクリプトを書いてみました。

かなり、やっつけなので、どなたかもっといい感じに書き直してください。


定期的にジョブを実行するのには、crond を使用します。

/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthy/

の下に放り込めばよいです。
hourly より細かいスケジュールを組みたい場合は /etc/crontab
に直接記載します。

以下は、 /rpool/share と /rpool/home の下を定期的にバックアップをとっている場合です。


●/etc/crontab に追加する内容

10  *  *  *  *  root     /usr/local/sbin/zfs-autosnap frequent
20  *  *  *  *  root     /usr/local/sbin/zfs-autosnap frequent
30  *  *  *  *  root     /usr/local/sbin/zfs-autosnap frequent
40  *  *  *  *  root     /usr/local/sbin/zfs-autosnap frequent
50  *  *  *  *  root     /usr/local/sbin/zfs-autosnap frequent

● /etc/cron.hourly/zfs-autosnap-hourly の内容
#!/bin/sh

if [ -x /usr/local/sbin/zfs-autosnap ]; then
        /usr/local/sbin/zfs-autosnap hourly
fi

exit 0

● /etc/cron.daily/zfs-autosnap-dailyの内容

#!/bin/sh

if [ -x /usr/local/sbin/zfs-autosnap ]; then
        /usr/local/sbin/zfs-autosnap daily
fi

exit 0

●/etc/cron.weekly/zfs-autosnap-weekly の内容


#!/bin/sh

if [ -x /usr/local/sbin/zfs-autosnap ]; then
        /usr/local/sbin/zfs-autosnap weekly
fi

exit 0

●/etc/cron.monthly/zfs-autosnap-monthly の内容

#!/bin/sh

if [ -x /usr/local/sbin/zfs-autosnap ]; then
        /usr/local/sbin/zfs-autosnap monthly
fi

exit 0

● /usr/local/sbin/zfs-autosnap の内容

#!/bin/sh

date=`date +%Y-%m-%d-%Hh%M`

snapname=zfs-auto-snap_$1-$date


for fs in rpool/share rpool/home
do
        zfs snapshot -r $fs@$snapname
done

if [ -x /usr/local/sbin/zfs-autosnap-cleanup ]; then
    /usr/local/sbin/zfs-autosnap-cleanup $1
fi

exit 0

●/usr/local/sbin/zfs-autosnap-cleanup の内容

#!/bin/sh

frequency=$1

case $frequency in
    frequent) max=6;;
    hourly)   max=24;;
    daily)    max=7;;
    weekly)   max=4;;
    monthly)  max=12;;
    *)        max=999;;
esac

for fs in rpool/home rpool/share
do
    snapshots=$(zfs list -t snapshot | sed -n "s|$fs@\(zfs-auto-snap_$frequency-[^[:blank:]]*\).*|\1|p" | sort)
    nr_snapshots=$(echo $snapshots | wc -w)

    set $snapshots

    while [ $nr_snapshots -gt $max ]
    do
        zfs destroy -r "$fs@$1"
        nr_snapshots=$(( $nr_snapshots - 1 ))
        shift
    done

done

exit 0
のようになっています。

frequently は 10分おきに 6個まで
hourly は 1時間おきに24個まで
daily は1日おきに7個まで
weekly は1週おきに 4個まで
monthly は1ヶ月おきに 12個まで
スナップショットを取っています。
それ以上の数になると、古いものから消えていきます。


スナップショットを表示されると以下のような感じです。

# zfs list -t snapshot

(中略)

rpool/share@zfs-auto-snap_monthly-2013-01-17-03h22                0      -  20.5G  -
rpool/share@zfs-auto-snap_weekly-2013-01-21-03h04                 0      -  20.5G  -
rpool/share@zfs-auto-snap_weekly-2013-01-28-04h00             98.6K      -  20.5G  -
rpool/share@zfs-auto-snap_weekly-2013-02-04-03h26                 0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-09-03h19                  0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-10-03h21                  0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-11-03h35                  0      -  20.5G  -
rpool/share@zfs-auto-snap_weekly-2013-02-11-03h55                 0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-12-03h21                  0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-13-03h23                  0      -  20.5G  -
rpool/share@zfs-auto-snap_monthly-2013-02-14-03h11                0      -  20.5G  -
rpool/share@zfs-auto-snap_daily-2013-02-14-04h49                  0      -  20.5G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-14h01                 0      -  20.5G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-15h01                 0      -  20.5G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-16h01                 0      -  20.5G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-17h01                 0      -  20.5G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-18h01              125K      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-19h01             32.0K      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-20h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-21h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-22h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-14-23h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-00h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-01h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-02h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-03h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_daily-2013-02-15-03h41                  0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-04h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-05h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-06h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-07h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-08h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-09h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-10h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-11h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-11h50               0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-12h01                 0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-12h10               0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-12h20               0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-12h30               0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-12h40               0      -  40.3G  -
rpool/share@zfs-auto-snap_frequent-2013-02-15-12h50               0      -  40.3G  -
rpool/share@zfs-auto-snap_hourly-2013-02-15-13h01                 0      -  40.3G  -