Table des matières

btrfs

btrfs est un système de fichiers moderne, bien plus avancé qu'ext4. btrfs est examiné ici dans le cadre d'une utilisation sur un ordinateur personnel.

J'ai migré ma machine personnelle d'ext4 vers btrfs, aussi bien pour le système (/) que pour mon /home. Avantages:

PS: Je ne me sers pas des fonctionnalités de btrfs (snapshot distants, etc.) pour faire mes backups. Je me sers d'un autre outils (BorgBackup).

Je note ici en vrac des infos utiles ou mes interrogations.

Je ne vais pas parler ici que de certaines fonctionnalités de btrfs, mais sachez qu'on peut aller beaucoup plus loin, comme faire du RAID logiciel, faire un miroir quasi-temps réel d'un disque vers une autre machine, ou encore remplacer à chaud un disque dur sans arrêter le système (!)

Concepts de btrfs

Il faut voir btrfs comme un énorme gestionnaire de blocs de données (de tailles variables, jusqu'à 128 ko par défaut) gérés par un arbre binaire (d'où le nom de btrfs : "Binary Tree") permettant une recherche très rapide de ces blocs. Un fichier est décrit comme l'enchaînement d'un nombre de blocs de données. Cette particularité permet à btrfs un certain nombre de choses assez cools, comme les snapshots, la répartitions sur plusieurs supports de stockage (RAID) ou le "CoW" (Copy-on-Write).

Je ne vais pas vous énumérer ici toutes les autres particularités de btrfs (support des très gros fichiers, gestion des volumes logiques, checksum des blocs de données et méta-données, indexation des répertoires, possibilité d'envoyer les snapshot sur une autre machine, etc.). Pour cela, je vous laisser regarder le Wiki officiel.

Je ne vais ici aborder que les particularités majeurs de btrfs : Le Copy-on-Write (CoW) et les snapshots.

CoW (Copy-on-write)

Le Copy-on-write (ou "CoW") est une particularité bien spécifique de certains systèmes de fichiers récents comme btrfs ou ZFS.

Fonctionnement

Avec le CoW (actif par défaut dans btrfs), toute modification d'un fichier écrit les données modifiées à côté du fichier original. Ce mécanisme permet d'assurer l'intégrité des données à tout moment. Imaginons que nous ayons un fichier constitué de blocs de données A, B, C et D:

btrfs:cow-1.png

Maintenant on écrit de nouvelles données dans une partie du fichier: btrfs:cow-2.png

La plupart des systèmes de fichiers vont écrire les données de E par dessus C, sur place.

Avec le Copy-on-Write, btrfs va copier ces nouvelles données dans une nouvelle zone (un "extend") et une fois la copie terminée, il va mettre à jour les méta-données du fichier pour dire que cette partie du fichier pointe sur le nouvel extend. btrfs:cow-3.png

Ainsi, il ne peut pas y avoir d'état où les données de E sont à moitié écrites dans le fichier. Votre fichier est forcément dans un état correct: Soit dans son ancienne version (A,B,C,D) soit dans la nouvelle (A,B,E,D).

Le bloc C sera ultérieurement libéré automatiquement par un processus en tâche de fond de btrfs.

(dé)fragmentation

Inconvénient: Plus un fichier est modifié, plus cela génère de fragmentation.

Il y a trois manières de lutter contre cette fragmentation:

  1. Montez votre système de fichiers avec l'option autodefrag pour une défragmentation automatique.
  2. Défragmentez manuellement des fichiers ou répertoires:
    sudo btrfs filesystem defragment -r /
  3. Pour les gros fichiers modifiés souvent (machines virtuelles, bases de données, conteneurs docker…), vous pouvez désactiver sélectivement CoW sur un fichier ou un répertoire.
    sudo chattr +C fichier
    • Notez que si vous désactivez CoW sur un répertoire, tout nouveau fichier créé dans ce répertoire aura également CoW désactivé.
    • Un fichier marqué en "NOCOW" ne pourra pas bénéficier de la compression (voir plus loin).
Le fait de faire une défragmentation casse les liens de déduplication. Cela n'a aucun impact sur l'intégrité des données, mais si vous aviez des fichiers dédupliqués (par exemple avec jdupes), avec la défragmentation chaque fichier se retrouve avec sa copie des données. L'occupation de l'espace disque sera donc supérieure. Il sera nécessaire de refaire une déduplication après la défragmentation pour récupérer l'espace.

atime

atime est probablement l'une des plus mauvaises inventions d'Unix/Linux. Il enregistre la date de dernier accès à un fichier ou un répertoire. Ce qui veut dire que tout fichier lu va générer une écriture disque.

Dans la plupart des systèmes récents, l'option de montage relatime est active par défaut et permet de limiter ces écritures, mais dans le cas d'un système de fichier travaillant en Copy-on-Write, il vaut mieux désactiver totalement cela en utilisant les options de montage noatime/nodiratime dans votre /etc/fstab.

Attention: Certains outils (serveurs de mail, certains outils de backup, audit) ont besoin de la date de dernier accès au fichier. noatime peut donc potentiellement nuire à leur fonctionnement. D'une manière générale, sur un serveur, évitez noatime sur /var/spool et /tmp. (Là dans le cadre de ma machine perso, avec aucun serveur de mail qui tourne dessus, j'ai activé noatime partout. Quant à /tmp, il est en tmpfs (en mémoire) et non dans la partition btrfs).

