Part 2 · 1 chapters · ~8 min

btrfs and ZFS

Copy-on-write B-trees, atomic root updates, snapshots and clones, send and receive, end-to-end checksums and scrubs, ZFS pools, vdevs, ARC cache and ZIL, btrfs subvolumes and RAID profiles, compression and deduplication, and running databases on copy-on-write file systems (recordsize, nodatacow).

4

Snapshots, checksums, pools

code
# ZFS: a mirrored pool, a dataset tuned for Postgres, snapshots and replication
zpool create tank mirror /dev/nvme1n1 /dev/nvme2n1
zfs create -o recordsize=8K -o compression=lz4 -o atime=off tank/pg      # match Postgres 8 KB pages
zfs snapshot tank/pg@before-migration                                      # instant
zfs send -i tank/pg@mon tank/pg@tue | ssh backup zfs recv pool/pg          # incremental replication
zpool scrub tank && zpool status -v                                       # checksum errors found and repaired

# btrfs: subvolumes and snapshots
btrfs subvolume create /data/app
btrfs subvolume snapshot -r /data/app /data/.snap/app-2026-10-07
chattr +C /data/pg        # disable copy-on-write for a database directory (also disables checksums there)

Databases on CoW: random in-place updates fragment copy-on-write files and amplify writes. Match recordsize to the database page size on ZFS, or disable CoW for the data directory on btrfs, accepting the loss of checksums there.

COPY-ON-WRITE FILE SYSTEMS
never overwrite: write new blocks, then switch the root
old treeroot A → blocksnew blockschanged data + new parentsatomic root switchroot A → root Bsnapshotkeep root A: freechecksumsin parent pointers
swipe the figure sideways, or tap expand for full screen
1/4
write elsewhere
A change writes new data blocks and new copies of every parent up to the root, leaving the old tree intact.
new blocks up to the rootold tree untouched