TL;DR — Résumé Rapide

Snapshots ZFS protègent vos données Linux par copy-on-write. Créez, restaurez, clonez et répliquez des datasets avec zfs send/receive et sanoid.

Les snapshots ZFS sont l’un des outils de protection des données les plus puissants disponibles sous Linux. Contrairement aux approches de sauvegarde traditionnelles qui copient des datasets entiers, les snapshots ZFS exploitent la sémantique copy-on-write (COW) pour capturer l’état exact d’un système de fichiers à un instant précis — instantanément et sans coût d’espace initial. Ce guide couvre les fondamentaux ZFS jusqu’aux pipelines de snapshots automatisés avec sanoid et syncoid.

Prérequis

  • Ubuntu 22.04/24.04 LTS (ou toute distro avec OpenZFS 2.1+)
  • Un ou plusieurs dispositifs de bloc pour les tests
  • Accès sudo
  • Familiarité de base avec les noms de dispositifs Linux (/dev/sd*, /dev/vd*)

Concepts Fondamentaux de ZFS

Copy-on-Write (COW) : ZFS n’écrase jamais les données actives sur place. Quand un bloc est modifié, ZFS écrit la nouvelle version dans un emplacement libre et met à jour atomiquement le pointeur. L’ancien bloc reste intact — c’est ce qu’exploitent les snapshots.

Pools et Datasets : Un pool (zpool) est le conteneur de stockage de niveau supérieur formé par un ou plusieurs vdevs. Un dataset (zfs create) est un système de fichiers montable dans un pool.

Checksums : Chaque bloc porte un checksum 256 bits. En lecture, ZFS vérifie le checksum et peut s’auto-réparer depuis une copie redondante si le bloc primaire est corrompu.


Installer ZFS sur Ubuntu

sudo apt update
sudo apt install zfsutils-linux -y
zfs --version

Créer des Pools

# Miroir (équivalent RAID-1)
sudo zpool create tank mirror /dev/sdb /dev/sdc

# RAIDZ1 — 1 disque de parité, tolère 1 panne
sudo zpool create tank raidz /dev/sdb /dev/sdc /dev/sdd

# RAIDZ2 — 2 disques de parité, tolère 2 pannes (recommandé pour >=6 disques)
sudo zpool create tank raidz2 /dev/sd{b,c,d,e,f,g}
zpool status tank
zpool list

Gestion des Datasets

# Dataset avec compression LZ4
zfs create -o compression=lz4 tank/data

# Point de montage explicite
zfs set mountpoint=/srv/data tank/data

# Compression zstd pour un meilleur taux
zfs set compression=zstd tank/data

# Ajustement du recordsize pour les bases de données
zfs set recordsize=16K tank/postgres    # PostgreSQL
zfs set recordsize=128K tank/mysql      # MySQL InnoDB

# Quotas et réservations
zfs set quota=500G tank/data
zfs set reservation=100G tank/data

Propriétés de surveillance clés :

Propriété Signification
used Espace consommé par le dataset + ses snapshots
available Espace libre que le dataset peut encore utiliser
referenced Espace du dataset actif uniquement (exclut les snapshots)
compressratio Taux de compression atteint (ex. 2.14x)

Fondamentaux des Snapshots

Créer des Snapshots

# Snapshot unique
zfs snapshot tank/data@2026-03-22

# Snapshot récursif
zfs snapshot -r tank@2026-03-22

# Avec horodatage du shell
zfs snapshot tank/data@$(date +%Y-%m-%dT%H%M)

Lister les Snapshots

zfs list -t snapshot
zfs list -t snapshot -o name,used,referenced,creation

Restaurer (Rollback)

zfs rollback tank/data@2026-03-22

# Si des snapshots plus récents existent
zfs rollback -r tank/data@2026-03-21

Accéder au Contenu d’un Snapshot sans Restaurer

ls /srv/data/.zfs/snapshot/
# Restaurer un fichier individuel
cp /srv/data/.zfs/snapshot/2026-03-22/important.sql /srv/data/restaure.sql

Supprimer des Snapshots

zfs destroy tank/data@2026-03-20
# Plage de snapshots
zfs destroy tank/data@2026-03-01%2026-03-15

Clones : Snapshots Inscriptibles

Un clone est un dataset inscriptible dérivé d’un snapshot, idéal pour les environnements de staging.

# Créer un clone
zfs clone tank/data@2026-03-22 tank/data-staging

