Comment configurer l’envoi et la réception Btrfs pour des sauvegardes incrémentielles hors site

Eva Wong est la rédactrice technique et bricoleuse résidente chez ZimaSpace. Geek depuis toujours, passionnée par les homelabs et les logiciels open source, elle se spécialise dans la traduction de concepts techniques complexes en guides accessibles et pratiques. Eva croit que l’auto-hébergement doit être amusant, pas intimidant. À travers ses tutoriels, elle donne à la communauté les moyens de démystifier les configurations matérielles, depuis la construction de leur premier NAS jusqu’à la maîtrise des conteneurs Docker.

Btrfs send et receive peuvent transformer des instantanés de sous-volume en lecture seule en une chaîne efficace de réplication hors site. Le premier transfert envoie un instantané complet. Les transferts suivants utilisent un instantané déjà répliqué comme parent ; seuls les changements nécessaires pour reconstruire le nouvel instantané traversent donc le réseau.

Sur ZimaOS, vérifiez d’abord que la source et la destination hors site sont bien des systèmes de fichiers Btrfs et que l’accès SSH est disponible. Le guide actuel des formats de disque de ZimaSpace répertorie la prise en charge de BTRFS en lecture/écriture, et le guide SSH de ZimaOS explique comment activer l’accès au terminal depuis le mode développeur.

Comprendre la chaîne de sauvegarde avant de commencer

Btrfs send/receive est une réplication de sous-volume, et non une commande générique de copie de répertoire. La source doit être un sous-volume Btrfs, et chaque instantané utilisé par btrfs send doit être en lecture seule. Un montage en lecture seule ne remplace pas un instantané de sous-volume en lecture seule.

La documentation officielle de btrfs send décrit deux modes. Un envoi complet contient l’instantané entier. Un envoi incrémentiel utilise -p ou -c avec des instantanés disponibles dans le même état sur l’expéditeur et le récepteur.

Pour une chaîne hors site simple, utilisez un parent explicite avec -p:

snapshot-A  --full send-->  instantané hors site snapshot-A
snapshot-B  --send -p A-->  instantané hors site snapshot-B
snapshot-C  --send -p B-->  instantané hors site snapshot-C

Ne supprimez pas et ne modifiez pas le parent actuel avant que le prochain transfert incrémentiel soit terminé et vérifié.

Vérifier que la source est un sous-volume Btrfs

Remplacez les chemins d’exemple par les véritables points de montage de votre système. Le répertoire des instantanés doit se trouver en dehors du sous-volume source actif, afin que les instantanés de sauvegarde ne deviennent pas imbriqués dans les données protégées.

findmnt -no FSTYPE --target /mnt/pool/data
sudo btrfs subvolume show /mnt/pool/data
sudo btrfs version

La première commande doit afficher btrfs. Le second doit identifier correctement /mnt/pool/data en tant que sous-volume. S’il s’agit seulement d’un répertoire normal, arrêtez-vous ici : btrfs send ne peut pas envoyer un répertoire arbitraire.

Effectuez la même vérification du système de fichiers sur le système hors site pour l’emplacement de réception. btrfs receive doit créer son sous-volume répliqué sur un système de fichiers Btrfs.

Préparer SSH avant de transmettre les données de sauvegarde

Un flux d’envoi hors site contient des données binaires de système de fichiers. SSH est un moyen de transport pratique, car il fournit une authentification et un chiffrement en transit. Si vous utilisez ZimaOS sur l’un ou l’autre des points de terminaison, activez d’abord SSH et testez une connexion normale avant de tenter un flux Btrfs.

ssh backup@backup.example.net

Pour les tâches sans surveillance, utilisez une authentification SSH par clé. Le compte distant doit également pouvoir exécuter btrfs receive de manière non interactive. Ne laissez pas un sudo une invite de mot de passe lue depuis la même entrée standard que celle qui transporte le flux Btrfs. Une règle de privilèges limitée à l’opération de réception requise est plus sûre qu’un accès root général sans mot de passe.

