Le provisionnement fin est une réunion budgétaire déguisée en fonctionnalité de stockage. Tout a l’air parfait jusqu’à ce que la réalité présente la facture.
Avec les volumes sparsés ZFS (zvols thin), vous pouvez allouer plus de « disque » que ce que vous possédez physiquement — volontairement. Ce n’est pas intrinsèquement mauvais.
Le problème, c’est d’y recourir sans rigueur, puis de faire semblant d’être surpris quand un pool atteint 100 % et que l’onde de choc ressemble à un exercice de confiance à l’échelle d’un datacenter.
Ce guide pratique explique le piège du surengagement : ce qui s’épuise réellement en premier, ce qui casse, à quoi ressemblent les signaux,
et exactement quoi vérifier quand ça sent le brûlé. Vous aurez des commandes concrètes, la signification des sorties et les décisions à prendre.
Ce que signifient réellement les « volumes sparse » dans ZFS
Dans ZFS, un zvol est un périphérique bloc soutenu par un dataset. On l’utilise pour des VM, des LUN iSCSI, des bases de données qui exigent un périphérique bloc brut,
ou tout système qui pense en blocs plutôt qu’en fichiers. Un zvol « sparse » est thin-provisioned : son volsize (la taille présentée) peut être plus grande que
l’espace actuellement alloué dans le pool.
Voici l’essentiel : sparse ne veut pas dire gratuit. Cela signifie « alloué à l’écriture ». Le pool reste le pool. Si les consommateurs écrivent suffisamment,
ZFS doit allouer de vrais blocs. Quand il ne peut pas, il renvoie des erreurs. Ces erreurs se propagent vers votre système de fichiers invité, votre base de données ou votre hyperviseur,
généralement de la manière la moins polie possible.
Pourquoi les gens aiment les zvols sparse ? Parce que l’alternative est du pessimisme : préallouer la capacité totale pour chaque VM ou LUN signifie acheter des disques tôt, puis
passer des années à admirer l’espace vide pour lequel vous avez payé. Le provisionnement fin est pragmatique. Le problème, c’est que c’est aussi une promesse que vous pouvez rompre.
Les deux nombres que vous devez dissocier dans votre tête
- Taille logique : ce que vous avez dit au client qu’il peut utiliser (
volsize). - Allocation physique : ce que ZFS a réellement alloué dans le pool pour ce zvol (plus métadonnées, parité, copies, etc.).
Le surengagement survient lorsque la somme des tailles logiques dépasse la capacité physique. Ce n’est pas immédiatement incorrect.
Cela devient problématique quand les schémas d’écriture (ou le calendrier) exigent la réalisation de ces promesses logiques.
Le piège du surengagement : pourquoi ça échoue si abruptement
Le provisionnement fin échoue ainsi : tout semble aller bien, puis soudainement non. C’est parce que la consommation de stockage est en grumeaux.
Sauvegardes, jobs hebdomadaires, pics de logs, chaînes de snapshots VM, compactage de base de données, réindexations et « on a migré des données » allouent des blocs réels rapidement.
Des pools qui stagnent à 70 % pendant des mois peuvent bondir à 95 % en un jour, puis atteindre 100 % en une heure.
ZFS n’est pas indulgent quand il s’agit d’épuisement d’espace. Des pools presque pleins déclenchent fragmentation, douleur pour l’allocateur et pression sur les métadonnées.
Quand le pool est vraiment plein, vous obtenez ENOSPC puis des défaillances en cascade : disques de VM en lecture seule, bases de données paniquées, ou hyperviseur incapable d’écrire
les logs nécessaires à la récupération. Le provisionnement fin est l’accélérant ; le véritable incendie est la complaisance opérationnelle.
Il y a aussi une subtilité : même si le pool affiche « un peu d’espace libre », vous pouvez quand même échouer des allocations à cause de l’espace de slop,
de la fragmentation, des effets de recordsize/volblocksize et des métadonnées qui doivent être écrites pour rester cohérentes.
L’espace libre n’est pas un seul chiffre. C’est « l’espace libre qui est allouable dans la forme et la classe requises ».
Blague n°1 : Le provisionnement fin, c’est comme commander un pantalon « un jour j’y rentrerai ». Le jour arrive à 2h du matin, et votre ceinture est le pager.
Ce qui casse en premier dans la vraie vie
- Les systèmes de fichiers invités voient des erreurs d’E/S. Le journalisme aide jusqu’à un certain point.
- Les bases de données subissent des écritures partielles ou ne peuvent pas étendre des fichiers, puis lancent une récupération de crash au pire moment.
- Les hyperviseurs peuvent mettre des VM en pause, marquer des disques comme défaillants ou échouer les snapshots.
- La réplication peut stagner parce qu’elle ne peut pas écrire les buffers de réception ou de nouveaux snapshots.
- ZFS lui-même peine à libérer de l’espace si vous devez supprimer des snapshots mais ne pouvez pas écrire les mises à jour de métadonnées de manière fiable.
Qu’un pool dépasse ~80–85 % n’est pas une faute morale. C’est un signal. Vous pouvez fonctionner plus haut si vous connaissez la charge et si vous êtes discipliné.
Mais avec le provisionnement fin, la discipline signifie surveillance et marge, pas optimisme et vibes.
Faits et contexte intéressants (ce qui explique les étrangetés)
- ZFS a introduit le stockage en pool comme idée de premier plan, donc « système de fichiers plein » est devenu « pool plein ». Cela déplace les domaines de défaillance d’un seul point de montage vers tout le pool.
- Le provisionnement fin a été popularisé dans les SAN d’entreprise bien avant que les zvols ZFS ne soient courants ; ZFS a hérité des avantages et des arêtes vives.
- La comptabilité d’espace dans ZFS est volontairement conservatrice à plusieurs endroits (espace slop, réservations de métadonnées) pour prévenir les impasses catastrophiques.
- Le copy-on-write signifie que les écrasements allouent d’abord de nouveaux blocs, puis libèrent les anciens plus tard. Les pools presque pleins punissent les charges de travail « mises à jour en place ».
- Les snapshots n’« utilisent » pas d’espace à la création, mais ils épinglent les anciens blocs. Les suppressions et les écrasements deviennent de nouvelles allocations au lieu de réutilisation.
- La compression change les mathématiques du surengagement car logicalused peut être bien plus grand que l’usage physique — jusqu’à ce que les données deviennent incompressibles (bonjour, sauvegardes chiffrées).
- L’overhead de parité RAIDZ dépend du profil de charge : les petites écritures aléatoires peuvent amplifier les allocations à cause du padding et de l’alignement des enregistrements (varie selon l’implémentation et ashift).
- Les classes d’allocation spéciales (special vdevs) peuvent déplacer métadonnées/petits blocs hors des disques rotatifs, mais elles créent un autre précipice de capacité si elles sont sous-dimensionnées.
- Le support du discard/TRIM a mis du temps à mûrir dans l’écosystème de virtualisation ; les invités qui n’émettent pas de discard empêchent ZFS d’apprendre que des blocs sont libres.
Mécanismes importants : volsize, referenced, logicalused et les blocs inévitables
Zvols sparse : propriétés qui décident de votre destin
ZFS vous donne une poignée de leviers. La plupart des gens n’en tirent qu’un (créer sparse) et ignorent les autres. C’est ainsi que l’on se retrouve avec un pool « mystérieusement » plein.
volsize: la taille exposée du périphérique bloc. C’est la promesse.refreservation: espace garanti pour le dataset (zvol). C’est le levier « nous ne surengagerons pas cette portion ».reservation: concept similaire pour les systèmes de fichiers ; pour les zvols on utilise typiquementrefreservation.volblocksize: granularité d’allocation pour le zvol ; impacte performance et efficacité d’espace.compression: peut étendre considérablement la marge — jusqu’à ce que vos données ne soient plus compressibles.sync: comment ZFS gère les écritures synchrones ; le modifier peut changer comportement et performance en cas de défaillance.
Termes de comptabilité d’espace que vous devez savoir lire rapidement
Pour les zvols, USED et ses amis dans zfs list sont faciles à mal comprendre. Ajoutez ces colonnes et le monde devient plus clair :
used: espace réellement consommé dans le pool (y compris métadonnées et copies selon la vue).referenced: espace accessible par ce dataset à sa tête (sans compter les snapshots).logicalused: octets logiques non compressés référencés (utile pour vérifier la réalité du ratio de compression).logicalreferenced: référencé logique à la tête du dataset.usedbysnapshots: espace épinglé par les snapshots ; le coupable du « pourquoi la suppression ne libère pas d’espace ».
La partie que personne ne budgète : métadonnées, fragmentation et « espace qu’on ne peut pas dépenser »
ZFS a besoin d’air pour respirer. Quand vous approchez du plein, l’allocateur a moins de choix, les metaslabs se fragmentent,
et les écritures ralentissent. Ce ralentissement peut lui-même déclencher plus d’écritures : timeouts, retries, croissance des logs, fichiers de récupération de crash.
C’est une boucle de rétroaction avec un sens de l’humour que vous ne partagerez pas.
Une idée de fiabilité pertinente vient de la culture d’ingénierie plus que des spécificités ZFS :
L’espoir n’est pas une stratégie.
(idée paraphrasée souvent attribuée à la formation opérations/fiabilité)
Si vous exécutez des zvols sparse sans réservations, vous faites fonctionner un système où l’espoir est littéralement le modèle de capacité.
Vous pouvez faire mieux.
Signaux de surveillance qui prédisent vraiment la panne
Surveiller le provisionnement fin n’est pas « alerter quand le pool est à 90 % ». C’est une alerte parmi d’autres, et elle arrive tard.
Vous voulez un petit ensemble de signaux qui expliquent à la fois la capacité et le taux de changement, plus « les choses qui rendent la récupération impossible ».
Signaux à suivre (et pourquoi)
- % alloué du pool (
zpool list) : le grand évident. Suivez la tendance, pas seulement le moment présent. - Espace libre par classe (
zpool list -vsur certaines plateformes ; aussizpool status) : les special vdevs et log vdevs ont leurs propres précipices. - Espace des snapshots (
usedbysnapshots) : un pool peut être « plein » parce que la rétention le grignote en silence. - Taux de surengagement : somme des
volsizedes zvols divisée par la taille physique du pool (et/ou par le « usable safe »). - Données sales / pression txg (
zfs-statsou équivalents plateforme) : les pics corrèlent souvent avec de gros bursts d’écriture. - Indicateurs d’amplification d’écriture : IOPS élevés avec débit modéré, latence en hausse et fragmentation de l’allocateur (histogrammes metaslab).
- Dérive du ratio de compression : quand de nouvelles charges sont incompressibles, la courbe de consommation monte en flèche.
- Efficacité du discard : si les invités émettent discard et si cela entraîne la libération d’espace côté ZFS au fil du temps.
Seuils d’alerte qui disent rarement des mensonges
Utilisez des alertes échelonnées, pas un grand cliff unique :
- 75% : « attention ». Vérifiez la tendance de croissance et la rétention des snapshots. Commencez à planifier.
- 85% : « action ». Geler les snapshots non essentiels, valider l’espace pour la réplication, s’assurer que les suppressions libèrent effectivement.
- 90% : « changer de mode ». Arrêtez de créer de nouveaux volumes thin. Déplacez des charges. Ajoutez des vdevs ou réduisez la rétention. Traitez comme prévention d’incident.
- 95% : « incident ». Vous payez maintenant la taxe de fragmentation et risquez des échecs d’allocation. Exécutez un runbook, pas un débat.
Ces seuils dépendent de la charge et de la topologie des vdevs. RAIDZ plus écritures aléatoires exige plus de marge que des miroirs avec écritures principalement séquentielles.
Mais si vous provisionnez fin et que vous ne connaissez pas la forme de votre charge, choisissez des seuils conservateurs et profitez de vos nuits.
Tâches pratiques : commandes, interprétation, décisions
Cette section est volontairement opérationnelle. Le but n’est pas d’admirer ZFS. Le but est de savoir quoi faire à 3h du matin.
Chaque tâche inclut une commande exécutable, ce que signifie la sortie, et la décision à prendre.
Task 1: Check pool capacity and health fast
cr0x@server:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 21.8T 18.9T 2.90T - - 41% 86% 1.00x ONLINE -
Ce que ça veut dire : CAP 86% est dans la zone « action ». FRAG 41% suggère que la douleur de l’allocateur arrive.
Décision : Arrêter les écritures non essentielles (tempêtes de snapshots, migrations). Commencer la revue snapshots/rétention et le plan de capacité maintenant.
Task 2: Confirm no devices are failing while you chase “space” ghosts
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
scan: scrub repaired 0B in 09:12:44 with 0 errors on Sun Dec 22 09:12:55 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 1
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/vmstore/zvol-104-disk-0
Ce que ça veut dire : Il y a une erreur de checksum associée à un zvol spécifique. Ce n’est pas un problème de capacité, mais ça peut s’en déguiser.
Décision : Trier l’intégrité des données séparément : vérifier le disque invité, les résultats du scrub, envisager de remplacer le disque et restaurer les données de la VM affectée si nécessaire.
Task 3: List zvols and spot the overcommit picture
cr0x@server:~$ zfs list -t volume -o name,volsize,used,referenced,logicalused,refreservation -r tank/vmstore
NAME VOLSIZE USED REFER LUSED REFRESERV
tank/vmstore/vm-101-disk-0 500G 412G 401G 603G none
tank/vmstore/vm-102-disk-0 2T 1.31T 1.28T 1.28T none
tank/vmstore/vm-103-disk-0 1T 74G 72G 92G none
tank/vmstore/vm-104-disk-0 4T 3.61T 3.55T 3.55T none
Ce que ça veut dire : Ce sont des sparse (pas de refreservation). Les promesses de taille logique sont importantes. Il y a de la compression (vm-101 montre logical > physical).
Décision : Si c’est en production, choisissez : définir refreservation pour les zvols critiques, ou imposer une marge stricte du pool avec alertes et gestion de capacité.
Task 4: Calculate “promised capacity” (sum of volsize)
cr0x@server:~$ zfs list -H -p -t volume -o volsize -r tank/vmstore | awk '{s+=$1} END{printf("total_volsize_bytes=%d\n",s)}'
total_volsize_bytes=8246337208320
Ce que ça veut dire : Vous avez promis ~8.2 TB aux invités dans ce sous-arbre. Ce chiffre seul n’est pas diabolique ; il faut du contexte.
Décision : Comparez à l’espace utilisable du pool (après parité, politique slop_space et croissance). Définissez un ratio maximal de surengagement et faites-le respecter.
Task 5: See snapshot pressure for a dataset tree
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbydataset,usedbychildren -r tank/vmstore | head -n 8
NAME USED USEDSNAP USEDDS USEDCH
tank/vmstore 6.12T 2.04T 4.01T 77.6G
tank/vmstore/vm-101 622G 211G 401G 9.6G
tank/vmstore/vm-102 1.53T 243G 1.28T 12.4G
tank/vmstore/vm-103 119G 42.1G 72G 4.9G
tank/vmstore/vm-104 3.85T 1.52T 3.55T 18.6G
Ce que ça veut dire : 2 To en snapshots n’est pas « gratuit ». C’est alloué et épinglé. Supprimer dans les invités ne le libérera pas.
Décision : Si la capacité est tendue, ajustez la rétention. Supprimez les snapshots stratégiquement (les plus anciens, les plus gros deltas), et confirmez d’abord les dépendances de réplication.
Task 6: Identify the top space consumers quickly
cr0x@server:~$ zfs list -o name,used,usedbysnapshots -s used -r tank/vmstore | tail -n 6
tank/vmstore/vm-103 119G 42.1G
tank/vmstore/vm-101 622G 211G
tank/vmstore/vm-102 1.53T 243G
tank/vmstore/vm-104 3.85T 1.52T
Ce que ça veut dire : vm-104 porte un gros ballast de snapshots.
Décision : Si vous avez besoin d’un gain rapide, les charges heavy en snapshots sont les plus « récupérables » — après validation des exigences métiers/sauvegardes.
Task 7: Verify compression reality (and detect the “encrypted backup ruined it” moment)
cr0x@server:~$ zfs get -H -o name,property,value compression,compressratio -r tank/vmstore | head
tank/vmstore compression zstd
tank/vmstore compressratio 1.24x
tank/vmstore/vm-101 compression zstd
tank/vmstore/vm-101 compressratio 1.46x
tank/vmstore/vm-102 compression zstd
tank/vmstore/vm-102 compressratio 1.02x
Ce que ça veut dire : vm-102 est essentiellement incompressible. Si elle croît, elle mangera de l’espace brut presque à 1:1.
Décision : Ne comptez pas sur les économies de compression pour les charges qui chiffrent au repos à l’intérieur de l’invité ou stockent des blobs déjà compressés. Planifiez la capacité comme si c’était 1.0x.
Task 8: Check reservations/refreservations (a.k.a. “who is allowed to sink the ship”)
cr0x@server:~$ zfs get -o name,property,value -r tank/vmstore | egrep 'refreservation|reservation' | head -n 12
tank/vmstore reservation none
tank/vmstore refreservation none
tank/vmstore/vm-101 reservation none
tank/vmstore/vm-101 refreservation none
tank/vmstore/vm-102 reservation none
tank/vmstore/vm-102 refreservation none
Ce que ça veut dire : Personne n’a d’espace garanti. Ça signifie que le dernier écrivain gagne jusqu’à ce que le pool perde.
Décision : Pour les volumes « must not fail » (bases de données, plan de contrôle, identité), définissez refreservation afin qu’ils puissent continuer à écrire même sous pression.
Task 9: Set a refreservation for a critical zvol (and understand the consequence)
cr0x@server:~$ sudo zfs set refreservation=600G tank/vmstore/vm-101-disk-0
cr0x@server:~$ zfs get -H -o name,property,value refreservation tank/vmstore/vm-101-disk-0
tank/vmstore/vm-101-disk-0 refreservation 644245094400
Ce que ça veut dire : ZFS réserve maintenant ~600G pour ce volume. L’espace libre du pool diminue en conséquence.
Décision : C’est ainsi que vous empêchez les charges critiques d’être étouffées par le job d’un autre. Utilisez-le intentionnellement ; cela réduit la flexibilité.
Task 10: Check ashift and vdev layout (capacity math depends on it)
cr0x@server:~$ zdb -C tank | egrep 'ashift|raidz|mirror' | head -n 20
ashift: 12
type: 'raidz'
nparity: 2
Ce que ça veut dire : ashift 12 implique des secteurs 4K. RAIDZ2 parité présente. Les petites écritures peuvent s’amplifier.
Décision : Si vous êtes déjà serré sur l’espace, changer les schémas de charge (plus d’écritures aléatoires, blocs plus petits) peut accélérer la consommation et la fragmentation. Intégrez-le au risque.
Task 11: Inspect free space fragmentation and metaslab histograms
cr0x@server:~$ sudo zdb -mm tank | head -n 40
Metaslab 0:
size 1090519040
alloc 1019215872
free 71303168
free segments: 142
histogram:
000: ------------------------------------------------------------
001: ******************* 19
002: ***************************** 29
003: ******************** 20
Ce que ça veut dire : Beaucoup de petits segments libres signifie « il y a de l’espace libre mais il est morcelé ». L’allocation devient plus lente et peut échouer pour des besoins contigus plus importants.
Décision : Considérez la haute fragmentation + haute capacité comme un multiplicateur de risque. Créez de la marge en libérant de l’espace et en évitant l’agitation (snapshots, réécritures).
Task 12: Confirm guest discard is enabled (thin provisioning without discard is a lie)
cr0x@server:~$ lsblk -D
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda 0 512B 2G 0
sdb 0 512B 2G 0
Ce que ça veut dire : Les périphériques bloc exposent la granularité de discard. C’est nécessaire mais pas suffisant.
Décision : Assurez-vous que l’hyperviseur transmet discard/TRIM et que le système de fichiers invité l’émet (options de montage, timer fstrim). Sinon les suppressions ne seront pas récupérées.
Task 13: Observe whether freeing data actually reclaims on the host
cr0x@server:~$ zfs get -H -o name,property,value written tank/vmstore/vm-101-disk-0
tank/vmstore/vm-101-disk-0 written 103215702016
Ce que ça veut dire : written peut aider à estimer le churn récent. Si les invités « ont supprimé beaucoup » mais que used ne baisse pas, suspectez des snapshots ou l’absence de discard.
Décision : Si les snapshots épinglent les blocs, le discard ne servira à rien. Si les snapshots sont minimes, activez le discard de bout en bout et lancez des trims.
Task 14: Find datasets with huge snapshot deltas (fast reclaim candidates)
cr0x@server:~$ zfs list -t snapshot -o name,used,referenced -s used -r tank/vmstore | tail -n 5
tank/vmstore/vm-104@auto-2025-12-20 188G 3.55T
tank/vmstore/vm-104@auto-2025-12-21 201G 3.55T
tank/vmstore/vm-104@auto-2025-12-22 214G 3.55T
tank/vmstore/vm-102@auto-2025-12-22 61G 1.28T
tank/vmstore/vm-101@auto-2025-12-22 49G 401G
Ce que ça veut dire : Les snapshots avec un grand USED consomment beaucoup de blocs uniques. En supprimer peut libérer un espace significatif.
Décision : Si la réplication le permet, supprimez d’abord les snapshots les plus grands/anciens. Si la réplication en dépend, il vous faut un autre plan (augmenter la capacité ou ajuster la réplication).
Task 15: When near-full, check slop space impact
cr0x@server:~$ zfs get -H -o property,value slop_space tank
slop_space 12884901888
Ce que ça veut dire : ZFS garde une partie d’espace effectivement hors-limites pour réduire les scénarios « le pool est si plein qu’il ne peut pas fonctionner ».
Décision : Ne comptez pas utiliser les derniers Go/To. Planifiez pour ne jamais voir 100 % en dehors d’un labo. Si vous atteignez slop_space, vous êtes déjà en retard.
Task 16: Check if you can even delete (sometimes you can’t, and that’s the horror story)
cr0x@server:~$ sudo zfs destroy tank/vmstore/vm-104@auto-2025-12-20
cannot destroy 'tank/vmstore/vm-104@auto-2025-12-20': out of space
Ce que ça veut dire : Vous êtes dans la zone « on ne peut pas libérer d’espace parce que libérer de l’espace nécessite de l’espace » (les mises à jour de métadonnées demandent encore des allocations).
Décision : Arrêtez toutes les écritures, exportez les datasets non critiques si possible, ajoutez de l’espace (attachez temporairement un vdev) ou libérez de l’espace depuis un autre pool via send/receive. C’est un incident.
Blague n°2 : Un pool à 99 % de remplissage est comme une réunion qui « ne prendra que cinq minutes ». Tout le monde sait ce qui se passe ensuite.
Guide de diagnostic rapide
Quand un environnement thin-provisioned devient étrange, les gens argumentent sur le « stockage » comme si c’était la météo. Ne faites pas ça.
Exécutez une courte séquence qui vous dit : sommes-nous à court d’espace, d’intégrité ou de vérité ?
Première étape : confirmer le mode de défaillance (capacité vs intégrité vs performance)
- Capacité du pool et fragmentation :
zpool list. Si CAP > 85% et FRAG en hausse, traitez comme incident de pression sur la capacité même si vous n’êtes pas « plein ». - État du pool :
zpool status -v. Si des erreurs existent, corrigez l’intégrité avant de chasser la « mathématique du thin provisioning ». - Épinglage par snapshots :
zfs list -o usedbysnapshotssur l’arbre concerné. Si l’usage des snapshots est important, les suppressions dans les invités ne serviront à rien.
Seconde étape : localiser le consommateur et le taux de croissance
- Top datasets/zvols par USED :
zfs list -s used. - Top snapshots par USED :
zfs list -t snapshot -s used. - Indicateurs de churn :
zfs get writtensur les coupables probables ; corrélez avec les horaires de jobs et l’activité VM.
Troisième étape : décider si vous pouvez récupérer ou devez étendre
- Si récupérable : supprimer des snapshots (avec prudence), réduire la rétention, activer discard, compacter dans les invités là où cela libère effectivement des blocs.
- Si pas récupérable rapidement : ajouter de la capacité (nouveaux vdevs) ou déplacer des charges hors du pool ; n’essayez pas d’improviser sur un pool à 95–100 %.
- Protéger les charges critiques : appliquer
refreservationpour les zvols essentiels avant de commencer à supprimer les mauvaises choses.
Erreurs courantes (symptôme → cause racine → correction)
1) « Les invités montrent de l’espace libre, mais les écritures échouent avec ENOSPC »
Symptôme : Le système de fichiers de la VM montre de l’espace, les applications renvoient des erreurs, les logs de l’hyperviseur indiquent « No space left on device ».
Cause racine : Le pool ZFS est plein (ou effectivement plein à cause du slop_space / fragmentation). L’invité ne peut pas voir l’épuisement du pool hôte jusqu’à l’échec des écritures.
Correction : Libérez immédiatement de l’espace pool (supprimer snapshots, déplacer des datasets), ajoutez de la capacité, puis imposez des marges d’alerte et éventuellement refreservation pour les disques critiques.
2) « Supprimer des fichiers dans l’invité ne libère pas d’espace sur le pool »
Symptôme : L’usage dans l’invité baisse ; USED dans ZFS ne baisse pas.
Cause racine : Les snapshots épinglent les blocs, ou le discard ne fonctionne pas de bout en bout, ou le système de fichiers invité n’émet pas de trim.
Correction : Vérifiez usedbysnapshots. Si élevé, supprimez/expirez les snapshots. Si faible, activez discard dans l’hyperviseur + invité et planifiez des fstrim périodiques.
3) « Le pool est à 88 % et tout est lent »
Symptôme : Pics de latence, pauses de VM, écritures sync qui ralentissent.
Cause racine : Fragmentation et contention de l’allocateur à des niveaux de remplissage élevés ; le copy-on-write amplifie les petites réécritures ; RAIDZ peut magnifier les petites écritures aléatoires.
Correction : Créez de la marge (objectif <80–85%), réduisez l’agitation (snapshots, réécritures fréquentes), ajustez les tailles de blocs si approprié, et considérez un changement de layout pour la prochaine build (miroirs pour charges IOPS élevées).
4) « Nous avons opté pour le thin provisioning parce que la compression nous sauverait »
Symptôme : La courbe de croissance du pool s’accentue soudainement.
Cause racine : Les nouvelles données sont incompressibles (sauvegardes chiffrées, médias, archives déjà compressées). Les hypothèses de ratio de compression deviennent de la fantaisie.
Correction : Surveillez la dérive du compressratio et planifiez avec 1.0x pour les charges non fiables. Déplacez les données incompressibles vers des pools ou des niveaux séparés.
5) « La suppression de snapshots prend une éternité, et l’espace ne revient pas »
Symptôme : La destruction des snapshots est lente ; le pool reste sous pression.
Cause racine : Fragmentation élevée et chaînes massives de snapshots rendent les frees coûteuses ; de plus l’espace revient progressivement à mesure que les mises à jour de métadonnées se complètent.
Correction : Supprimez les snapshots par lots hors-peak, évitez les chaînes gigantesques, gardez de la marge, et envisagez de réviser la stratégie de sauvegarde (moins de snapshots longue durée, plus de rétentions incrémentales ailleurs).
6) « Nous ne pouvons pas supprimer les snapshots car le pool est à court d’espace »
Symptôme : zfs destroy retourne out-of-space.
Cause racine : Le pool est si plein que les opérations métadonnées ne peuvent pas allouer ; vous êtes au-delà du « nettoyage » et en mode « stabiliser ».
Correction : Arrêtez les écritures, ajoutez une capacité temporaire (un nouveau vdev est l’approche propre), ou évacuez des datasets via send/receive si possible. Ensuite, appliquez des plafonds opérationnels stricts.
Trois mini-histoires d’entreprise issues des tranchées du thin-provisioning
Mini-histoire 1 : L’incident causé par une mauvaise hypothèse
Une entreprise SaaS de taille moyenne exploitait un cluster de virtualisation propre avec des zvols sur ZFS. L’équipe stockage était à l’aise avec le provisionnement fin parce que « les VM ne remplissent jamais leurs disques ».
C’était vrai, jusqu’à ce que ce ne le soit plus.
Un trimestre, la finance a voulu une rétention plus longue pour les logs d’audit. L’équipe applicative a obtempéré en augmentant la verbosité des logs et en conservant plus d’historique sur les mêmes disques VM.
Personne n’a prévenu le stockage. Personne n’a pensé en avoir besoin.
Deux semaines plus tard, le pool a atteint le haut des 80s. Les performances sont devenues molles, mais rien ne criait. Puis une fenêtre de maintenance a démarré : snapshots VM pour sauvegarde, plus une mise à jour d’application qui a réécrit de gros datasets.
Le copy-on-write a fait son œuvre : les overwrites ont nécessité des allocations fraîches. Le pool a sprinté de « inconfortable » à « plein » plus vite que la surveillance n’a pu alerter.
Le premier symptôme visible n’était pas « pool plein ». C’étaient des écritures de base de données qui échouaient dans une VM, suivies de boucles de crash et d’erreurs « système de fichiers en lecture seule ».
Le canal d’incident s’est rempli de théories : problèmes SAN, bug noyau, « peut-être que l’hyperviseur est instable ».
La correction fut ennuyeuse : supprimer d’anciens snapshots, réduire la rétention et ajouter un vdev. La leçon n’était pas « le thin provisioning est malveillant ».
La leçon était que le provisionnement fin est un contrat, et le contrat n’avait jamais été rédigé.
Mini-histoire 2 : L’optimisation qui s’est retournée contre eux
Dans une grande entreprise, une équipe plateforme cherchait une meilleure efficacité de stockage. Ils ont activé des snapshots agressifs — horaires pendant une semaine, quotidiens pendant un mois — sur les datasets zvol VM.
Les graphiques avaient fière allure : restauration rapide, moins de tickets de backup.
Puis ils ont introduit une nouvelle charge CI avec beaucoup de VM éphémères. Ces VM écrivaient, supprimaient, réécrivaient, et répétaient. À l’intérieur des invités, les fichiers allaient et venaient constamment.
Sur ZFS, avec des snapshots, supprimer ne veut pas dire « libérer ». Cela signifie « libérer plus tard, si rien ne référence les anciens blocs ». Les snapshots référençaient tout.
L’usage d’espace a augmenté régulièrement, mais l’équipe se rassurait : « les snapshots valent le coup ». Le pool est resté sous 80 % pendant un moment.
Le piège était que la fragmentation montait et que la chaîne de snapshots transformait chaque overwrite en allocation nette nouvelle.
Quand le pool a dépassé les hauts 80s, la latence a explosé. Les jobs CI ont ralenti, provoquant des timeouts. Les timeouts ont entraîné des retries. Les retries ont provoqué plus d’écritures.
Ce n’était pas juste une pression de capacité ; c’était une spirale d’amplification d’écritures provoquée par une « optimisation » que personne n’avait réévaluée.
Ils ont réglé le problème en séparant les classes de charge : les VM CI sont passées sur un pool avec une politique de snapshot différente (rétention courte), et les snapshots « golden rollback » ont été conservés pour les systèmes stateful de longue durée uniquement.
Le snapshoting n’a pas été supprimé. Il est devenu intentionnel.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une entreprise de santé exploitait des zvols ZFS pour des systèmes critiques. Leur lead stockage insistait sur deux règles :
garder l’utilisation du pool sous un plafond strict, et définir refreservation sur la poignée de volumes qui ne doivent jamais rater d’écritures.
Ce n’était pas populaire. Les réservations font paraître les pools « plus petits », et les dashboards aiment les grands nombres d’espace libre.
Lors d’une clôture de fin de mois routinière, un système de reporting est parti en vrille et a commencé à générer d’énormes fichiers intermédiaires sur son disque VM.
Il a consommé ce qui lui avait été promis. Sur une configuration thin sans garde-fous, cela aurait été le problème de tout le monde.
Au lieu de cela, la VM de reporting a rencontré des erreurs d’E/S et a cessé de croître. C’était désagréable, mais contenu.
Les volumes de base de données et les services d’identité ont conservé leur espace garanti et sont restés sains.
L’équipe opérations a eu le temps de répondre : étendre correctement le disque de reporting, rééquilibrer la rétention et ajouter de la capacité selon le calendrier plutôt que dans la panique.
Rien n’a fait les gros titres. C’est tout l’intérêt.
Listes de contrôle / plan étape par étape
Checklist A : Avant d’activer des zvols sparse en production
- Définir une politique de surengagement : ratio maximum, quels locataires peuvent surengager, et ce qui se passe quand les seuils sont dépassés.
- Choisir des cibles de marge : un plafond dur pour le CAP du pool (généralement 80–85 % pour charges mixtes ; plus conservateur pour RAIDZ + écritures aléatoires).
- Décider quels volumes sont « must write » : définir
refreservationpour ceux-ci, et accepter la perte visible d’espace libre comme le coût de la fiabilité. - Rétention de snapshots par classe : n’appliquez pas la même rétention aux disques scratch CI et aux bases de données.
- Plan discard/TRIM : confirmer que l’hyperviseur et les invités le supportent ; planifier
fstrimou équivalent. - Surveillance & alerting : CAP du pool, FRAG, usage snapshots, dérive du compressratio, et alertes sur le taux de changement.
Checklist B : Revue opérationnelle hebdomadaire (15 minutes, évite un week-end)
- Vérifier
zpool listpour les tendances CAP et FRAG. - Vérifier l’usage des meilleurs snapshots avec
zfs list -o usedbysnapshots. - Revoir les datasets/zvols en forte croissance :
zfs list -s used. - Valider que les scrubs se complètent et sont propres :
zpool status. - Repérer les changements de compressratio sur les datasets majeurs.
- Confirmer que les cibles de réplication ont aussi de la marge (le provisionnement fin aux deux bouts, c’est la recette d’un désastre synchronisé).
Checklist C : Quand le pool atteint 85% (traiter comme un incident contrôlé)
- Geler l’agitation : suspendre migrations massives, suspendre les jobs snapshots non essentiels, arrêter les pipelines de test qui thrashent le disque.
- Identifier l’espace récupérable : plus grands snapshots, datasets lourds en snapshots.
- Confirmer le chemin de discard : si vous comptez sur la récupération via suppression, vérifiez que c’est même possible.
- Protéger les écrivains critiques : appliquer
refreservationsi absent, avant que la situation n’empire. - Décider expansion vs récupération : si vous ne pouvez pas récupérer assez en toute sécurité, planifier un ajout de capacité immédiatement.
Checklist D : Quand le pool atteint 95% (arrêtez l’improvisation)
- Arrêter les écritures partout où c’est possible (throttles applicatifs, pause création VM, halt des rafales de snapshots de sauvegarde).
- Ne lancez pas de « scripts de nettoyage » aléatoires ; vous supprimerez ce qui est facile, pas ce qui est efficace.
- Prioriser la suppression de gros snapshots sûrs à retirer (valider la réplication et les exigences de restauration).
- Préparer l’ajout d’un vdev. C’est souvent la sortie sûre la plus rapide.
- Après stabilisation : post-mortem de la politique de surengagement et implémentation d’alertes sur le taux de changement.
FAQ
1) Les zvols sparse sont-ils identiques au « thin provisioning » d’un SAN ?
Conceptuellement, oui : vous présentez plus de capacité logique que ce que vous avez physiquement alloué. Opérationnellement, ZFS ajoute le copy-on-write, les snapshots et l’allocation en pool,
ce qui peut rendre les modes de défaillance plus abrupts si vous poussez la capacité.
2) Le surengagement est-il toujours mauvais ?
Non. Le surengagement est un outil. Il devient problématique quand vous ne le mesurez pas, ne le plafonnez pas, et ne gardez pas de marge pour les pics et le comportement copy-on-write.
Si vous ne pouvez pas expliquer votre ratio de surengagement et votre plan de récupération, vous ne surengagez pas — vous jouez.
3) Dois-je utiliser refreservation sur chaque zvol ?
En général non. Réserver tout annule l’intérêt du thin provisioning. Utilisez-le sur les volumes critiques où l’échec d’écriture est inacceptable (bases de données, plan de contrôle, services partagés),
et comptez sur la marge + alertes pour le reste.
4) Pourquoi ZFS devient-il lent quand le pool est presque plein ?
Parce que les allocateurs aiment avoir le choix. Les pools presque pleins ont moins de segments libres, une fragmentation plus élevée, et le copy-on-write rend les overwrites coûteux.
Sur RAIDZ, les petites écritures aléatoires peuvent ajouter un surcoût. Le résultat est une inflation de latence et un effondrement du débit.
5) Puis-je compter sur la suppression de données dans les invités pour récupérer de l’espace sur le pool ?
Seulement si deux choses sont vraies : les snapshots ne pinent pas ces blocs, et le discard/TRIM fonctionne de bout en bout.
Sans discard, l’hôte ne peut souvent pas savoir que des blocs sont libres. Avec des snapshots, ils ne sont pas libres même si l’invité supprime.
6) Quelle est la manière la plus sûre de récupérer rapidement de l’espace ?
Supprimer de gros snapshots anciens qui ont un USED significatif est souvent le moyen le plus prévisible de récupérer — en supposant que vous avez validé la réplication et les besoins de restauration.
Supprimer des fichiers aléatoirement dans des invités est moins prévisible sauf si vous savez que le discard est effectif et que les snapshots ne vous retiennent pas en otage.
7) La compression et la déduplication changent-elles le risque de surengagement ?
La compression peut beaucoup aider, mais c’est dépendant de la charge et peut évoluer. La dédup peut être dangereuse opérationnellement à cause de la pression mémoire et de la complexité ;
elle ne résout pas le fait fondamental que les écritures nécessitent des blocs physiques. Modélisez le risque comme si la compression pouvait chuter à 1.0x.
8) Comment définir l’alerte spécifique au thin provisioning ?
Alertez sur le CAP du pool avec plusieurs seuils, suivez la croissance de l’usage des snapshots, et suivez le ratio de surengagement (somme des volsize vs pool utilisable).
Ajoutez des alertes sur le taux de changement : « pool used +5% en 1 heure » capture les bursts que les seuils statiques ratent.
9) Quel est un ratio de surengagement raisonnable ?
Il n’y a pas un chiffre universel. Pour des fermes VM d’entreprise prévisibles avec une bonne hygiène, 1.5–2.0x peut être tolérable.
Pour des charges mixtes avec beaucoup de snapshots et des équipes inconnues, restez plus proche de 1.0–1.2x ou appliquez des réservations sur des sous-ensembles critiques.
10) Est-il jamais acceptable de tourner à 90 % ?
Parfois, pour une courte période, avec des charges connues, des miroirs, peu d’agitation, et un plan de récupération répété. En général, 90 % est le point où ZFS commence à facturer des intérêts.
Si vous vivez en permanence à 90 % en thin provisioning, vous choisissez le drame.
Conclusion : mesures suivantes pour éviter le pager
Les zvols sparse ne sont pas le méchant. Le méchant, ce sont les promesses non gérées. Si vous voulez le provisionnement fin sans excuses fines,
traitez la capacité comme un SLO avec budgets, alertes et garde-fous.
Faites ce qui suit :
- Instrumenter le minimum : CAP du pool, FRAG, usage snapshots, dérive du compressratio et alertes sur le taux de croissance.
- Rédiger une politique de surengagement : définir le maximum et ce qui déclenche « arrêter de créer de nouveaux volumes thin ».
- Protéger les zvols critiques : ajouter
refreservationlà où l’échec d’écriture est inacceptable. - Corriger les mécanismes de récupération : vérifier snapshots et comportement discard ; ne pas supposer que les suppressions récupèrent l’espace.
- Répéter le runbook 95% : savoir exactement comment vous récupérerez ou étendrez avant d’en avoir besoin.
Le provisionnement fin peut être un avantage compétitif : meilleure utilisation, provisionnement plus rapide, moins d’achats de disques en urgence.
Mais seulement si vous êtes honnête concernant la facture qui arrive à échéance. ZFS encaissera, à l’heure, à chaque fois.