# Point de montage
zfs set mountpoint=/srv/staging tank/data-staging

# Promouvoir le clone en indépendant
zfs promote tank/data-staging

Send/Receive : Réplication ZFS

Envoi Initial Complet

# Copie locale
zfs send tank/data@2026-03-22 | zfs receive backup/data

# Par SSH avec compression
zfs send -c tank/data@2026-03-22 | ssh backup-host zfs receive backup/data

Envois Incrémentiels

# -i = incrément unique
zfs send -ci tank/data@2026-03-21 tank/data@2026-03-22 | \
  ssh backup-host zfs receive -F backup/data

# -I = inclut les snapshots intermédiaires
zfs send -cI tank/data@2026-03-20 tank/data@2026-03-22 | \
  ssh backup-host zfs receive -F backup/data

Reprendre les Transferts Interrompus

zfs get receive_resume_token backup/data
zfs send -t <token> | ssh backup-host zfs receive -s backup/data

Référence des Flags de Réplication

Flag Effet
-c Compresse le flux
-i Incrémental entre deux snapshots
-I Incrémental incluant les snapshots intermédiaires
-R Réplique le dataset récursivement
-s Sauvegarde l’état de reprise sur le récepteur
-v Sortie détaillée

Snapshots Automatisés avec Sanoid

Installer Sanoid

sudo apt install sanoid -y

Configurer les Politiques

# /etc/sanoid/sanoid.conf
[tank/data]
  use_template = production
  recursive = yes

[template_production]
  hourly = 24
  daily = 30
  monthly = 3
  autosnap = yes
  autoprune = yes

Activer le Timer Systemd

sudo systemctl enable --now sanoid.timer
sudo sanoid --take-snapshots --verbose
sudo sanoid --prune-snapshots --verbose

Syncoid pour la Réplication

syncoid tank/data backup-host:backup/data
syncoid --recursive tank backup-host:backup

Vérification et Auto-réparation (Scrub)

sudo zpool scrub tank
zpool status tank | grep -A5 scrub
echo "0 2 1 * * root /sbin/zpool scrub tank" | sudo tee /etc/cron.d/zfs-scrub

ZFS vs. Alternatives

Fonctionnalité ZFS Btrfs LVM + ext4 XFS
Copy-on-write Oui Oui Non Non
RAID intégré Oui (RAIDZ) Oui (limité) Via LVM Non
Snapshots natifs Oui Oui Via LVM Non
Réplication send/receive Oui (natif) Oui Non Non
Checksums / auto-réparation Oui Oui (limité) Non Non
Compression Oui (lz4, zstd) Oui Non Non
Cache ARC/L2ARC Oui Non Non Non
Maturité en production (Linux) Haute (OpenZFS) Moyenne Très haute Très haute

Patterns de Production

Boot Environments

sudo zfs snapshot -r rpool/ROOT/ubuntu@before-upgrade

Docker sur ZFS

echo '{"storage-driver": "zfs"}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
zfs set recordsize=128K tank/docker

Recordsize pour les Bases de Données

Base de données recordsize recommandé Raison
PostgreSQL 8K ou 16K Correspond à la page de 8K
MySQL InnoDB 16K Correspond à la page InnoDB
MySQL MyISAM 128K Favorise les scans séquentiels
MongoDB 16K Page WiredTiger par défaut
SQLite 4K Correspond à la page par défaut

Cas Particuliers et Mises en Garde

  • N’importez jamais le même pool sur deux hôtes simultanément : cela provoque un split-brain et une corruption du pool.
  • La déduplication vaut rarement le coup : elle nécessite ~5 Go de RAM par To de données uniques.
  • Swap sur ZFS : Évitez d’utiliser un zvol ZFS comme swap — des deadlocks peuvent survenir sous pression mémoire extrême.

Résumé

  • Les snapshots ZFS sont des copies instantanées et efficaces en espace basées sur le copy-on-write.
  • Utilisez zfs snapshot pour les snaps manuels et sanoid pour la gestion automatisée par politiques.
  • zfs send | zfs receive réplique les datasets efficacement — seuls les blocs modifiés transitent par le réseau.
  • Le scrubbing mensuel détecte la corruption silencieuse avant qu’elle ne se propage.
  • Les snapshots sur le même pool ne remplacent pas les sauvegardes hors pool — répliquez toujours vers un hôte séparé.

Articles Associés