Créez le répertoire de destination lors d’une session administrative interactive :

ssh -t backup@backup.example.net \
  'sudo mkdir -p /mnt/backup/btrfs-recv'

Créer le premier instantané en lecture seule

Créez un instantané fixe en lecture seule du sous-volume source actif. L’ -r Cet indicateur est important, car l’envoi incrémentiel Btrfs dépend d’instantanés qui ne peuvent pas être modifiés pendant l’opération d’envoi.

sudo mkdir -p /mnt/pool/.snapshots

sudo btrfs subvolume snapshot -r \
  /mnt/pool/data \
  /mnt/pool/.snapshots/data-20260831-1000

Confirmez la propriété avant l’envoi :

sudo btrfs property get \
  /mnt/pool/.snapshots/data-20260831-1000 ro

Le résultat attendu est ro=true.

Envoyer l’instantané complet initial hors site

Le premier transfert n’a pas de parent ; il s’agit donc d’un envoi complet. Dans un shell compatible avec Bash, activez pipefail rend visible au shell appelant tout échec de l’un ou l’autre côté du pipeline.

set -o pipefail

sudo btrfs send \
  /mnt/pool/.snapshots/data-20260831-1000 \
  | ssh backup@backup.example.net \
  'sudo -n btrfs receive /mnt/backup/btrfs-recv'

Si sudo -n échoue sur l’hôte distant, corrigez la configuration des privilèges distants avant de réessayer. Ne le remplacez pas par une invite de mot de passe à l’intérieur du pipeline de streaming.

La documentation officielle de btrfs receive indique qu’un sous-volume reçu devient en lecture seule. Elle avertit également qu’il ne faut pas modifier le chemin de réception pendant l’application d’un flux.

Vérifier l’instantané reçu avant de l’utiliser comme parent

Ne supposez pas que la fin d’une session SSH signifie que la chaîne de sauvegarde est saine. Inspectez les deux instantanés :

sudo btrfs subvolume show \
  /mnt/pool/.snapshots/data-20260831-1000

ssh backup@backup.example.net \
  'sudo -n btrfs subvolume show \
  /mnt/backup/btrfs-recv/data-20260831-1000'

Sur l’expéditeur, notez l’instantané UUIDSur le récepteur, le sous-volume répliqué doit afficher cet identifiant source comme son UUID reçuConfirmez également que le sous-volume reçu est en lecture seule.

Ce n’est qu’après cette vérification qu’il faut data-20260831-1000 devienne le parent de la prochaine sauvegarde incrémentielle.

Créer et envoyer l’instantané incrémentiel suivant

Après la modification des données en direct, créez un nouvel instantané en lecture seule :

sudo btrfs subvolume snapshot -r \
  /mnt/pool/data \
  /mnt/pool/.snapshots/data-20260901-0200

Envoyez ensuite uniquement le delta depuis l’instantané précédent :

set -o pipefail

sudo btrfs send \
  -p /mnt/pool/.snapshots/data-20260831-1000 \
  /mnt/pool/.snapshots/data-20260901-0200 \
  | ssh backup@backup.example.net \
  'sudo -n btrfs receive /mnt/backup/btrfs-recv'

Cela fonctionne parce que l’instantané parent du premier envoi existe toujours sous une forme identique sur les deux systèmes. Une fois le nouvel instantané reçu et vérifié avec succès, data-20260901-0200 peut devenir le parent de l’exécution suivante.

Conserver des instantanés parents identiques

La manière la plus courante de rompre une chaîne incrémentielle consiste à modifier l’état de lecture seule ou le contenu d’un instantané utilisé comme parent. Btrfs suit les instantanés reçus au moyen d’un UUID reçu, afin que l’émetteur et le récepteur puissent identifier l’historique correspondant.

Les recommandations officielles de Btrfs concernant les indicateurs de sous-volume et les UUID reçus avertissent que le passage d’un instantané reçu du mode lecture seule au mode lecture-écriture rompt les hypothèses utilisées par l’envoi incrémentiel.