Copie de fichier rapide

Astuce: Quand vous copiez des fichiers avec cp à l'intérieur de votre partition btrfs, ajoutez l'option --reflink=auto : Cela va utiliser CoW. Non seulement la copie du fichier sera instantanée, mais elle ne consommera aucun espace disque supplémentaire (Bien sûr cela ne fonctionne qu'à l'intérieur d'un même système de fichiers btrfs).

Exemple: cp --reflink=auto fichier1 fichier2

À la différence des hardlinks, modifier fichier2 ne modifiera pas fichier1.

Des données ne commenceront à être écrites sur disque que si vous modifiez l'un des deux fichiers. Avant cela, ils partagent leurs blocs de données.

Sous-volumes et snapshots

L'autre truc extrêment cool avec CoW, c'est la possibilité de faire des snapshots (des "images") instantanées de votre système de fichiers.

"sous-volumes" et "snapshots" sont en fait les mêmes entités. Sauf qu'un sous-volume peut être créé vide, alors qu'un snapshot est la copie d'un autre sous-volume ou snapshot. On peut utiliser indifféremment l'un ou l'autre.

Imaginons que vous ayez dans votre sous-volume @home (que vous avez monté en /home) un Fichier1: btrfs:snapshot-1.png

Maintenant on créé une copie (un snapshot) de @home en @backupHome:

sudo btrfs subvolume snapshot @home @backupHome

Le snapshot est immédiat, car aucune donnée n'est copiée. On se contente de dire que dans ce nouveau snapshot @backupHome, Fichier1 pointe sur les mêmes blocs de données: btrfs:snapshot-2.png

Mais que se passe-t-il quand dans @home on écrit dans Fichier1 ? Et bien avec CoW, il va créer un extend qui contient les nouvelles données, et faire pointer cette partie du fichier sur le nouveau bloc E, mais uniquement dans ce sous-volume @home. btrfs:snapshot-3.png

Vous pouvez donc accéder à l'ancienne version de Fichier1 dans @backupHome, et la nouvelle dans @home, sans pour autant avoir besoin d'avoir deux copies complètes des données du fichier sur disque.

Ainsi les blocs de données partagés entre sous-volumes et snapshots n'occupent pas plus de place sur disque. Ce qui prend de la place sur disque, ce sont les modifications de données.

Encore plus cool: Vous avez besoin de revenir à l'ancienne version de votre "home" ? C'est désarmant de simplicité:

sudo mv @home @home.old
sudo mv @backupHome @home

(oui, c'est aussi simple que cela !)

Bien entendu, à force d'accumuler des snapshots, cela prend de la place. Il convient de ne pas accumuler de manière inutile des snapshots sous peine de remplir son disque dur. Mais cela permet de prendre à n'importe quel moment des instantanés de votre système de fichiers, et d'y revenir très facilement en cas de problème.

Voici quelques commandes pour gérer les sous-volumes et snapshots:

Manipulation des volumes et snapshots:


Compression

Il y a donc 2 endroits où vous pouvez compresser:

Mon expérience:

Donc en ce qui me concerne, ce n'est que du positif.

Cliquez pour afficher comment installer et utiliser compsize

Cliquez pour afficher comment installer et utiliser compsize

  • Note: compsize est généralement fourni dans les depôts des distributions (paquet btrfs-compsize). Si ce n'est pas le cas, voici comment télécharger et compiler la dernière version:
  • sudo apt install build-essential libbtrfs-dev
  • Entrez dans le répertoire compsize-master et lancez: make
  • Cela va créer l'exécutable compsize que vous pouvez alors utiliser. Exemple:
    > sudo ./compsize /usr
    Processed 212419 files, 90023 regular extents (113050 refs), 117223 inline.
    Type       Perc     Disk Usage   Uncompressed Referenced  
    TOTAL       68%      2.8G         4.2G         4.6G       
    none       100%      1.2G         1.2G         1.3G       
    lzo         54%      1.5G         2.9G         3.2G
  • none: Données non compressées ; lzo: Données compressées en lzo ; (Vous verrez aussi zstd ou zlib si vous utilisez ces algos.)
  • Colonnes:
    • Perc: Pourcentage de compression (tailles des données compressées par rapport aux données non compressées) (Plus la valeur est faible, mieux c'est)
    • Disk usage: Place effectivement occupée sur disque par ces données.
    • Uncompressed: Taille réelle des données (sans compression). Ces données peuvent être partagées entre plusieurs fichiers.
    • Referenced: Taille totale des fichiers (puisque plusieurs fichiers peuvent pointer sur les mêmes blocs de données)
  • Il y a donc au total 4,6 Go de fichiers dans ce répertoire. Avec la déduplication et la compression, ces 4,6 Go n'occupent que 2,8 Go sur disque.
  • La ligne lzo montre uniquement les fichiers qui sont compressés. Il y a 3,2 Go de fichiers qui sont dédupliqués et compressés, et qui au final n'occupent que 1,5 Go sur disque.
  • Certains fichiers n'ont pas été compressés probablement parce qu'ils ne sont pas compressibles (jpg, etc.)


Comment lire un compte-rendu de compsize

Type       Perc     Disk Usage   Uncompressed Referenced  
TOTAL       65%      1.4G         2.1G         4.0G  

Déduplication

Contrairement à ZFS, btrfs ne fait pas (encore) de déduplication en temps réel. Il n'est également pas fourni avec des outils officiels pour faire la déduplication. Il faut lancer des outils tiers pour dédupliquer les données. Il en existe plusieurs: https://btrfs.wiki.kernel.org/index.php/Deduplication#Dedicated_btrfs_deduplicators

Cette déduplication ne peut être effectuée que sur une partition montée.

Certains outils de déduplication fonctionnent au niveau fichier (les fichiers identiques en entier seront dédupliqués), d'autres au niveau blocs de données (les blocs de données identiques, même dans des fichiers différents, seront dédupliqués).

La déduplication au niveau blocs est en théorie plus efficace, mais j'ai constaté de bien meilleurs résultats avec jdupes (déduplication au niveau fichiers) qu'avec duperemove (déduplication au niveau blocs). Je ne me l'explique pas. Donc de manière générale, parmis les solutions proposées, préférez jdupes.

Voici différents outils:

Déduplication au niveau fichiers avec jdupes ⇐ :-) solution recommandée

Déduplication au niveau fichiers avec jdupes ⇐ :-) solution recommandée

jdupes possède une option spécifique pour btrfs.

sudo apt install jdupes
ulimit -n 600000
sudo jdupes -1 -r -B /home
sudo jdupes -1 -r -B /bin /etc /lib /lib64 /opt /sbin /usr /snap /var
  • -1 : Ne comparer que les fichiers qui sont sur le même système de fichier (btrfs ne pourra pas dédupliquer des fichiers situés dans des systèmes de fichiers différents).
  • -r : Traiter les sous-répertoires.
  • -B : Soumettre les déduplications à btrfs.
    • Astuce: Retirez le paramètre -B pour voir les fichiers identiques, sans dédupliquer.
  • jdupes va balayer les répertoires, rechercher les fichiers identiques et s'ils sont identiques octet par octet, soumettre la déduplication à btrfs.
  • La commande ulimit -n permet d'augmenter le nombre de fichier ouverts simultanément (1024 par défaut, ce qui peut être trop juste pour jdupes. Si vous n'augmentez pas, vous risquez d'avoir l'erreur "too many open files" qui va nuire à l'efficacité de la déduplication.)

Déduplication au niveau blocs avec duperemove

Déduplication au niveau blocs avec duperemove

  • Installation: sudo apt install duperemove
  • Utilisation: sudo duperemove -drh --hashfile=/.duperemove.dat /etc /lib /lib32 /lib64 /libx32 /sbin /snap /srv /usr /var /home
    • -r : traiter les sous-répertoires
    • -d : soumettre les déduplications de blos de données à btrfs.
    • -h : affichage des tailles lisible (k/M/G)
    • --hashfile=/.duperemove.dat : Stocker la table de travail (hash) entre les lancements.
    • Le premier lancement sera long, car il va faire la checksum de tous les fichiers du disque.
    • Les lancements suivants seront nettement plus rapides, car il n'ira examiner que les fichiers nouveaux/modifiés.
    • Le fichier .duperemove.dat lui permet de mémoriser les hashs de blocs de données et la liste des fichiers entre chaque lancement.
    • À la fin de chaque exécution, duperemove vous affichera le gain potentiel de place gagnée par la déduplication.

Déduplication au niveau fichiers avec rmlint

Déduplication au niveau fichiers avec rmlint

rmlint possède une option spécifique pour btrfs.

  • Installez: sudo apt install rmlint
  • Lancez le scan: sudo rmlint -T df --config=sh:handler=clone /home
    • -T df pour trouver les fichiers dont le contenu est identique.
    • --config=sh:handler=clone pour que les doublons trouvés soient envoyés à btrfs pour déduplication.
  • Après le scan, il va vous afficher les doublons, et le gain potentiel. Cela va également créer deux fichiers: rmlint.sh et rmlint.json
  • Lancez rmlint.sh:
    sudo chmod +x rmlint.sh
    sudo ./rmlint.sh -d
    • Notez qu'à la fin du traitement, le script rmlint.sh se supprime lui-même.
  • Je ferais: sudo rmlint -T df --config=sh:handler=clone /bin /boot /etc /home /lib /lib64 /opt /root /sbin /usr /var

Déduplication au niveau blocs avec bees

Déduplication au niveau blocs avec bees

BEES est un déduplicateur qui travaille au niveau bloc. Notez que la déduplication se fait à la fois dans les sous-volumes et les snapshots. Donc, par exemple, il sera capable de dédupliquer un fichier qui serait également présent à l'intérieur d'un fichier tar (non compressé), ce que ne pourraient pas faire des déduplicateurs qui fonctionnent au niveau fichier entier (jdupes, rmlint).

Attention: bees ne doit pas être utilisé avec certaines versions du noyau. Voir cette page pour les versions recommandées.
  • bees est un outils en ligne de commande. Il n'y a pas de packages debian disponibles, il faut le compiler.
  • Installation:
    • sudo apt install build-essential uuid-dev markdown libbtrfs-dev
    • make
    • sudo make install
      • L'installation créé peu de fichiers:
        /usr/lib/bees/bees
        /usr/sbin/beesd
        /etc/bees/beesd.conf.sample
        /lib/systemd/system/beesd@.service
  • Configuration:
    • sudo cp /etc/bees/beesd.conf.sample /etc/bees/beesd.conf
    • Modifiez le fichier /etc/bees/beesd.conf:
      • UUID= : Renseignez l'UUID venant de votre /etc/fstab
      • DB_SIZE= : C'est la taille de la table de travail de bees. Elle sera stockée sur disque. Pour un disque de 1 To, avec des blocs à 128ko (par défaut dans btrfs), une table de 128 Mo est recommandée. Si la compression est activée, il est recommandé de doubler cette valeur. On va donc prendre une table de 256 Mo (1024*1024*256): DB_SIZE=$((1024*1024*256))
  • Utilisation:
    • sudo /usr/sbin/beesd <UUID>
    • Utilisez l'UUID de votre partition. Exemple: sudo /usr/sbin/beesd c6c3f724-9918-471c-8936-eb44569c4a91
  • Notes:
    • Avec bees, un service systemd est également fourni, mais je ne l'utilise pas. La déduplication est un processus gourmand en CPU, et je ne veux pas que ça se déclenche n'importe quand. Je conserve donc le lancement manuel (typiquement: le lancer une fois de temps en temps le soir, et le laisser tourner la nuit).
    • Si vous montez votre partition btrfs, vous verrez à la racine un répertoire .beeshome qui contient la fameuse table de travail de bees (256 Mo).
    • beesd étant conçu pour être un service, il ne s'arrête jamais. Vous pouvez l'arrêter à tout moment avec Ctrl+C, il reprendra là où il en était quand vous le relancerez. Pour savoir s'il a fini son travail, regardez l'occupation CPU.
    • Si vous voulez juste faire tourner beeds pendant quelques minutes, utilisez la commande timeout.
    • Et pour lui donner en prime la priorité CPU et disque minimales, utilisez nice et ionice.
    • Exemple: Lancer la déduplication pendant 15 minutes seulement, avec la priorité disque et CPU minimales:
      sudo timeout 15m nice -n 19 ionice -c3 /usr/sbin/beesd c6c3f724-9918-471c-8936-eb44569c4a91



Fiabilité

On trouve beaucoup d'histoires de corruptions et de problème avec btrfs. Mais il semblerait qu'elles soient toutes liées à d'anciennes versions (<2016) de btrfs. Or le développement de btrfs est très actif. Afin d'éviter les problèmes, il est donc conseillé d'utiliser des noyaux Linux récents.

Facebook utilise massivement btrfs sur ses serveurs. Je ne pense pas qu'ils soient très fan de la corruption de données.
Les NAS de Synology utilisent aussi btrfs. La distribution Linux Fedora utilise btrfs par défaut.

Ceci dit, certaines fonctionnalités de btrfs ne sont pas considérées comme stable et ne devraient pas encore être utilisées (par exemple RAID56) : https://btrfs.wiki.kernel.org/index.php/Status

Quoi qu'il en soit, la règle suivante est toujours valable: FAITES DES BACKUPS :!::!::!:

Je ne manquerai pas d'indiquer dans cette page si j'ai des soucis avec btrfs.


Performances

On trouve des avis contradictoires.

En performances pures, ext4 semble meilleur que btrfs, mais je n'ai jamais vu de comparaison avec un btrfs compressé lzo (données compressées, donc en moins d'I/O disque, donc en principe plus rapide).


