À un moment donné, toutes les équipes de stockage rencontrent le même antagoniste : le vdev « temporaire ». Il est arrivé pendant une crise, a résolu un problème de capacité, et maintenant il vit dans votre pool comme un mauvais colocataire qui ne paie pas sa part. Vous voulez qu’il parte. ZFS, célèbre pour sa prudence, répond : peut-être.
La suppression de vdev existe, est utile, et reste pleine d’écueils. En production, la différence entre « ça marche » et « j’ai perdu mon week-end » tient à la planification autour des règles de ZFS, pas à vos espoirs.
Le modèle mental : ce que signifie réellement « suppression »
Les pools ZFS sont construits à partir de vdevs (dispositifs virtuels). Un vdev est l’unité atomique de redondance et d’allocation. ZFS répartit les données en bandes across les vdevs, pas across les disques individuels. Cette phrase devrait changer votre façon de penser la suppression.
Quand vous lancez zpool remove, vous ne « débranchez pas un disque ». Vous initiez une évacuation : ZFS réécrit chaque bloc alloué qui réside sur le vdev ciblé vers d’autres vdevs du pool. Ce n’est qu’après le succès de cette opération que le vdev peut être détaché de la configuration du pool. Pendant l’évacuation, le vdev doit être lisible ; le reste du pool doit disposer de suffisamment d’espace libre pour absorber les données.
Cela signifie aussi que la suppression n’est pas instantanée. C’est un travail de déplacement de données à l’échelle du pool avec de vrais effets secondaires : plus d’I/O, davantage de pression de fragmentation, des pics de latence, et beaucoup de « pourquoi mon pool est occupé à 2h du matin ? ».
Une autre nuance cruciale : la suppression de vdev n’est pas une fonctionnalité générale de « réduction du pool ». C’est une capacité très spécifique avec des contraintes, et ZFS refusera souvent de la faire dans de nombreuses dispositions. Si vous ne retenez rien d’autre : concevrez votre pool comme si vous vouliez pouvoir le modifier plus tard, parce que ZFS ne vous sauvera pas magiquement d’un regret architectural.
Termes dont vous avez besoin, en langage opérationnel
- Top-level vdev : Un vdev directement sous le pool (par ex., un mirror vdev, un raidz vdev, ou un top-level single-disk vdev). La plupart des discussions sur la suppression portent sur les top-level vdevs.
- Leaf device : Un disque ou une partition à l’intérieur d’un vdev. Dans un mirror, vous pouvez retirer/remplacer des leafs ; ce n’est pas une « suppression de vdev », c’est un « remplacement/détachement de device ».
- Special vdev : Un device de classe d’allocation pour métadonnées (et éventuellement petits blocs). Puissant. Aussi facile à transformer en point de défaillance unique si vous tentez des choses audacieuses.
- SLOG (log vdev) : journal d’intentions séparé pour les écritures synchrones. Retirable, mais les conséquences dépendent de votre charge et des réglages de sync.
- L2ARC (cache vdev) : cache de lecture. Toujours retirables ; c’est un indice de performance, pas un stockage primaire.
- Evacuation : Le déplacement de données par ZFS hors du vdev supprimé. C’est le travail.
Ce que vous pouvez supprimer (et ce que vous ne pouvez pas)
Vous pouvez généralement supprimer : les dispositifs cache (L2ARC)
Les dispositifs L2ARC peuvent être ajoutés et retirés sans affecter la cohérence des données. Dans le pire des cas, vous subissez une régression de performance tandis que le cache se réchauffe à nouveau. Si votre pool est sain, retirer un L2ARC est essentiellement ennuyeux.
Vous pouvez généralement supprimer : les dispositifs de log (SLOG)
Retirer un device de log est autorisé. ZFS retombera sur l’utilisation du pool principal pour le ZIL. Le pool reste cohérent. Le risque est la latence et le débit pour les écritures synchrones, pas la perte de données. Si vous retirez SLOG sous une forte charge sync, vos applications vous le feront savoir immédiatement, généralement via des timeouts.
Vous pouvez supprimer : des top-level vdevs dans certaines configurations (la grosse option)
La suppression de top-level vdev est ce qui intéresse les gens quand ils parlent de « réduire un pool ». Elle existe, mais elle est verrouillée par le support d’implémentation et la version. En pratique :
- La suppression d’un top-level mirror vdev entier est couramment supportée (quand la feature existe sur votre plateforme et pool).
- La suppression d’un top-level single-disk vdev est souvent supportée (encore une fois : dépend des features et de la plateforme).
- La suppression d’un top-level raidz vdev n’est généralement pas supportée sur de nombreux déploiements ; même lorsque certaines plateformes évoluent, traitez-le comme « supposons que non » sauf si vous avez vérifié explicitement votre implémentation ZFS et les feature flags.
Vous pouvez retirer : des devices d’un mirror vdev (mais ce n’est pas une « suppression de vdev »)
Si vous avez un mirror vdev à deux disques, vous pouvez détacher un disque et continuer à opérer sur le disque restant (qui devient un vdev single-disk). C’est une opération sur les leafs. Elle réduit la redondance. Elle n’évacue pas les blocs vers d’autres vdevs. C’est souvent ce que les gens veulent réellement dire par « retirer un disque ».
Special vdevs : théoriquement supprimables, effrayants en pratique
Les special vdevs (classe d’allocation) sont l’endroit où la production rencontre l’orgueil. Si un special vdev contient des métadonnées (ce qui est le cas), le perdre peut rendre le pool inutilisable. Retirer un special vdev peut être supporté dans votre stack, mais vous devriez le traiter comme un projet de migration, pas comme une commande occasionnelle. Si votre special vdev est en mirror et sain, vous pouvez planifier sa suppression ; s’il est dégradé, vous êtes en territoire d’urgence.
Blague #1 : Un special vdev, c’est comme un cluster Kubernetes « temporaire » — tout le monde jure que c’est juste pour les tests jusqu’à ce que ça devienne critique un vendredi soir.
Limites strictes à respecter
1) Vous ne pouvez pas supprimer ce que ZFS ne peut pas évacuer
L’évacuation nécessite de l’espace libre sur les vdevs restants. Pas « un peu » d’espace libre. Suffisamment pour réécrire les blocs alloués plus la surcharge, tout en conservant le fonctionnement de l’allocateur du pool. Si votre pool est rempli à 85–90%, la suppression est une mauvaise idée. À 95%, c’est de l’automutilation.
2) La suppression est activée par feature et dépend de l’implémentation
Il n’existe pas un seul ZFS. Il y a OpenZFS, puis des intégrations systèmes et des distributions fournisseurs avec des versions, des flags de feature et des backports de correctifs différents. Le pool lui-même a aussi des feature flags : si le pool n’a pas la bonne feature activée, vous ne supprimerez rien.
3) Vous ne pouvez pas « supprimer partiellement » un top-level raidz pour le réduire
Les gens demandent : « Puis-je retirer un disque de mon raidz vdev et garder raidz ? » Non. Vous pouvez remplacer des disques par des plus gros et étendre (avec le support des bonnes features), mais réduire la largeur d’un raidz en retirant une leaf n’est pas la conception de ZFS. Si vous voulez une réduction flexible, construisez avec des mirrors, acceptez le surcoût de capacité, et dormez tranquille.
4) Vous ne pouvez pas supprimer le dernier top-level vdev
Un pool a besoin d’au moins un top-level vdev. Si vous voulez « tout supprimer », vous ne faites pas une réduction. Vous migrez.
5) La suppression met le pool sous stress et entre en concurrence avec les charges de production
L’évacuation est un job de réécriture. Elle sollicitera les disques, l’ARC, les métadonnées, et possiblement aggravera votre fragmentation. Si vous la lancez pendant la charge maximale, attendez-vous à une montée de la latence et des ralentissements « mystérieux » pour les applications. Si vous devez le faire en ligne, bridez et surveillez sans relâche.
6) La suppression n’est pas la même chose que le resilvering, et les réglages diffèrent
Le resilvering reconstruit dans un device de remplacement. L’évacuation redistribue à travers le pool. Vous verrez des symptômes différents : pas seulement la « vitesse de scan », mais le comportement de l’allocateur, la contention des metaslabs, et la file d’attente I/O globale.
7) Vous pouvez supprimer le vdev et ne pas récupérer l’espace attendu
La comptabilité ZFS peut vous surprendre. Snapshots, reservations, refreservation, paramètres pour petits blocs, et copies affectent « pourquoi c’est encore plein ? » Après suppression, la taille totale du pool diminue — parfois fortement — donc l’espace disponible que vous pensiez avoir peut s’évaporer. Planifiez la capacité post-suppression, pas seulement « puis-je supprimer ça ».
Une citation opérationnelle à garder sur soi
John Allspaw (idée paraphrasée) : « La fiabilité vient de la façon dont les systèmes se comportent sous contrainte, pas de la façon dont ils se comportent quand tout va bien. »
Faits intéressants et bref historique (parce que cette fonctionnalité n’est pas tombée du ciel)
- ZFS a été conçu autour de « les vdevs sont éternels. » Les premières conceptions de ZFS partaient du principe que vous feriez principalement croître les pools, pas les réduire.
- La suppression de top-level vdev est arrivée tard comparée aux bases mirror/raidz ; c’est une reconnaissance que les opérateurs réels font des choses désordonnées pendant les incidents.
- Les « allocation classes » (special vdevs) ont changé le risque opérationnel : déplacer les métadonnées sur des devices rapides peut être brillant, mais rend ces devices existentiel.
- Le ZIL est toujours présent même sans SLOG ; SLOG déplace simplement le journal vers un stockage plus rapide et à plus faible latence.
- Le contenu de L2ARC est jetable par conception ; il a été pensé comme un cache que l’on peut perdre sans pleurs.
- Les feature flags du pool sont une porte à sens unique : activer des features récentes peut empêcher l’import sur des systèmes plus anciens. La capacité de suppression dépend souvent de ces flags.
- Les scrubs ZFS préexistent à l’ère « cloud native » comme moyen routinier de détecter la corruption silencieuse avec checksums de bout en bout.
- Les metaslabs et les space maps comptent davantage pendant l’évacuation : l’allocateur devient le goulot d’étranglement bien avant que le CPU ne soit saturé.
- La fragmentation n’est pas qu’un problème de performance : elle peut transformer une évacuation en un long travail saccadé de réécriture avec des pics de latence désagréables.
Mode d’action rapide pour le diagnostic (trouvez le goulot avant d’improviser)
Voici le flux « j’ai 15 minutes avant la prochaine réunion et le pool fond ». Ne soyez pas créatif. Soyez systématique.
Première étape : le pool est-il même éligible à la suppression de vdev ?
- Vérifiez les feature flags et la version/implémentation ZFS.
- Confirmez que la cible est une classe supprimable (pas un top-level raidz sur une stack qui ne le supporte pas).
Deuxième étape : avez-vous assez d’espace pour évacuer ?
- Regardez l’espace libre du pool et la fragmentation.
- Examinez les snapshots et reservations qui empêcheront la libération d’espace.
- Décidez si vous devez supprimer/déplacer des données ou ajouter une capacité temporaire d’abord.
Troisième étape : le pool est-il assez sain pour survivre à l’opération ?
- Y a-t-il des vdevs dégradés ? Réparez-les d’abord.
- Y a-t-il un resilver/scrub en cours ? Décidez s’il faut attendre.
- Vérifiez SMART pour les devices qui pourraient mourir en cours d’évacuation.
Quatrième étape : si la suppression est lente, sur quoi attend-elle ?
- Saturation IOPS disque ? Surveillez
iostatet la latence par vdev. - Un disque lent en particulier ? Cherchez un device avec des await énormes.
- Contention de l’allocateur / fragmentation ? Attendez un progrès inégal et beaucoup d’I/O métadonnées.
- Taille d’enregistrement / petits blocs ? Les charges à petits blocs peuvent rendre l’évacuation aussi lente que de la colle qui sèche.
Tâches pratiques : commandes, sorties et la décision que vous prenez
Ci-dessous des actions opérationnelles réelles. Chaque action est « faire une chose, interpréter la sortie, décider de la prochaine étape. » C’est ainsi que l’on empêche le stockage de devenir un art de la performance.
Task 1: Identifier ce que vous avez en face (topologie du pool)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : Deux top-level mirror vdevs, plus un device de log et un device cache. Les mirrors sont la topologie top-level la plus favorable à la suppression.
Décision : Si le but est de réduire la capacité, le candidat est mirror-1 (top-level). Si le but est de simplifier, vous pouvez retirer SLOG ou L2ARC avec un risque minimal.
Task 2: Vérifier les feature flags du pool (porte d’éligibilité)
cr0x@server:~$ zpool get -H feature@device_removal tank
tank feature@device_removal active -
Ce que cela signifie : Le pool a la feature device_removal et elle est active.
Décision : Poursuivez la planification. Si elle est disabled ou -, vous ne pourrez probablement pas supprimer des top-level vdevs sur ce pool sans mise à niveau/import avec features (ce qui est lui-même une fenêtre de changement).
Task 3: Vérifier le taux d’occupation du pool (pouvez-vous évacuer ?)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r tank
NAME USED AVAIL REFER MOUNTPOINT
tank 41.2T 6.3T 96K /tank
tank/home 11.1T 6.3T 10.9T /tank/home
tank/vm 28.7T 6.3T 28.7T /tank/vm
tank/backups 1.4T 6.3T 1.4T /tank/backups
Ce que cela signifie : Seulement 6.3T disponibles. Si le vdev que vous voulez supprimer a plus que cela alloué, l’évacuation ne peut pas se terminer.
Décision : Avant de supprimer un top-level vdev, estimez combien de données s’y trouvent. En cas d’incertitude, supposez « à peu près proportionnel » et exigez une marge d’espace confortable. Si vous ne pouvez pas créer de marge, ne lancez pas la suppression.
Task 4: Vérifier la capacité et la fragmentation du pool (prévision de la douleur d’évacuation)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 47.5T 41.2T 6.3T 58% ONLINE
Ce que cela signifie : 58% de fragmentation n’est pas « acceptable ». C’est « cela prendra plus de temps que vous voulez et nuira à la performance ».
Décision : Si vous devez supprimer maintenant, planifiez un bridage et une fenêtre plus longue. Si vous pouvez attendre, envisagez de déplacer les données froides hors et de les remettre (ou d’autres stratégies de défragmentation) avant d’essayer la suppression.
Task 5: Identifier si des snapshots retiennent de l’espace
cr0x@server:~$ zfs list -t snapshot -o name,used,refer -S used | head
NAME USED REFER
tank/vm@hourly-2025-12-25-0900 1.2T 28.7T
tank/vm@hourly-2025-12-25-0800 1.1T 28.7T
tank/home@daily-2025-12-24 640G 10.9T
tank/vm@hourly-2025-12-25-0700 610G 28.7T
Ce que cela signifie : Les snapshots consomment un espace significatif. Supprimer des datasets peut ne pas libérer d’espace si des snapshots référencent les anciens blocs.
Décision : Si vous avez besoin d’espace pour évacuer, réduisez la rétention des snapshots ou répliquez les snapshots hors pool, puis détruisez localement — prudemment, avec l’accord des parties prenantes.
Task 6: Vérifier les reservations de datasets qui bloquent l’évacuation
cr0x@server:~$ zfs get -H -o name,property,value -r reservation,refreservation tank | egrep -v '\t(none|0)\t' | head
tank/vm reservation 5T
tank/home refreservation 1T
Ce que cela signifie : Les reservations réservent de l’espace que les autres opérations ne peuvent pas utiliser, y compris la marge d’évacuation.
Décision : Diminuez ou retirez temporairement les reservations (avec accord des propriétaires d’applications) pour créer un véritable espace libre. Rétablissez-les après.
Task 7: Confirmer la santé avant de lancer le mouvement de données
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
Ce que cela signifie : ONLINE, pas d’erreurs, scrub récent réussi. Voilà à quoi ressemble l’éligibilité au travail risqué.
Décision : Si vous voyez DEGRADED, FAULTED, ou une montée d’erreurs de checksum, réparez cela d’abord. Supprimer sous dégradation revient à jouer avec des enjeux plus élevés.
Task 8: Retirer un device L2ARC (sûr, réversible en esprit)
cr0x@server:~$ sudo zpool remove tank nvme-INTEL_SSDPEKNW512
Ce que cela signifie : Le device cache est détaché du pool. Il n’y a généralement pas de sortie spectaculaire.
Décision : Surveillez la latence de lecture et le taux de hit du cache (si vous le suivez). Si la performance chute, remettez-le ou remplacez-le par un meilleur device. L’intégrité des données n’est pas en jeu.
Task 9: Retirer un device SLOG (attendez des changements sur la latence des écritures sync)
cr0x@server:~$ sudo zpool remove tank nvme-SAMSUNG_MZVLB256
Ce que cela signifie : ZFS reviendra à l’utilisation du pool principal pour le journal d’intentions. Vos applications peuvent le remarquer.
Décision : Si votre environnement dépend des écritures synchrones (bases de données, NFS en sync), planifiez ce changement ou ajustez temporairement les attentes. Si vous voyez des timeouts applicatifs, remettez rapidement SLOG.
Task 10: Lancer la suppression d’un top-level vdev (l’évacuation commence)
cr0x@server:~$ sudo zpool remove tank mirror-1
Ce que cela signifie : Le pool commence à évacuer les données de mirror-1 vers les top-level vdevs restants.
Décision : Démarrez immédiatement la surveillance de la progression et des performances. Et : prévenez les humains. Ce n’est pas une opération silencieuse.
Task 11: Surveiller la progression via zpool status
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
remove: Removal of vdev 1 copied 8.31T of 17.2T at 612M/s, 03:48:29 remaining
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0 (removing)
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : ZFS indique les octets copiés, le débit, et le temps estimé restant. Les débits varieront fortement ; ne vénérez pas l’ETA.
Décision : Si le débit s’effondre et que la latence grimpe, bridez ou réduisez la charge. Si des erreurs apparaissent, arrêtez et réévaluez la santé matérielle.
Task 12: Surveiller la latence par device pendant la suppression (trouvez la roue lente)
cr0x@server:~$ iostat -x 5
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s await svctm %util
sda 92.1 48.3 9840 5120 6.4 1.1 15.2
sdb 89.7 47.9 9600 4980 6.7 1.0 14.8
sdc 31.2 88.4 3200 10120 38.9 1.2 98.5
sdd 29.8 90.1 3100 10320 41.3 1.2 99.1
Ce que cela signifie : sdc et sdd sont saturés avec des await élevés ; ils sont probablement le vdev en cours de suppression ou le vdev de destination sous pression.
Décision : Si un seul device est lent, suspectez un disque défaillant ou un problème de chemin/câble. Si les deux devices destination sont saturés, vous faites simplement trop d’I/O — réduisez la suppression en diminuant la charge concurrente.
Task 13: Vérifier le comportement TRIM/discard sur des pools SSD (falaise de performance cachée)
cr0x@server:~$ zpool get -H autotrim tank
tank autotrim on -
Ce que cela signifie : Autotrim est activé. Pendant des réécritures intensives, le trim peut ajouter une surcharge selon le firmware du device.
Décision : Si vous observez une amplification d’écriture ou des pics de latence étranges sur des SSDs durant l’évacuation, testez autotrim=off en fenêtre de maintenance. Ne changez pas cela à la légère sans comprendre le comportement des SSDs dans votre parc.
Task 14: Trouver « pourquoi l’espace ne se libère pas ? » avec usage logique vs physique
cr0x@server:~$ zfs get -H -o name,property,value -r used,usedbysnapshots,usedbydataset,usedbyrefreservation tank/vm
tank/vm used 28.7T
tank/vm usedbysnapshots 6.4T
tank/vm usedbydataset 22.3T
tank/vm usedbyrefreservation 0B
Ce que cela signifie : Une grande portion est consommée par les snapshots. Supprimer des fichiers à l’intérieur de tank/vm ne récupérera pas cet espace référencé par snapshot.
Décision : Ajustez la politique de snapshots ou répliquez et taillez. Si vous essayez de faire de la place pour la suppression, les snapshots sont souvent le véritable blocage.
Task 15: Confirmer que le vdev supprimé a disparu (vérification d’état final)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : mirror-1 a disparu. La taille du pool reflétera la réduction.
Décision : Vous pouvez maintenant réaffecter les disques, les remplacer, ou reconstruire un nouveau vdev ailleurs. Vérifiez aussi les alarmes de capacité. Vos seuils doivent changer car le pool est plus petit.
Task 16: Valider la taille du pool et la marge après le changement (ne supposez rien)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 23.7T 21.1T 2.6T 64% ONLINE
Ce que cela signifie : Le pool est maintenant beaucoup plus petit ; l’espace libre a diminué aussi. La fragmentation a augmenté (classique après de gros mouvements).
Décision : Si l’espace libre est maintenant critique, déplacez des charges, ajoutez un nouveau vdev, ou ajustez la rétention. Ne célébrez pas la suppression puis oubliez que vous êtes proche du seuil critique.
Trois mini-récits d’entreprise issus du terrain
Incident : la mauvaise hypothèse (« on peut supprimer un vdev raidz, non ? »)
Une entreprise SaaS de taille moyenne avait un pool ZFS soutenant une flotte d’hôtes VM. Il a démarré en raidz2 parce que l’équipe voulait efficacité de capacité et tolérance aux pannes. Au fil du temps, ils ont ajouté un autre vdev raidz2 pendant une phase de croissance. Puis la croissance a ralenti, les budgets matériels se sont resserrés, et quelqu’un a proposé « de supprimer le vdev récent » pour réaffecter ces disques à un autre cluster.
Le plan paraissait inoffensif : lancer la suppression le vendredi soir, laisser tourner tout le week-end, revenir lundi avec un pool plus petit. L’opérateur avait utilisé zpool remove auparavant — sur des devices cache. Ils ont supposé la même flexibilité pour tout type de vdev. ZFS n’était pas d’accord.
La commande a échoué avec une erreur nette indiquant que le type de vdev n’était pas supprimable dans leur environnement. Le vrai problème n’était pas l’échec ; c’était ce qui s’est passé ensuite. Pour « forcer », l’équipe a essayé une série de contournements désespérés : détacher des devices, mettre des disques hors ligne, tenter des remplacements partiels. C’est ainsi qu’ils ont transformé un vdev raidz sain en vdev dégradé, en cours de changement, alors qu’ils étaient en production.
Ils se sont récupérés, mais cela leur a pris une longue nuit : remettre en ligne des devices, resilver, et annuler le plan de « réduction ». Le post-mortem était simple : l’erreur initiale était de traiter la suppression de vdev comme un outil général de réduction de pool. Ce n’est pas le cas. Si vous voulez pouvoir réduire, vous choisissez une topologie qui le permet et acceptez le coût.
Optimisation qui s’est retournée contre eux : ajout d’un special vdev « temporaire » pour accélérer les métadonnées
Une équipe d’ingénierie de services financiers avait un pool ZFS servant un grand arbre de fichiers avec des millions de petits fichiers. Les opérations sur métadonnées étaient lentes, les traversées de répertoires pénibles, et chaque revue d’incident répétait la même conclusion : « on devrait ajouter des SSDs. » Ils l’ont fait. Ils ont ajouté un special vdev sur une paire de NVMe pour contenir métadonnées et petits blocs. La performance s’est améliorée immédiatement.
Puis ils se sont montrés ambitieux. Pour maximiser la capacité, ils ont configuré le special vdev d’une manière techniquement redondante mais opérationnellement fragile : les mises à jour firmware et la maintenance étaient gérées par une autre équipe plateforme, et l’équipe stockage n’était pas alertée des bizarreries NVMe. Prédictiblement, un NVMe a commencé à renvoyer des erreurs sous charge soutenue et disparaissait/réapparaissait parfois sur le bus PCIe.
Rien ne s’est corrompu immédiatement. C’est ce qui rend la situation dangereuse. Le pool a commencé à journaliser des erreurs de checksum intermittentes liées aux lectures de métadonnées. Les utilisateurs ont vu des erreurs I/O « aléatoires ». L’instinct de l’équipe a été de supprimer le special vdev et revenir à l’état antérieur. Mais la suppression nécessite un chemin sain pour lire les blocs et les réécrire ailleurs. Leur « optimisation » était devenue une dépendance.
La réparation a été peu glamour : remplacer le NVMe instable, resilver le mirror du special, scrub jusqu’à la propreté, puis planifier une suppression/migration contrôlée avec marge d’espace. La leçon n’était pas « ne jamais utiliser de special vdevs ». C’était : si vous ajoutez un special vdev, traitez-le comme une tier de stockage à part entière avec gestion du cycle de vie, surveillance et contrôle des changements. Sinon, c’est une amélioration de perf qui vous facturera plus tard.
Pratique ennuyeuse mais correcte qui a sauvé la mise : marge de capacité et migration par étapes
Une équipe plateforme interne d’entreprise utilisait ZFS pour des répertoires NFS home et des artefacts de build. Ils avaient une règle agaçante : le pool doit rester sous 75% alloué, et la rétention des snapshots doit être justifiée par des besoins réels de récupération. Les ingénieurs se plaignaient car cela semblait être une capacité gaspillée.
Un trimestre, ils ont dû décommissionner un châssis de disques anciens. Le pool avait été étendu au fil des ans avec plusieurs top-level mirror vdevs (pas raidz), précisément parce qu’ils privilégiaient la flexibilité opérationnelle. Ils ont planifié la suppression des mirrors qui se trouvaient sur l’ancien châssis.
Parce que le pool avait de la marge, l’évacuation a pu se dérouler sans que l’allocateur ne panique. Parce que les snapshots étaient contrôlés, ils ont réellement pu libérer de l’espace si nécessaire. Parce qu’ils pratiquaient les scrubs et remplaçaient les disques douteux tôt, ils n’ont pas découvert de défaillances matérielles au milieu d’un job de réécriture de plusieurs jours.
Les suppressions ont quand même pris du temps, et le pool a fonctionné plus chaud que d’habitude, mais tout est resté prévisible. Le décommission s’est déroulé selon le calendrier, et personne en dehors de l’équipe stockage n’a même remarqué. Voilà l’intérêt des pratiques ennuyeuses : elles ne créent pas d’histoires excitantes, et c’est pourquoi on continue à les appliquer.
Blague #2 : « Just remove the vdev » est la version stockage de « just restart it » — parfois correct, généralement sans expliquer ce qui casse ensuite.
Erreurs courantes : symptômes → cause racine → correction
1) Symptom: zpool remove refuse avec « operation not supported »
Cause racine : Les feature flags du pool n’incluent pas device removal, ou votre implémentation/version ZFS ne supporte pas la suppression pour ce type de vdev.
Correction : Vérifiez les feature flags, la version ZFS, et le type de vdev. Si c’est du raidz, supposez qu’il vous faut une migration plutôt qu’une suppression. N’essayez pas des hacks créatifs de détachement/hors-ligne.
2) Symptom: la suppression démarre, puis la progression s’écroule presque à zéro
Cause racine : Le pool est trop plein ou trop fragmenté ; l’allocateur et la sélection des metaslabs deviennent coûteux, et les écritures concurrencent l’I/O de production.
Correction : Créez de la marge (supprimez/répliquez des données, réduisez les snapshots), planifiez le travail dans une fenêtre calme, et réduisez la charge concurrente. Si vous ne pouvez pas, ne lancez pas la suppression en ligne aux heures de pointe.
3) Symptom: le pool est ONLINE mais les applis subissent des pics de latence et des timeouts pendant la suppression
Cause racine : L’évacuation sature les disques et explose la latence pour les charges synchrones ou riches en métadonnées.
Correction : Ajoutez une capacité temporaire pour réduire la pression de mouvement, déplacez les workloads chauds, ou bridez au niveau applicatif (limitez backup, mettez en pause les rebuilds, échelonnez les jobs). Surveillez les SLOs applicatifs, pas seulement les métriques stockage.
4) Symptom: « Nous avons libéré 5TB mais zpool list free n’a pas beaucoup changé »
Cause racine : Les snapshots référencent encore les blocs ; l’espace est logiquement supprimé mais physiquement retenu.
Correction : Identifiez les grands consommateurs de snapshot avec zfs list -t snapshot et usedbysnapshots. Ajustez la rétention, répliquez, puis détruisez les snapshots de façon intentionnelle.
5) Symptom: après suppression de SLOG, les bases de données chutent en perf
Cause racine : Les écritures sync vont maintenant sur le pool principal ; la latence a fortement augmenté.
Correction : Réajoutez SLOG sur des devices à faible latence et protégés contre la perte de puissance. Si impossible, évaluez si l’appli a vraiment besoin de sync ou si vous forciez sync via des options d’export/mount.
6) Symptom: supprimer un special vdev semble impossible sans risque
Cause racine : Le special vdev contient des métadonnées/petits blocs critiques, et vous n’avez pas de topologie cible sûre ni la marge pour migrer.
Correction : Traitez-le comme une migration : ajoutez un nouveau special vdev (mirrored), migrez, scrubbez, puis retirez l’ancien. Si votre plateforme ne supporte pas la suppression, planifiez une migration du pool.
7) Symptom: le pool a rétréci mais l’espace libre est maintenant dangereusement bas
Cause racine : Vous avez planifié la faisabilité de l’évacuation, pas la marge opérationnelle post-suppression.
Correction : Recalculez les cibles de capacité après suppression. Mettez à jour les seuils d’alerte. Ajoutez de la capacité avant d’être forcé de le faire en urgence.
8) Symptom: un disque montre un await fou pendant la suppression
Cause racine : Disque en défaillance, câble/HBA défectueux, ou device avec comportement shingled/quark firmware sous écritures soutenues.
Correction : Validez le matériel. Remplacez le device suspect avant de continuer une longue évacuation. S’il meurt en cours d’opération, vous risquez de perdre la capacité de lire les blocs nécessaires à l’évacuation.
Listes de contrôle / plan étape par étape (comment faire sans improviser à 3h du matin)
Checklist pré-vol : décider si la suppression est l’outil approprié
- Définir l’objectif : réduire la capacité, décommissionner du matériel, retirer une tier de performance, ou inverser une expansion temporaire.
- Identifier la cible : cache/log/special/top-level data vdev.
- Vérifier le support : feature flags et implémentation/version ZFS pour cette cible.
- Confirmer la santé du pool : pas de vdev dégradé, pas d’erreurs de checksum non résolues.
- Confirmer la marge : espace libre plus marge opérationnelle ; ajuster snapshots/reservations.
- Planifier l’impact sur la charge : programmer, brider, et communiquer.
Plan d’exécution : suppression d’un top-level vdev (data vdev)
- Prenez un instantané de configuration pour votre saine tranquillité : capturez
zpool status,zpool list,zfs list, et les paramètres de reservations. - Lancez un scrub avant la suppression si ce n’est pas récent. Vous voulez découvrir les erreurs de lecture latentes maintenant, pas en plein milieu de l’évacuation.
- Réduisez ou mettez en pause les jobs batch non critiques : backups, grosses restaurations, et travaux de type compactage.
- Démarrez la suppression :
zpool remove pool target. - Surveillez la progression et la latence :
zpool statusetiostat -x. - Si l’impact sur la performance est inacceptable : réduisez d’abord la charge concurrente. Ne paniquez pas et n’arrêtez pas sans plan de rollback explicite.
- Quand c’est terminé, vérifiez la topologie et la capacité. Mettez à jour les seuils de monitoring et les prévisions de capacité.
Plan d’exécution : suppression de SLOG ou L2ARC (vdevs de support)
- Mesurez la latence applicative et la latence stockage en baseline.
- Retirez le device avec
zpool remove. - Surveillez les charges d’écriture synchrones (bases de données, NFS) pour la suppression de SLOG ; attendez peu de choses pour L2ARC sauf le réchauffement du cache.
- Décidez de remplacer par un meilleur device ou de rester sans.
Réflexion sur le rollback (parce qu’on n’obtient pas toujours ce qu’on veut)
- Si la suppression n’est pas supportée : votre rollback est « cessez d’essayer » et planifiez une migration vers un nouveau pool avec la bonne topologie.
- Si la suppression est supportée mais trop disruptive : le rollback est opérationnel — mettez en pause les workloads concurrents, ajoutez une capacité temporaire, ou replanifiez. Vous ne pouvez pas « décrire » l’évacuation déjà effectuée.
- Si le matériel commence à lâcher pendant la suppression : traitez cela comme un incident. Le vdev supprimé doit rester lisible pour terminer l’évacuation en sécurité.
FAQ
Puis-je réduire un pool ZFS comme on réduit un volume LVM ?
Généralement non. ZFS a été conçu pour étendre les pools. La suppression de vdev est une fonctionnalité d’évacuation spécifique, pas un outil général de réduction, et elle est limitée par le type de vdev et le support de la plateforme.
Retirer un disque d’un mirror est-ce la même chose que supprimer un vdev ?
Non. Détacher un disque leaf d’un mirror change la redondance à l’intérieur du vdev. Supprimer un top-level vdev déclenche l’évacuation des blocs alloués vers d’autres top-level vdevs.
Puis-je retirer un vdev raidz d’un pool ?
Dans de nombreux déploiements réels : pratiquement non. Traitez les top-level vdevs raidz comme permanents. Si vous avez besoin de flexibilité pour réduire, concevez avec des mirrors ou planifiez une migration de pool.
Combien de temps prend la suppression d’un vdev ?
Cela dépend des données allouées sur le vdev cible, de la fragmentation du pool, des vitesses des devices, et de la charge concurrente. Comptez « des heures à des jours », pas « des minutes », pour des vdevs multi-téraoctets.
Que se passe-t-il si un disque du vdev en suppression tombe en panne en plein milieu ?
Si le vdev devient illisible, l’évacuation peut échouer et vous risquez de perdre la capacité de finir la suppression en sécurité. Les mirrors offrent plus de résilience ; les vdevs single-disk sont impitoyables. Ne commencez pas la suppression sur du matériel douteux.
Retirer SLOG risque-t-il la perte de données ?
Pas dans le sens de corrompre des données engagées. ZFS reste cohérent. Le risque est la performance : la latence des écritures synchrones peut augmenter fortement, provoquant des timeouts applicatifs.
Retirer L2ARC risque-t-il la perte de données ?
Non. L2ARC est un cache. Le retirer supprime les données en cache et votre hit rate se reconstruira avec le temps.
Puis-je supprimer un special vdev en toute sécurité ?
Parfois, mais ce n’est pas « sûr » au sens casual. Les special vdevs contiennent des métadonnées ; vous devez garantir la redondance, la santé, la marge et le support sur votre plateforme. Traitez-le comme une migration avec scrubs et vérifications.
Pourquoi l’espace libre est-il si critique pour la suppression ?
Parce que l’évacuation réécrit des blocs alloués ailleurs. Si les vdevs restants ne peuvent pas accepter les données, ZFS ne peut pas terminer le déplacement. De plus, les pools très pleins se comportent mal : l’allocation ralentit et la performance s’effondre.
Dois-je préférer les mirrors aux raidz si je veux pouvoir supprimer des vdevs plus tard ?
Oui, si la flexibilité opérationnelle compte plus que l’efficacité brute de capacité. Les mirrors coûtent plus en espace utilisable, mais ils vous offrent des expansions, remplacements et (là où supporté) des suppressions plus simples.
Conclusion : prochaines étapes pratiques
Si vous voulez supprimer quelque chose d’un pool ZFS, commencez par le classer. Les devices cache et log sont généralement des victoires faciles. Les top-level vdevs de données sont possibles uniquement lorsque votre pool et votre plateforme le supportent explicitement, et même dans ce cas c’est une migration de données contrôlée sous charge.
Prochaines étapes qui rapportent immédiatement :
- Exécutez maintenant les vérifications d’éligibilité (feature flags, topologie) avant d’avoir besoin de l’option en incident.
- Faites respecter une marge. Si votre pool vit au-dessus de ~80% alloué en permanence, vous avez choisi le mode crise comme style de vie.
- Concevez pour le changement : si vous anticipez de réduire, préférez des top-level mirrors et évitez les dispositions « temporaires » irréversibles.
- Pratiquez les disciplines ennuyeuses : scrubs, surveillance SMART, hygiène des snapshots, et des reservations que vous pouvez justifier à un collègue sceptique.
ZFS fera la bonne chose quand vous respecterez ses règles. Quand vous ne le faites pas, il fera quand même la bonne chose — en refusant. C’est une fonctionnalité. Traitez-la comme telle.