Pour cette raison, ne rendez pas l’instantané de réception hors site accessible en écriture simplement pour parcourir, restaurer ou modifier des fichiers. Si vous avez besoin d’une copie de récupération accessible en écriture, créez un instantané distinct à partir de l’instantané de réception protégé :

sudo btrfs subvolume snapshot \
  /mnt/backup/btrfs-recv/data-20260901-0200 \
  /mnt/restore/data-20260901-0200

Le nouvel instantané de restauration est accessible en écriture par défaut, tandis que l’instantané de réception d’origine reste intact pour les futurs envois incrémentiels.

Utiliser une règle sûre de rétention des instantanés

Vous n’avez pas besoin de conserver indéfiniment tous les anciens instantanés, mais vous devez conserver sur les deux systèmes le parent requis par l’envoi suivant. Une règle de rotation simple consiste à :

  1. Créez le nouvel instantané source en lecture seule.
  2. Envoyez-le en utilisant l’instantané précédent réussi comme -p.
  3. Vérifiez le nouvel instantané de réception hors site.
  4. Faites du nouvel instantané le parent suivant.
  5. Ce n’est qu’ensuite que vous devez supprimer les anciens points de restauration conformément à votre politique de rétention.

Conserver plusieurs instantanés historiques peut fournir des points de restauration utiles, mais rappelez-vous qu’un instantané situé sur le même système de fichiers ne constitue pas une sauvegarde indépendante. La réplique hors site est précieuse, car elle place une autre copie sur un système et dans un emplacement distincts. Le guide de sauvegarde 3-2-1 de ZimaSpace explique pourquoi une copie hors site protège contre les défaillances que la redondance locale ne peut pas couvrir.

Gérer séparément les sous-volumes Btrfs imbriqués

Les instantanés Btrfs ne sont pas récursifs pour les sous-volumes imbriqués. Si /mnt/pool/data contient un autre sous-volume, l’instantané parent contient un stub de sous-volume plutôt qu’un instantané complet des données imbriquées.

Répertoriez les sous-volumes avant de finaliser le plan de sauvegarde :

sudo btrfs subvolume list /mnt/pool

Si des données applicatives importantes résident dans des sous-volumes imbriqués, créez et répliquez une chaîne distincte d’instantanés en lecture seule pour chacun d’eux.

Savoir quand utiliser -p et quand utiliser -c

Pour un historique de sauvegarde linéaire, -p est l’option la plus simple et la plus facile à vérifier. La -c L’option peut ajouter une ou plusieurs sources de clonage permettant à Btrfs de réutiliser les étendues correspondantes d’instantanés supplémentaires, mais ces sources de clonage doivent également exister exactement dans le même état aux deux extrémités.

Si vous ne pouvez pas prouver qu’une source de clonage n’a pas changé et qu’elle est présente sur les deux systèmes, ne l’utilisez pas. Une chaîne simple à parent unique est généralement plus sûre pour une tâche de sauvegarde hors site.

Facultatif : utiliser le protocole 2 pour les étendues compressées

Sur des versions suffisamment récentes de Linux et de btrfs-progs, le protocole d’envoi Btrfs 2 peut transmettre plus efficacement les étendues compressées avec --compressed-data. La documentation officielle de l’envoi indique que le protocole 2 nécessite btrfs-progs 6.0 ou une version ultérieure sur l’émetteur et le récepteur, ainsi que Linux 6.0 ou une version ultérieure sur l’émetteur.

sudo btrfs send \
  --proto 2 \
  --compressed-data \
  -p /mnt/pool/.snapshots/data-20260831-1000 \
  /mnt/pool/.snapshots/data-20260901-0200 \
  | ssh backup@backup.example.net \
  'sudo -n btrfs receive /mnt/backup/btrfs-recv'

N’activez pas cette option simplement parce qu’elle existe. Vérifiez d’abord les versions sur les deux points d’extrémité et utilisez le protocole par défaut lorsque la compatibilité est plus importante que l’optimisation.

Résoudre les échecs courants d’envoi et de réception incrémentiels

