ZFS Backup Best Practices

linux
zfs
backup

ZFS Backup Best Practices

ZFS combines a filesystem, a volume manager, and RAID in a single storage stack. Because StateWarden operates at the block/device level, protecting a ZFS-based system means selecting the correct block device as the backup source. This article explains what to back up on ZFS hosts, what a ZVOL backup contains, and which selection mistakes to avoid.


1. ZVOLs vs. Datasets

ZFS exposes two kinds of storage objects:

  • Datasets are filesystem-level objects mounted into the directory tree (for example /tank/home). They contain files and directories and have no block device representation.
  • ZVOLs (ZFS Volumes) are block devices created with zfs create -V. A ZVOL is typically used as a virtual machine disk, as the backing device for an iSCSI LUN, or as a raw volume for a database.

On Linux, each ZVOL appears under two device paths:

  • /dev/zvol/<pool>/<name> - a stable, human-readable symlink (for example /dev/zvol/tank/vm-100).
  • /dev/zd<N> - the underlying kernel block device (for example /dev/zd0).

Identify ZVOLs by their /dev/zvol/... path when configuring backup sources. The path encodes the pool and volume name, so it stays stable across reboots, while zd numbering can change as devices are added or removed. In the Dashboard, ZVOLs appear in the volume list of the device's Storage & Backups tab alongside other block devices.

StateWarden is a block-level backup agent. It protects ZVOLs directly. It cannot capture a mounted dataset (a directory tree such as /tank/home), because a dataset is not a block device. If data that must be protected lives in a dataset, migrate it to a filesystem placed on a ZVOL.

For each backup run on a ZVOL, StateWarden uses native ZFS snapshots to obtain a consistent source. ZFS copy-on-write makes snapshot creation effectively instantaneous and does not pause writes on the storage layer. The backup therefore captures an exact, frozen block-level image of the volume from a single point in time.

What a ZVOL backup gives you:

  • A point-in-time image of the volume content, deduplicated and compressed on the storage node like any other block-level backup.
  • Per-volume restore granularity: you can restore a single ZVOL without touching the rest of the pool.

What it does not give you:

  • Dataset-level file semantics. The backup contains the raw bytes of the block device - that is, the filesystem written inside the ZVOL by the guest or application. It does not contain the pool's dataset hierarchy or ZFS-level metadata.
  • ZFS snapshot history. Local snapshots of the ZVOL are not transferred to the storage node. The backup is a block-level image, not a ZFS replication stream. A restore reproduces the volume as of the backup point, not the local snapshot chain, clones, or ZFS properties such as recordsize or compression.

3. Do Not Back Up Pool Member Disks

Do not add the physical disks that make up a ZFS pool (for example /dev/sdc) to a backup policy. This is the same principle that applies to LVM physical volumes and software RAID members (see LVM Backup Best Practices).

A pool stripes data across its vdevs in transaction groups (TXGs). Backing up individual member disks of a live pool captures each disk at a different transaction group state. On restore, the disks cannot be assembled into a consistent pool, and the result is corruption. Note that ZFS redundancy (mirror, RAIDZ) is an availability mechanism, not a backup: select the ZVOLs, and leave pool member disks unassigned.

4. VM and Database Workloads on ZVOLs

A snapshot-based backup of a ZVOL is crash-consistent: the captured image matches the state you would see after an unexpected power loss. Modern filesystems and databases recover from this state automatically, but crash-consistent is not the same as application-consistent. Buffers held in memory by the application are not part of the image.

For workloads that must be application-consistent, quiesce them around the backup window:

  • Virtual machines: use the hypervisor's guest agent or filesystem freeze mechanism so the guest flushes its filesystems at backup time, and schedule backups during periods of low guest I/O.
  • Databases: coordinate the database's native flush or hot-backup mechanism (for example, a flush-with-read-lock) with the backup schedule, or accept crash consistency and verify it through regular test restores.

The general rule: the storage layer freezes the blocks; making the application state clean at that moment is the workload's responsibility.

5. Compression and Deduplication Interaction

ZFS compression (compression=lz4 and similar) is transparent at the block layer. Reads of a ZVOL return the logical, decompressed content, so the backup pipeline sees the same bytes that the guest or application wrote. Two practical consequences:

  • ZFS compression on the ZVOL neither helps nor hurts backup-side deduplication and compression ratios. Set storage expectations from the workload data itself, not from pool-level compressratio figures.
  • Data that is already compressed or encrypted above the block layer - archives, media files, databases with internal compression, or guest-level disk encryption - reduces deduplication and compression ratios, exactly as on any other volume type.

6. Smart CBT Applicability

Smart CBT on Linux is built on dm-era change tracking and does not apply to ZVOLs. ZVOLs are snapshotted natively for consistency and read in full during backup; storage efficiency comes from block-level deduplication rather than changed-block tracking. The Dashboard reports the CBT state of every volume; see Smart CBT: Incremental Backups for the state indicators and fallback behavior.

7. Summary Checklist

WorkloadBackup sourceVerdict
VM disk on ZFSThe ZVOL, for example /dev/zvol/tank/vm-100Recommended
iSCSI LUN backed by a ZVOLThe backing /dev/zvol/... device on the ZFS hostRecommended
Raw database volumeThe ZVOL, with quiesce as described in Section 4Recommended
Mounted dataset (for example /tank/home)Not a block device; migrate the data to a ZVOL-backed filesystemNot supported
Pool member disk (for example /dev/sdc)None; leave unassignedNever back up individually

Was this article helpful?