Gotchas


Migration et utilisation dans Linux (Ubuntu / Linux Mint)

Le noyau Linux (et Ubuntu/Linux Mint) supporte nativement btrfs. Avantages:

L'énorme avantage des snapshots systèmes Timeshift en btrfs, par rapport à ext4, c'est qu'ils sont instantanés (ça prend moins d'une seconde) et qu'ils prennent moins de place que les snapshots rsync.


Migration depuis ext4

Il existe un outils de migration ext4 vers btrfs, mais il n'est absolument pas stable. J'ai donc choisi de déplacer temporairement mes fichiers sur un disque externe, reformater, et re-transférer les fichiers.

Il est fortement déconseillé d'utiliser l'outils de migration ext4➡btrfs. Il faut mieux: sortir les fichiers sur un autre support, reformater en btrfs, puis recopier les fichiers. Vous pouvez vous aider de fsarchiver est extrêmement efficace pour stocker temporairement des fichiers sur un support externe.

Partitionnement

btrfs:btrfs-migration.png

Notes:

Planning de la migration:

  1. Backup habituel de mon /home avec borg (parce que ceintures et bretelles)
  2. Récupération d'un HD externe 1 To temporairement (le disque de l'ordinateur à migrer fait 1 To)
  3. Formatage d'une partition en ext4 sur ce HD externe.
    • :!: Gotcha: Formattez - bien à l'avance de votre backup - votre partition de 1 To en ext4 et laissez le disque branché, car la création des inodes en tâche de fond prend une éternité. Je me suis fait avoir. J'ai perdu beaucoup de temps à cause de ça.
  4. Sauvegarde de /home sur ce disque avec fsarchiver
    sudo fsarchiver -v -Z 1 savedir /mnt/sdb1/home.fsa /home
    • savedir=sauvegarder un répertoire, -v pour verbose, -Z 1 pour utiliser la compression ztsd (très rapide).
    • Je ne sauvegarde pas '/' car je ré-installe le système (Je change de version de Mint).
    • Pourquoi fsarchiver ? Il est fiable, très rapide, les archives sont checksummées, et surtout si une partie de l'archive est corrompue, on ne perd QUE les fichiers de la partie corrompue, pas toute l'archive. Et puis le chiffrement me permet de ne pas laisser mes données de la partition VeraCrypt en clair sur le disque externe.
  5. Sauvegarde du contenu de ma partition VeraCrypt avec fsarchiver (en ajoutant l'option -c - pour chiffrer l'archive)
  6. Repartionnement en btrfs et ré-installation de l'OS.
  7. Activation des options de montage des volumes btrfs dans /etc/fstab (noatime,nodiratime,autodefrag,compress-force=zstd) + reboot pour prise en compte.
  8. Recopie des données du dd externe vers la machine (fsarchiver restdir)
  9. (plus tard) Déduplication des données.