La commande d’envoi indique que l’instantané n’est pas en lecture seule

Recréez l’instantané avec btrfs subvolume snapshot -r. Le simple fait de monter un instantané accessible en écriture via un montage en lecture seule ne satisfait pas à l’exigence d’envoi.

L’envoi incrémentiel ne trouve pas son parent ou ne peut pas l’utiliser

Vérifiez que l’instantané parent exact existe toujours sur l’émetteur et que l’instantané reçu correspondant existe toujours sur le récepteur. Si l’un des parents a été supprimé, modifié ou rendu accessible en écriture, restaurez un parent correspondant si vous en avez un. Sinon, créez un nouvel instantané en lecture seule et lancez un nouvel ensemencement complet.

btrfs receive indique que le sous-volume de destination existe déjà

btrfs receive n’écrasera pas un sous-volume existant portant le même nom entrant. Inspectez d’abord le sous-volume existant. S’il s’agit d’une réception échouée ou incomplète et que vous avez confirmé qu’il est possible de le supprimer sans risque, supprimez ce sous-volume incomplet avant de réessayer le même transfert.

Le parent de réception a été modifié après son arrivée

N’utilisez pas cet instantané modifié comme base d’un nouveau flux incrémentiel. S’il n’existe aucun parent de réception correspondant et inchangé, démarrez une nouvelle chaîne de sauvegarde complète.

Les fichiers d’un répertoire imbriqué sont absents de l’instantané

Vérifiez si ce répertoire est lui-même un sous-volume Btrfs. Les sous-volumes imbriqués ne sont pas inclus récursivement dans l’instantané parent et nécessitent leur propre chaîne d’envoi/réception.

La connexion WAN ou SSH est interrompue pendant un transfert

Considérez la réception comme échouée, sauf si elle s’est terminée correctement et si le sous-volume obtenu est correctement vérifié. L’interface de commandes Btrfs send/receive documentée ne fournit pas d’option de reprise d’un flux. Pour les liaisons longue distance peu fiables, envisagez d’écrire le flux d’envoi dans un fichier intermédiaire, de transférer ce fichier avec un transport reprenable, puis de transmettre le fichier fiable et complet à btrfs receive.

Protégez le côté réception contre les flux non fiables

La réception Btrfs applique les opérations du système de fichiers provenant du flux entrant. La documentation officielle de la réception déconseille d’accepter des flux d’envoi provenant de sources non fiables et recommande de protéger le chemin de réception contre les écritures concurrentes pendant l’application d’un flux.

Utilisez la vérification de l’hôte SSH, l’authentification par clé, un compte de sauvegarde dédié et les privilèges les plus restreints possibles. Empêchez le répertoire de réception d’être accessible en écriture par les utilisateurs ordinaires pendant l’exécution d’une sauvegarde.

Utilisez cette checklist pour chaque exécution incrémentielle

  • Confirmez que les deux extrémités utilisent Btrfs.
  • Créez le nouvel instantané source avec -r.
  • Conservez le parent précédent ayant réussi inchangé sur les deux systèmes.
  • Envoyer avec btrfs send -p OLD NEW.
  • Effectuez la réception via une connexion SSH authentifiée et chiffrée.
  • Vérifiez la réussite et comparez l’UUID source à l’UUID reçu du destinataire.
  • Conservez l’instantané de sauvegarde reçu en lecture seule.
  • Créez un instantané inscriptible distinct lorsque vous devez restaurer ou tester des données.
  • Faites tourner les anciens instantanés uniquement après avoir vérifié le nouveau parent.
  • Sauvegardez les sous-volumes imbriqués avec des chaînes distinctes.

Une fois qu’une sauvegarde complète et une sauvegarde incrémentielle ont toutes deux réussi manuellement, automatisez la même séquence avec une journalisation et des vérifications explicites du code de sortie. L’important n’est pas le planificateur, mais la conservation d’un instantané parent inchangé et vérifié aux deux extrémités de chaque étape incrémentielle.

Assistance et conseils

Plus à lire

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.