ZFS and Backups Raw

Backup all datasets and snapshots in a Zpool to an external USB drive. [This person](https://www.ixsystems.com/community/threads/manually-on-demand-replicating-entire-main-pool-to-external-usb-drive-for-physical-offsite-emergency.79804/) has basically the same approach except that they're doing it via manual `cron` job.

_Run all this stuff as `root`_! Get weird errors with zfs not being able to unmount before receiving snapshots :/

```bash
#!/usr/local/bin/bash

export SOURCE_POOL="source"
export DESTINATION_POOL="backup"
export SNAPSHOT_LABEL="manual_monthly_backup"
export SNAPSHOT_LABEL_PREV="${SNAPSHOT_LABEL}_previous"

# --- Initial Backup ---

# First, take a snapshot of the pool to back up
# I have underlying underlying datasets, so make this recursive
zfs snapshot -r "$SOURCE_POOL@$SNAPSHOT_LABEL"

# Initial transfer. `pv` shows progress nicely. We
# are backing up all datasets and their snapshots.
zfs send -R "$SOURCE_POOL@$SNAPSHOT_LABEL" | pv | zfs receive -vF $DESTINATION_POOL

# --- All subsequent backups ---

# Incremental backups! First, rename the old
zfs rename -r $SOURCE_POOL@$SNAPSHOT_LABEL $SOURCE_POOL@$SNAPSHOT_LABEL_PREV

# Take a fresh new snapshot
zfs snapshot -r $SOURCE_POOL@$SNAPSHOT_LABEL

# Send incrementals to the destination. The `-i` flag
# will send the difference between the two arguments to
# the destination.
#
# If all intermediary snapshots are required, use '-I'
zfs send -R -i $SOURCE_POOL@$SNAPSHOT_LABEL_PREV $SOURCE_POOL@$SNAPSHOT_LABEL | pv | zfs receive -vF $DESTINATION_POOL

# Don't need the previous snapshots anymore... clean up
zfs destroy -r $SOURCE_POOL@$SNAPSHOT_LABEL_PREV
zfs destroy -r $DESTINATION_POOL@$SNAPSHOT_LABEL_PREV
```

### `cron` Job

From that forum post up top:

```bash
(
    zfs rename -r mainpool@offsite-backup-new mainpool@offsite-backup-old;
    zfs snapshot -r mainpool@offsite-backup-new;
    zfs send -Ri mainpool@offsite-backup-old mainpool@offsite-backup-new | zfs recv -vFdu usbdrivepool;
    zfs destroy -r mainpool@offsite-backup-old;
    zfs destroy -r usbdrivepool@offsite-backup-old;
) | mail -s "FreeNAS Replication to USB Drive" "myemail@example.com"
```

### Other Notes

I ended up just making a small script that uses `rsync` and snapshots. Sample:

```bash
TIMESTAMP=$(date "+%Y-%m-%dT%H.%M.%S")

zfs snapshot "backup/miscellaneous@$TIMESTAMP"
rsync -avWHh --progress --stats /mnt/orangepool/miscellaneous/ /mnt/backup/miscellaneous/

zfs snapshot "backup/media@$TIMESTAMP"
rsync -avWHh --progress --stats /mnt/orangepool/media/ /mnt/backup/media/
```

Other useful commands:

```bash
# View snapshots for a particular pool
zfs list -t snapshot -r mypool

# View snapshot names only for a given pool (silences the header too)
zfs list -r -t snapshot -o name -H backup

# Rename a snapshot
zfs rename mypool/dataset_foo mypool/dataset_bar
```

Importing and renaming pools:

```bash
# View importable pools
zpool import

# Import a pool
zpool import my-pool

# If you messed up a pool's name, export it...
zpool export my-polo

# ... and import it with the correct name
zpool import my-polo my-pool
```