ZFS snapshot of MySQL in Docker
I wrote this script to backup Linux servers running MySQL among other things in Docker on top of the ZFS filesystem. It does the following things in sequence:
- locks all databases
- snapshots all volumes
- unlocks databases
- rsyncs over the latest snapshot
It always creates the same snapshot because I use it in tandem with
zfs-auto-snapshot so this is mostly for syncing the snapshots to my NAS which does its own snapshotting.
One requirement for this setup is to have password-less authentication in the form of public key authentication between the current user on the system to backup and the target system.
#!/bin/bash # Stop on error set -e # Debugging # set -v # Docker containers running MySQL MYSQL_CONTAINERS=( my_mysql_1 my_other_mysql_1 ) TARGET_HOST=your-target-backup.horse TARGET_USER=server-backup TARGET_PORT=22 TARGET_PATH=/backup/of/your-server # For snapshotting ROOT_VOLUME=tank SNAPSHOT_NAME=sync-backup # Destroy the snapshots (fails on first run, so ignore status code) /usr/sbin/zfs destroy -r [email protected]$SNAPSHOT_NAME || true # Lock databases for backup for cont in $MYSQL_CONTAINERS do /usr/bin/docker exec $cont bash -c "MYSQL_PWD=\$MYSQL_ROOT_PASSWORD mysql -uroot -e \"flush tables with read lock;\"" done # Snapshot /usr/sbin/zfs snap -r [email protected]$SNAPSHOT_NAME # Unlock databases for cont in $MYSQL_CONTAINERS do /usr/bin/docker exec $cont bash -c "MYSQL_PWD=\$MYSQL_ROOT_PASSWORD mysql -uroot -e \"unlock tables;\"" done # List all volumes to backup VOLUMES=$(/usr/sbin/zfs list -r -o mountpoint $ROOT_VOLUME | grep /) # Iterate over all volumes to sync them for vol in $VOLUMES do # `remslash` is volume name where / is replaced with - remslash=$(echo $vol | cut -c 2- | sed 's#/#-#g') rsync -e "ssh -p $TARGET_PORT" --delete-after -az "$vol/.zfs/snapshot/$SNAPSHOT_NAME/" "[email protected]$TARGET_HOST:$TARGET_PATH/$remslash" done
If you read through the code, you'll find that I am replacing the
pool-volume-subvolume to circumvent rsync's
--delete-after. I am using
rsync because my NAS is running btrfs instead of
ZFS. If I was running the same filesystem on both systems, I could basically stream over the snapshots. A very cool feature, but I am happy with my Synology NAS and it does not support ZFS.