À l'installation de Mint

À l'installation de Mint:

Après installation:

L'installeur de Linux Mint met automatiquement /home dans un sous-volume btrfs @home ce qui est une excellente idée. Cela permet de faire des snapshots séparés du système et des fichiers utilisateurs. (On peut donc par exemple restaurer un snapshot du système (@) sans impacter les données des utilisateurs (@home) ; C'est d'ailleurs ce que vous proposera Timeshift).

Options de montage

Je monte mes sous-volumes btrfs avec ces options:

UUID=e3dc85e3-0d2b-40e3-803b-7c2cb0bf543a /               btrfs   defaults,noatime,nodiratime,autodefrag,compress-force=zstd,subvol=@ 0       1
UUID=e3dc85e3-0d2b-40e3-803b-7c2cb0bf543a /home           btrfs   defaults,noatime,nodiratime,autodefrag,compress-force=zstd,subvol=@home 0       2

Timeshift

Linux Mint est fourni avec Timeshift et encourage fortement à son utilisation.

Par défaut, Timeshift fera un backup automatisé du système (tout sauf /home) en utilisant btrfs. C'est une excellente idée, et permet de revenir en arrière en cas de mise à jour ou bidouillage du système qui pose problème, sans que cela impact les données utilisateur.

Timeshift utilisant les fonctionnalités btrfs, les snapshots sont instantanés.

Timeshit a une GUI pour simplifier la configuration automatisée des snapshots et permet aussi de les consulter facilement.


Migration de version de Linux Mint par ré-installation

Quand je change de version de Linux Mint/Ubuntu, je procède par ré-installation. Cependant, même si Linux Mint supporte btrfs, l'installeur de Mint (Ubiquity) ne permet pas de spécifier des sous-volumes précis pour l'installation.

L'installeur Ubiquity supporte malgré tout btrfs, et créé automatiquement dans la partition btrfs:

Voici comment procéder pour upgrader Mint par ré-installation sans perdre votre @home:


Questions


Liens, sources


Après 7 mois sous btrfs

Voici donc un petit bilan après avoir passé ma machine personnelle d'ext4 en btrfs il y a 7 mois (j'ai migré en novembre 2019, nous sommes en juin 2020).

Alors c'est un gros oui. Je continue sous btrfs. Je gagne énormément de la place, je réduis les I/O disque, et j'ai des outils de snapshot extrêmement pratiques.

Comme avec la compression la quantité globales de données écrites et lues sur disque est moindre:

Histoire de vous donner un ordre d'idée, sur ma machine de travail:


PS: Puisqu'on me pose des questions: