jimsalterjrs / sanoid

These are policy-driven snapshot management and replication tools which use OpenZFS for underlying next-gen storage. (Btrfs support plans are shelved unless and until btrfs becomes reliable.)
http://www.openoid.net/products/
GNU General Public License v3.0
3.04k stars 299 forks source link
replication snapshot zfs-filesystem

sanoid logo

Sanoid is provided to you completely free and libre, now and in perpetuity, via the GPL v3.0 license. If you find the project useful, please consider either a recurring or one-time donation at Patreon or PayPal—your contributions will support both this project and the Practical ZFS forum.

Sanoid is a policy-driven snapshot management tool for ZFS filesystems. When combined with the Linux KVM hypervisor, you can use it to make your systems functionally immortal via automated snapshot management and over-the-air replication.

sanoid rollback demo
(Real time demo: rolling back a full-scale cryptomalware infection in seconds!)

More prosaically, you can use Sanoid to create, automatically thin, and monitor snapshots and pool health from a single eminently human-readable TOML config file at /etc/sanoid/sanoid.conf. (Sanoid also requires a "defaults" file located at /etc/sanoid/sanoid.defaults.conf, which is not user-editable.) A typical Sanoid system would have a single cron job but see INSTALL.md for more details:

* * * * * TZ=UTC /usr/local/bin/sanoid --cron

Note: Using UTC as timezone is recommended to prevent problems with daylight saving times

And its /etc/sanoid/sanoid.conf might look something like this:

[data/home]
    use_template = production
[data/images]
    use_template = production
    recursive = yes
    process_children_only = yes
[data/images/win7]
    hourly = 4

#############################
# templates below this line #
#############################

[template_production]
        frequently = 0
        hourly = 36
        daily = 30
        monthly = 3
        yearly = 0
        autosnap = yes
        autoprune = yes

Which would be enough to tell sanoid to take and keep 36 hourly snapshots, 30 dailies, 3 monthlies, and no yearlies for all datasets under data/images (but not data/images itself, since process_children_only is set). Except in the case of data/images/win7, which follows the same template (since it's a child of data/images) but only keeps 4 hourlies for whatever reason.

For more full details on sanoid.conf settings see Wiki page.

Note: Be aware that if you don't specify some interval options the defaults will be used (from /etc/sanoid/sanoid.defaults.conf)

Sanoid Command Line Options

Sanoid script hooks

There are three script types which can optionally be executed at various stages in the lifecycle of a snapshot:

pre_snapshot_script

Will be executed before the snapshot(s) of a single dataset are taken. The following environment variables are passed:

Env vars Description
SANOID_SCRIPT The type of script being executed, one of pre, post, or prune. Allows for one script to be used for multiple tasks
SANOID_TARGET DEPRECATED The dataset about to be snapshot (only the first dataset will be provided)
SANOID_TARGETS Comma separated list of all datasets to be snapshotted (currently only a single dataset, multiple datasets will be possible later with atomic groups)
SANOID_SNAPNAME DEPRECATED The name of the snapshot that will be taken (only the first name will be provided, does not include the dataset name)
SANOID_SNAPNAMES Comma separated list of all snapshot names that will be taken (does not include the dataset name)
SANOID_TYPES Comma separated list of all snapshot types to be taken (yearly, monthly, weekly, daily, hourly, frequently)

If the script returns a non-zero exit code, the snapshot(s) will not be taken unless no_inconsistent_snapshot is false.

post_snapshot_script

Will be executed when:

Env vars Description
SANOID_SCRIPT as above
SANOID_TARGET DEPRECATED as above
SANOID_TARGETS as above
SANOID_SNAPNAME DEPRECATED as above
SANOID_SNAPNAMES as above
SANOID_TYPES as above
SANOID_PRE_FAILURE This will indicate if the pre-snapshot script failed

pruning_script

Will be executed after a snapshot is successfully deleted. The following environment variables will be passed:

Env vars Description
SANOID_SCRIPT as above
SANOID_TARGET as above
SANOID_SNAPNAME as above

example

sanoid.conf:

...
[sanoid-test-0]
    use_template = production
    recursive = yes
    pre_snapshot_script = /tmp/debug.sh
    post_snapshot_script = /tmp/debug.sh
    pruning_script = /tmp/debug.sh
...

verbose sanoid output:

...
executing pre_snapshot_script '/tmp/debug.sh' on dataset 'sanoid-test-0'
taking snapshot sanoid-test-0@autosnap_2020-02-12_14:49:33_yearly
taking snapshot sanoid-test-0@autosnap_2020-02-12_14:49:33_monthly
taking snapshot sanoid-test-0@autosnap_2020-02-12_14:49:33_daily
taking snapshot sanoid-test-0@autosnap_2020-02-12_14:49:33_hourly
executing post_snapshot_script '/tmp/debug.sh' on dataset 'sanoid-test-0'
...

pre script env variables:

SANOID_SCRIPT=pre
SANOID_TARGET=sanoid-test-0/b/bb
SANOID_TARGETS=sanoid-test-0/b/bb
SANOID_SNAPNAME=autosnap_2020-02-12_14:49:32_yearly
SANOID_SNAPNAMES=autosnap_2020-02-12_14:49:32_yearly,autosnap_2020-02-12_14:49:32_monthly,autosnap_2020-02-12_14:49:32_daily,autosnap_2020-02-12_14:49:32_hourly
SANOID_TYPES=yearly,monthly,daily,hourly

post script env variables:

SANOID_SCRIPT=post
SANOID_TARGET=sanoid-test-0/b/bb
SANOID_TARGETS=sanoid-test-0/b/bb
SANOID_SNAPNAME=autosnap_2020-02-12_14:49:32_yearly
SANOID_SNAPNAMES=autosnap_2020-02-12_14:49:32_yearly,autosnap_2020-02-12_14:49:32_monthly,autosnap_2020-02-12_14:49:32_daily,autosnap_2020-02-12_14:49:32_hourly
SANOID_TYPES=yearly,monthly,daily,hourly
SANOID_PRE_FAILURE=0

Syncoid

Sanoid also includes a replication tool, syncoid, which facilitates the asynchronous incremental replication of ZFS filesystems. A typical syncoid command might look like this:

syncoid data/images/vm backup/images/vm

Which would replicate the specified ZFS filesystem (aka dataset) from the data pool to the backup pool on the local system, or

syncoid data/images/vm root@remotehost:backup/images/vm

Which would push-replicate the specified ZFS filesystem from the local host to remotehost over an SSH tunnel, or

syncoid root@remotehost:data/images/vm backup/images/vm

Which would pull-replicate the filesystem from the remote host to the local system over an SSH tunnel.

Syncoid supports recursive replication (replication of a dataset and all its child datasets) and uses mbuffer buffering, lzop compression, and pv progress bars if the utilities are available on the systems used. If ZFS supports resumable send/receive streams on both the source and target those will be enabled as default.

As of 1.4.18, syncoid also automatically supports and enables resume of interrupted replication when both source and target support this feature.

Syncoid Dataset Properties
Syncoid Command Line Options

Note that the sync snapshots syncoid creates are not atomic in a global context: sync snapshots of pool/dataset1 and pool/dataset2 will each be internally consistent, but one may be a few filesystem transactions "newer" than the other. (This does not affect the consistency of snapshots already taken in other ways, which syncoid replicates in the overall stream unless --no-stream is specified. So if you want to manually zfs snapshot -R pool@1 before replicating with syncoid, the global atomicity of pool/dataset1@1 and pool/dataset2@1 will still be intact.)