klaas1979 / zfs-backup

ZFS backup via zfs send/recv over ssh

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This is a backup script to replicate a ZFS filesystem and its children to
another server via zfs snapshots and zfs send/receive over ssh.  It was
developed on Solaris 10 but should run with minor modification on other
platforms with ZFS support.

It supplements zfs-auto-snapshot, but runs independently.  I prefer that
snapshots continue to be taken even if the backup fails.  It does not
necessarily require that package -- anything that regularly generates
snapshots that follow a given pattern will suffice.


Basic installation: After following the prerequisites, run manually to verify
operation, and then add a line like the following to zfssnap's crontab:
30 * * * * /path/to/zfs-backup.sh
(This for an hourly sync -- adjust accordingly if you only want to back up
daily, etc.)

This aims to be much more robust than the backup functionality of
zfs-auto-snapshot, namely:
* it uses 'zfs send -I' to send all intermediate snapshots (including
  any daily/weekly/etc.), and should still work even if it isn't run
  every hour -- as long as the newest remote snapshot hasn't been
  rotated out locally yet
* 'zfs recv -dF' on the destination host removes any snapshots not
  present locally so you don't have to worry about manually removing
  old snapshots there.

PREREQUISITES:
1. zfs-auto-snapshot package installed locally and at least hourly
   snapshots enabled (or daily, etc.)
2. home directory set for zfssnap role
3. ssh keys set up between zfssnap@localhost and remuser@remhost
4. zfs allow done for remuser on remhost
  (see http://mail.opensolaris.org/pipermail/zfs-auto-snapshot/2009-November/000198.html
  for guidance on #2-4)
5. an initial (full) zfs send/receive done so that remhost has the fs we
   are backing up, and the associated snapshots -- something like:
  zfs send -R $POOL/$FS@zfs-auto-snap_daily-(latest) | ssh $REMUSER@$REMHOST zfs recv -dvF $REMPOOL
6. configure the pool/fs/user/host variables in this script
7. zfs set $PROP={ fullpath | basename } pool/fs
   for each FS or volume you wish to back up.

PROPERTY VALUES:
Given the hierarchy pool/a/b,
* with 'fullpath' (zfs recv -d), this is replicated to backupserver:backuppool/a/b
* with 'basename' (zfs recv -e), this is replicated to backupserver:backuppool/b
  This is useful for replicating a sub-level FS into the top level of the backup pool;
  e.g. pool/backup/foo => backuppool/foo (instead of backuppool/backup/foo)

If this backup is not run for a long enough period that the newest
remote snapshot has been removed locally, manually run an incremental
zfs send/recv to bring it up to date, a la
  zfs send -I zfs-auto-snap_daily-(latest on remote) -R $POOL/$FS@zfs-auto-snap_daily-(latest local) |
      ssh $REMUSER@REMHOST zfs recv -dvF $REMPOOL
It's probably best to do a dry-run first (zfs recv -ndvF).

Note: I use daily snapshots in these manual send/recv examples because
it is less likely that the snapshot you are using will be rotated out
in the middle of a send.  Also, ZFS will send all snapshots for a given
filesystem before sending any for its children.

PROCEDURE:
  * find newest local hourly snapshot
  * find newest remote hourly snapshot (via ssh)
  * check that both $newest_local and $latest_remote snaps exist locally
  * zfs send incremental (-I) from $newest_remote to $latest_local to dsthost
  * if anything fails, set svc to maint. and exit

About

ZFS backup via zfs send/recv over ssh