ZFS dispose d’une propriété appelée copies qui ressemble à un cheat code : réglez-la sur 2 ou 3 et vos données obtiennent une redondance supplémentaire — pas de nouveaux disques, pas de nouveaux vdevs, pas de reconstruction du pool. C’est tentant, surtout quand les achats « regardent ça » et que votre registre des risques est « en feu ».
En pratique, copies n’est ni magique ni inutile. C’est un outil aiguisé qui peut sauver une semaine de production — ou brûler silencieusement une pile de capacité et de performance tout en vous donnant un faux sentiment de sécurité. Traitez-le comme une fonctionnalité d’adulte : comprenez exactement ce qu’il duplique, où il place ces blocs, comment il interagit avec mirrors/RAIDZ/special vdevs, et comment l’exploiter sans transformer votre pool en projet scientifique lent et coûteux.
Table des matières
- Ce que
copiesfait vraiment (et ce qu’il ne fait pas) - Faits rapides et contexte historique
- Sous le capot : placement des blocs, checksums et modes de défaillance
- Astuce ou gâchis ? Un cadre de décision
- Coûts en performance et capacité (les parties que vous ressentez)
- Schémas pratiques : où
copiesbrille - Trois mini-récits du monde de l’entreprise (douleur incluse)
- Tâches pratiques : commandes, sorties et interprétation
- Méthode de diagnostic rapide
- Erreurs courantes : symptômes et corrections
- Listes de contrôle / plan étape par étape
- FAQ
- Conclusion
Ce que copies fait vraiment (et ce qu’il ne fait pas)
La propriété de dataset ZFS copies contrôle combien de copies ZFS stocke pour chaque bloc écrit dans ce dataset : copies=1 (par défaut), copies=2, ou copies=3.
C’est par dataset, héritables, et ça s’applique aux nouvelles écritures (et aux blocs réécrits), pas aux blocs existants sauf si vous les réécrivez.
Ce que ça fait
Lorsque vous écrivez un bloc, ZFS alloue de l’espace et écrit ce bloc. Avec copies=2, il alloue deux emplacements de bloc distincts et écrit le même bloc deux fois. Avec copies=3, trois emplacements.
Les lectures peuvent provenir de n’importe quelle copie valide ; si une copie échoue la validation checksum, ZFS essaiera une autre.
Ce que ça ne fait pas
copies ne transforme pas un pool mono-disque en un pool sûr. Il ne vous protège pas de la perte d’un vdev. Il ne survit pas à un « disque disparu » à moins que la redondance des vdev(s) ne puisse encore fournir au moins une copie valide.
Il ne remplace pas non plus les sauvegardes. C’est toujours le même pool, le même domaine administratif, le même rayon d’explosion « oups j’ai supprimé ça ».
Un modèle mental utile : la redondance de vdev (mirror/RAIDZ) vous protège contre la défaillance d’un périphérique. copies vous protège contre certains scénarios de perte/corruption au niveau bloc à l’intérieur de la topologie survivante, et peut améliorer la récupérabilité quand vous êtes déjà en mode dégradé ou que vous avez des secteurs instables.
Blague n°1 : Mettre copies=3 sur l’ensemble de votre pool, c’est comme triple-emballer les courses — génial jusqu’à ce que vous réalisiez que vous ne pouvez plus rien porter d’autre et que vous avez quand même oublié les oeufs.
Faits rapides & contexte historique
Voici quelques points concrets de contexte qui façonnent la compréhension de copies en 2025 :
- ZFS a été construit autour du checksumming de bout en bout : la corruption est détectée au moment de la lecture, pas déduite via le « succès » du disque. Cela rend les copies multiples significatives car ZFS peut choisir une copie connue bonne.
- Les premiers déploiements de ZFS prônaient « scrub ou regret » : les scrubs périodiques transformaient les erreurs latentes de secteur en événements détectés-et-réparés — bien avant que le stockage grand public n’admette ses problèmes.
copiesest plus ancien que la carrière ZFS de beaucoup : ce n’est pas un ajout tendance ; cela existe depuis des années comme un bouton de redondance ciblé.- RAIDZ n’est pas « juste RAID » : la parité ZFS est intégrée aux checksums et aux lectures auto-réparantes, mais la parité a toujours des domaines de défaillance (perte complète de vdev, périphériques manquants) que des copies supplémentaires ne peuvent pas traverser magiquement.
- Les special vdevs ont changé la notion de « sécurité des métadonnées » : déplacer les métadonnées (et éventuellement les petits blocs) sur un special vdev est un gain de performance — et un piège de fiabilité si vous sous-redondez ce vdev. Des copies supplémentaires peuvent faire partie de l’histoire d’atténuation, mais pas la solution complète.
- Les disques modernes mentent poliment : une lecture « réussie » peut quand même livrer des bits erronés. Les checksums attrapent ça ; la redondance corrige. Des copies supplémentaires peuvent fournir une autre chance quand la reconstruction par parité est douloureuse ou impossible.
- La compression est devenue courante : avec
compression=lz4, la taxe de capacité decopies=2est parfois moins catastrophique que vous le pensez — sur des datasets compressibles. - Les tailles d’enregistrement ont augmenté, les petits fichiers sont plus bizarres : bases de données, images VM et stores d’objets mettent sous pression des patrons de blocs différents ;
copiesinteragit avec cela de façons qui ne sont pas intuitives depuis « deux fois les données, deux fois le coût ».
Sous le capot : placement des blocs, checksums et modes de défaillance
Les copies sont des allocations de blocs séparées, pas un « RAID dans le RAID »
ZFS ne stocke pas un « bloc principal » plus un « miroir interne ». Il stocke plusieurs pointeurs de bloc indépendants dans les métadonnées qui pointent tous vers des payloads de bloc équivalents.
À l’écriture, ZFS choisit plusieurs cibles d’allocation. À la lecture, ZFS peut choisir parmi elles.
La nuance importante : ces allocations finissent typiquement dans la même classe de vdev (vdevs de données normales, ou special vdevs si le bloc est classé pour y aller), et au sein du même pool.
Cela signifie que des copies supplémentaires ne sont pas indépendantes de la même manière qu’un second pool, un deuxième châssis ou un second site le seraient.
Les checksums sont l’arbitre
ZFS calcule un checksum pour chaque bloc et stocke les checksums dans les blocs parents (pas à côté des données qu’ils protègent). Quand vous lisez un bloc, ZFS le valide. Si le checksum échoue et qu’il existe de la redondance, ZFS peut essayer :
- une autre copie (avec
copies>1), - l’autre côté d’un mirror (sur un vdev mirror),
- la reconstruction par parité (sur RAIDZ),
- ou toute combinaison des options ci-dessus.
Quelles défaillances copies aide-t-il à gérer ?
Dans la vraie vie, les défaillances importantes sont rarement « disque mort, remplacé proprement ». Elles sont généralement :
- Erreurs latentes de secteurs qui surgissent pendant un scrub/resilver.
- Périphériques partiellement défaillants renvoyant des erreurs de lecture intermittentes.
- Glitches de firmware/transport qui provoquent des timeouts et des erreurs d’E/S sous charge.
- Mauvais blocs dans un pool dégradé, où la reconstruction par parité ou les alternatives mirror sont déjà contraintes.
Des copies supplémentaires peuvent aider quand le pool a suffisamment de redondance pour garder au moins une copie accessible, mais que des blocs individuels deviennent illisibles à un emplacement.
Si le vdev lui-même est perdu (par ex., trop de disques absents dans un RAIDZ, ou les deux faces d’un mirror deux voies mortes), toutes les copies stockées sur ce vdev sont hors sujet.
Où vont les copies ?
La réponse pratique : elles vont là où l’allocateur trouve de l’espace, soumis au comportement d’allocation des metaslabs de ZFS.
La vérité inconfortable : vous ne devez pas supposer que les copies atterrissent sur des disques physiques séparés d’une manière qui imite un mirror.
Elles peuvent se retrouver sur le même disque dans un vdev RAIDZ (toujours à des offsets différents), parce que RAIDZ stripe les données sur tous les disques et la parité, et la « copie » est un autre bloc logique qui sera distribué par le mapping RAIDZ. C’est toujours utile : c’est une deuxième allocation indépendante qui peut survivre à une corruption localisée ou à des régions illisibles, mais ce n’est pas un second domaine de panne indépendant.
Interaction avec mirrors vs RAIDZ
Sur un vdev mirror, vous avez déjà deux (ou plus) copies physiques sur différents disques. Mettre copies=2 en plus d’un mirror deux voies signifie que vous avez maintenant des copies logiques doublées, chacune étant mirrorée — effectivement quatre instances physiques réparties sur deux disques. Cela peut aider dans certains cas limites de corruption/réparation, mais c’est beaucoup d’amplification d’écriture pour un gain marginal.
Sur RAIDZ, copies peut être plus rationnel pour des petites données à haute valeur où la reconstruction par parité en période dégradée est risquée ou lente. Vous payez des allocations supplémentaires, mais vous achetez plus de « chances » pour qu’un bloc soit lisible sans récupération héroïque.
Special vdevs : l’endroit où copies devient politique
Si vous utilisez un special vdev pour stocker les métadonnées et (optionnellement) les petits blocs, la disponibilité de ce vdev devient existentielle pour le pool.
Si le special vdev meurt et que vous n’avez pas de redondance là-bas, vous pouvez perdre le pool même si vos gros disques de données RAIDZ sont en parfait état.
Des copies supplémentaires peuvent réduire la probabilité qu’un bloc de métadonnées spécifique devienne illisible à cause d’erreurs médias, mais elles ne résolvent pas la perte d’un special vdev.
Astuce ou gâchis ? Un cadre de décision
La bonne question n’est pas « est-ce que copies=2 est bien ? » La bonne question est : « Quelle défaillance j’essaie de survivre, et combien suis-je prêt à payer pour la survivre ? »
Quand copies=2 est judicieux
- Datasets petits et critiques pour l’activité : configurations, exports de vaults de secrets, petites bases de données, clés de licence, artéfacts CI qui doivent exister.
- Arbres riches en métadonnées : des millions de petits fichiers, où un seul chemin de métadonnées illisible peut être un cauchemar au moment de la restauration.
- Fenêtres à risque de dégradé : environnements où vous vous attendez à fonctionner en mode dégradé (sites distants, remplacement matériel lent), et où vous voulez une marge supplémentaire contre les UREs pendant scrub/resilver.
- Environnements de boot et datasets OS : là où « ne pas démarrer » est opérationnellement coûteux même si les données sont intactes ailleurs.
- Datasets liés au special vdev : certaines équipes appliquent
copies=2sur des datasets riches en métadonnées lorsque la capacité du special vdev le permet, comme approche « ceinture et bretelles » contre les erreurs médias localisées.
Quand c’est du gâchis (ou pire)
- Médias en vrac, sauvegardes et archives froides : si vous pouvez réhydrater, les copies supplémentaires sont souvent gaspillées ; utilisez la réplication vers un autre pool/site.
- Bases de données à fort débit d’écritures : l’amplification d’écriture fait mal deux fois : latence et endurance SSD (ou IOPS HDD). Vous le ressentirez et vous le paierez.
- Mettre tout le pool en
copies=2« au cas où » : c’est l’équivalent stockage de mettre toute l’entreprise dans un chat de groupe parce qu’une personne rate des messages. - Essayer de compenser une topologie risquée : si votre design est « RAIDZ1 unique sur de gros disques »,
copiesn’est pas la solution. La solution est le design des vdevs, des spares, du monitoring et un plan de resilver réaliste.
Un rubique décisionnel pratique
J’utilise trois questions en production :
- Quel est le chemin de récupération si quelques blocs sont illisibles ? Si la réponse est « restaurer depuis une sauvegarde en quelques heures » ou « reconstruire l’objet », vous n’avez probablement pas besoin de
copies. - Quel est le profil d’écriture ? Si c’est beaucoup d’écritures aléatoires à fort turnover,
copiespeut transformer un système stable en générateur de plaintes de latence. - Puis-je contraindre le rayon d’explosion ? Si vous pouvez isoler les données critiques dans un dataset et y appliquer
copies, la fonctionnalité devient viable. L’usage global est comment vous vous retrouvez à expliquer la mathématique du stockage aux finances.
Performance et coûts en capacité (les parties que vous ressentez)
Capacité : généralement proche de linéaire, parfois non
L’attente naïve est correcte la plupart du temps : copies=2 double approximativement l’espace référencé pour ce dataset ; copies=3 le triple approximativement.
La compression et le recordsize peuvent réduire les nombres absolus, mais l’effet multiplicateur reste : chaque bloc que vous gardez, vous le gardez plusieurs fois.
Là où les gens sont surpris, ce n’est pas le multiplicateur ; c’est l’interaction avec les snapshots et les schémas de réécriture. ZFS est copy-on-write. Si vous avez des snapshots et que vous réécrivez des blocs, vous vous retrouvez avec :
- des anciens blocs conservés par les snapshots (avec le réglage copies qui existait quand ils ont été écrits),
- des nouveaux blocs écrits avec le réglage copies actuel,
- et potentiellement plusieurs générations de données dupliquées si le dataset churne.
Amplification d’écriture : le vrai prix
Chaque copie supplémentaire est une allocation supplémentaire, une E/S supplémentaire, un travail de checksum supplémentaire, et des mises à jour de métadonnées supplémentaires. Sur des HDD en RAIDZ, la douleur se manifeste souvent comme :
- une latence d’écriture plus élevée et des temps de txg sync plus longs,
- plus de fragmentation (plus d’allocations par écriture logique),
- pire IOPS pour petits écrits.
Sur des pools SSD/NVMe, ça peut toujours nuire, mais le symptôme est souvent l’endurance et le comportement de garbage collection, plus des pics de latence occasionnels quand le système est sous pression mémoire.
Comportement en lecture : parfois mieux, parfois pire
Les lectures peuvent bénéficier si une copie est lente ou échoue de façon intermittente ; ZFS peut en choisir une autre. Mais vous pouvez aussi empirer les lectures en créant des layouts plus fragmentés et plus de surcharge métadonnée au fil du temps.
Dans des conditions propres, les lectures ne deviennent généralement pas magiquement plus rapides grâce à copies.
Blague n°2 : copies=3 ressemble un peu à amener trois parapluies pour éviter la pluie — vous serez quand même mouillé si le toit s’effondre, et maintenant vous avez trois parapluies à faire sécher.
Schémas pratiques : où copies brille
Schéma 1 : dataset « petit mais terrifiant »
Un petit dataset contenant des éléments comme des exports d’état Terraform, des assets de bootstrap de cluster, ou des autorités de certification peut être existentiel.
Le stocker avec copies=2 vous achète une marge supplémentaire contre des erreurs médias localisées sans repenser tout le pool.
Schéma 2 : arbres de fichiers riches en métadonnées
Des millions de petits fichiers signifient que le graphe de métadonnées est le système. Perdre un bloc de répertoire ou un bloc indirect n’est pas « un fichier en moins » ; cela peut être « tout ce sous-arbre est maintenant une scène de crime ».
copies=2 peut réduire la probabilité qu’un seul mauvais bloc devienne une expédition de récupération.
Schéma 3 : l’extrémité « dégradé est normal »
Si vous exploitez des sites distants où remplacer un disque prend des jours, pas des heures, vous passez du vrai temps en mode dégradé.
Des copies supplémentaires peuvent améliorer vos chances pendant cette fenêtre — particulièrement sur RAIDZ — quand les scrubs/resilvers sont plus susceptibles de rencontrer des erreurs de lecture ailleurs.
Schéma 4 : protection du special vdev, soigneusement limitée
Si vous utilisez un special vdev, gardez-le redondant en priorité. Ensuite, envisagez des copies supplémentaires sur les datasets qui placent de nombreux petits blocs là-bas, mais uniquement si la capacité est ample et que vous avez mesuré le comportement des txg.
L’objectif n’est pas de « rendre le special vdev sûr ». L’objectif est de réduire la chance que quelques blocs méchants ruinent votre semaine.
Trois mini-récits du monde de l’entreprise (douleur incluse)
Mini-récit n°1 : Un incident causé par une mauvaise hypothèse
Une entreprise de taille moyenne exploitait un seul pool pour « tout », construit sur un grand RAIDZ2. Un chef d’équipe a lu à propos de copies=2 et a décidé de l’activer sur le dataset contenant des images de disques VM, en se disant : « RAIDZ2 plus copies=2 équivaut à pratiquement RAIDZ4, non ? » Ce changement a été accepté parce que ça semblait être une sécurité gratuite.
Deux mois plus tard, un patch d’hyperviseur a déclenché une rafale d’écritures : snapshots VM, mises à jour de paquets et churn de logs. La latence a explosé. Les graphiques de stockage ressemblaient à un sismographe. La première réaction fut d’accuser le réseau, puis les hyperviseurs, puis « peut-être le nouveau noyau ». Personne n’a suspecté la propriété du système de fichiers parce que, en théorie, c’était « juste de la redondance ».
Le postmortem fut humiliante : le dataset avait une charge d’écriture élevée et copies=2 a doublé la pression d’allocation et le travail de sync. Le pool n’était pas plein, mais il était à bout de patience — les temps de txg sync ont augmenté, et les écritures synchrones (et tout ce qui se prétend synchrones) ont commencé à faire la queue derrière la réalité.
La mauvaise hypothèse n’était pas que ZFS pouvait stocker plusieurs copies. La mauvaise hypothèse était que la redondance est gratuite si vous n’achetez pas de disques. Ils ont supprimé copies pour les images VM, créé un petit dataset « config critique » avec copies=2, et remis le reste de la discussion sur la redondance à sa place : design des vdevs, spares et réplication.
Mini-récit n°2 : Une optimisation qui a échoué
Une autre organisation a décidé « d’optimiser » leur usage du special vdev. Ils avaient des NVMes en special vdev pour les métadonnées et les petits blocs, et quelqu’un voulait des performances maximales pour un cache de build monorepo : beaucoup de petits fichiers, beaucoup de métadonnées, très chaud.
Ils ont réglé special_small_blocks sur une valeur importante pour que plus de données aillent sur le special vdev, puis ils ont ajouté copies=2 « pour être sûrs ».
Les performances semblaient initialement excellentes. Les builds étaient plus rapides, les opérations lourdes en inodes volaient, et tout le monde a félicité l’équipe stockage pour son « innovation ». Puis le special vdev a commencé à se remplir plus vite que prévu. Parce qu’il hébergeait maintenant non seulement des métadonnées mais une énorme quantité de petites données, copies=2 a doublé la consommation là-bas. Le pool global avait beaucoup d’espace ; le special vdev non.
Une fois que le special vdev a franchi un seuil d’encombrement inconfortable, les allocations sont devenues plus lentes, la fragmentation a augmenté, et le système a développé un nouveau hobby : des pics de latence aux pires moments possibles (jours de release, bien sûr). L’« optimisation » avait déplacé une contrainte de capacité dans le chemin le plus chaud.
La résolution n’a pas été de déclarer les special vdevs « mauvais ». Ce fut de les traiter comme une couche séparée avec sa propre planification de capacité. Ils ont réduit special_small_blocks, gardé le special vdev redondant, et ont utilisé copies=2 seulement sur un très petit dataset qui le méritait vraiment. Le cache de build a reçu des ajustements de performance ailleurs — parce que le stockage n’est pas un substitut à la suppression des anciens caches.
Mini-récit n°3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe de services financiers avait une habitude qui paraissait douloureusement conservatrice : fenêtres de scrub mensuelles, alertes sur erreurs de checksum, et une politique que tout dataset contenant « keys, auth, bootstrap » recevait copies=2 — mais seulement ces datasets, et seulement après vérification de la capacité.
Personne n’en faisait des gorges chaudes. Ce n’était pas glamour. C’était de la paperasserie avec des commandes CLI.
Pendant un scrub de routine, ZFS a rapporté un petit nombre d’erreurs de checksum sur un disque. Le disque n’a pas franchi les seuils SMART ; il n’est pas tombé hors ligne. Il a juste commencé à renvoyer occasionnellement des données corrompues. Le scrub a détecté des mauvais blocs, ZFS les a guéris grâce à la redondance, et des alertes ont été déclenchées. L’équipe a remplacé le disque pendant les heures ouvrables sans drame.
Une semaine plus tard, ils ont eu un second incident : un périphérique séparé avait quelques secteurs illisibles. Cette fois, le dataset affecté était l’un des datasets « keys et bootstrap ». Parce qu’il avait copies=2, ZFS a pu lire depuis une copie alternative sans dépendre exclusivement de la reconstruction par parité sous stress.
Rien n’a explosé. Pas de war room. Pas de « restauration depuis bande ». Juste quelques tickets et un remplacement matériel. La pratique ennuyeuse n’était pas tant d’utiliser copies ; c’était de l’utiliser de manière étroite, de surveiller leurs pools comme des adultes, et d’exécuter des scrubs selon le calendrier même quand rien ne brûlait. L’ennui est sous-estimé en stockage.
Tâches pratiques : commandes, sorties et interprétation
Les commandes ci-dessous supposent des outils dans le style OpenZFS on Linux. Adaptez les noms de pool/dataset. L’objectif n’est pas de mémoriser les options ; c’est d’acquérir une mémoire musculaire pour vérifier le comportement avant et après avoir touché à copies.
Tâche 1 : Inspecter les réglages actuels de copies et l’héritage
cr0x@server:~$ zfs get -r copies tank
NAME PROPERTY VALUE SOURCE
tank copies 1 default
tank/critical copies 2 local
tank/critical/ca copies 2 inherited from tank/critical
tank/vm copies 1 inherited from tank
Interprétation : vous voulez voir SOURCE comme local uniquement là où vous le vouliez. L’héritage accidentel est la façon dont une « petite mesure de sécurité » devient « pourquoi le pool est plein ? ».
Tâche 2 : Changer copies pour un seul dataset
cr0x@server:~$ sudo zfs set copies=2 tank/critical
Interprétation : cela affecte les nouvelles écritures (nouveaux blocs). Les blocs existants restent tels qu’ils étaient jusqu’à réécriture.
Tâche 3 : Confirmer si les données existantes sont réécrites (ce ne sera pas le cas)
cr0x@server:~$ zfs get copies tank/critical
NAME PROPERTY VALUE SOURCE
tank/critical copies 2 local
Interprétation : la propriété est définie, mais cela ne duplique pas rétroactivement les blocs existants.
Tâche 4 : Forcer une réécriture pour que les blocs obtiennent la nouvelle politique de copies
cr0x@server:~$ sudo rsync -a --inplace --checksum /tank/critical/ /tank/critical/.rewrite-pass/
Interprétation : réécrire peut être coûteux et crée de nouvelles données. En pratique, vous ferez une réécriture contrôlée (parfois via un dataset temporaire) et vérifierez d’abord l’espace libre. Attention : « rétrofiter des copies » n’est pas une opération gratuite.
Tâche 5 : Suivre l’espace référencé et l’espace logique utilisé
cr0x@server:~$ zfs list -o name,used,refer,logicalused,logicalrefer,compressratio tank/critical
NAME USED REFER LUSED LREFER RATIO
tank/critical 18G 18G 11G 11G 1.60x
Interprétation : logical* montre la taille logique avant compression ; USED/REFER sont sur disque. Avec copies=2, vous vous attendez à ce que le sur-disque augmente par rapport au logique — sauf si la compression le compense.
Tâche 6 : Surveiller la santé du pool et les compteurs d’erreurs
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:19 with 0 errors on Sun Dec 22 03:10:05 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
errors: No known data errors
Interprétation : les erreurs CKSUM sont celles qui vous disent « le disque a renvoyé des données corrompues ». C’est là que la redondance et les copies supplémentaires comptent.
Tâche 7 : Lancer un scrub (et savoir à quoi s’attendre)
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 02:00:02 2025
1.02T scanned at 1.40G/s, 210G issued at 290M/s, 6.20T total
0B repaired, 3.39% done, 06:40:12 to go
Interprétation : les scrubs sont la façon de trouver les erreurs latentes tant que vous avez de la redondance. Si copies est votre filet de sécurité, les scrubs vous permettent de confirmer que le filet existe.
Tâche 8 : Mesurer le comportement des txg sync (un proxy pour « les écritures font mal »)
cr0x@server:~$ sudo zpool get -H -o name,property,value,source autotrim,ashift,autoreplace tank
tank autotrim off default
tank ashift 12 local
tank autoreplace off default
Interprétation : ce n’est pas encore le txg, mais vous validez les fondamentaux. Les erreurs d’ashift et les réglages de trim peuvent dominer les performances, et les gens blâment copies quand le vrai problème est un mauvais alignement ou le comportement des périphériques.
Tâche 9 : Observer l’I/O en temps réel par pool et vdev
cr0x@server:~$ zpool iostat -v tank 2
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 5.20T 1.00T 120 980 12.3M 210M
raidz2-0 5.20T 1.00T 120 980 12.3M 210M
sda - - 20 170 2.1M 35.0M
sdb - - 21 165 2.1M 34.1M
sdc - - 18 162 2.0M 33.8M
sdd - - 19 161 2.1M 34.6M
sde - - 21 160 2.0M 35.2M
sdf - - 21 162 2.0M 36.1M
-------------------------- ----- ----- ----- ----- ----- -----
Interprétation : après avoir activé copies=2 sur un dataset à écriture lourde, vous verrez souvent les opérations d’écriture grimper et la bande passante augmenter pour le même débit applicatif. C’est l’amplification d’écriture qui se montre au grand jour.
Tâche 10 : Vérifier les propriétés du dataset qui interagissent avec copies
cr0x@server:~$ zfs get -o name,property,value -s local,inherited,default recordsize,compression,sync,copies,logbias tank/critical
NAME PROPERTY VALUE SOURCE
tank/critical recordsize 128K default
tank/critical compression lz4 inherited from tank
tank/critical sync standard default
tank/critical copies 2 local
tank/critical logbias latency default
Interprétation : sync, recordsize et compression déterminent souvent si copies est tolérable. Un workload sync avec petit recordsize et copies supplémentaires est la recette pour créer une file de support pour l’équipe stockage.
Tâche 11 : Vérifier l’empreinte des snapshots avant de changer la politique
cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -s creation tank/critical | tail -n 5
tank/critical@auto-2025-12-23-0100 220M 18G Mon Dec 23 01:00 2025
tank/critical@auto-2025-12-23-0200 110M 18G Mon Dec 23 02:00 2025
tank/critical@auto-2025-12-23-0300 190M 18G Mon Dec 23 03:00 2025
tank/critical@auto-2025-12-23-0400 140M 18G Mon Dec 23 04:00 2025
tank/critical@auto-2025-12-23-0500 160M 18G Mon Dec 23 05:00 2025
Interprétation : les snapshots épinglent d’anciens blocs. Si vous passez à copies=2 puis que vous churnez les données, vous pouvez finir par payer pour l’historique single-copy et le futur double-copy jusqu’à ce que les snapshots expirent.
Tâche 12 : Valider la présence et la santé du special vdev (si utilisé)
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
special
mirror-1 ONLINE 0 0 0
nvme0n1p1 ONLINE 0 0 0
nvme1n1p1 ONLINE 0 0 0
Interprétation : si vous avez un special vdev, traitez-le comme un citoyen de première classe. Des copies supplémentaires ne sauveront pas un design non redondant de special vdev.
Tâche 13 : Repérer la pression de fragmentation à l’échelle du pool
cr0x@server:~$ zpool get fragmentation tank
NAME PROPERTY VALUE SOURCE
tank fragmentation 38% -
Interprétation : des copies supplémentaires augmentent l’activité d’allocation. Sur des pools de longue durée, cela peut augmenter la fragmentation et nuire à la latence. Cela ne signifie pas « n’utilisez jamais copies », mais plutôt « ne l’utilisez pas aveuglément et pour toujours ».
Tâche 14 : Confirmer qu’il n’y a pas de changement accidentel à l’échelle du pool
cr0x@server:~$ zfs get copies tank
NAME PROPERTY VALUE SOURCE
tank copies 1 default
Interprétation : si ceci montre local à la racine du pool, vous avez probablement doublé le coût de chaque dataset sauf s’il est surchargé. C’est le genre de découverte que vous voulez à 10:00, pas à 02:00.
Méthode de diagnostic rapide
Quand quelqu’un dit « le stockage est lent » et que vous avez récemment touché à copies, ne commencez pas par débattre de philosophie. Commencez par réduire le goulot d’étranglement en quelques minutes.
Étape 1 : Le pool est-il sain, ou masquons-nous une défaillance ?
- Vérifiez
zpool status -vpour des erreurs de lecture/écriture/checksum, des vdevs dégradés, ou un resilver/scrub en cours. - Si vous voyez des erreurs de checksum, supposez d’abord un problème de périphérique ou de chemin. Les copies supplémentaires peuvent vous aider à tenir, mais elles ne sont pas la cause racine.
Étape 2 : Est-ce la pression de capacité ou la pression du special vdev ?
- Vérifiez
zfs listetzpool listpour l’espace libre ; ZFS n’aime pas être très plein. - Si vous utilisez un special vdev, vérifiez son allocation et qu’il n’est pas proche du plein. Un pool « OK » avec un special vdev « assez plein » peut quand même mal se comporter.
Étape 3 : Est-ce l’amplification d’écriture et la contention txg ?
- Surveillez
zpool iostat -v 2pendant le ralentissement. Si les ops d’écriture et la bande passante sont élevées mais que le débit applicatif est stable, vous payez une taxe d’amplification. - Vérifiez les datasets impliqués :
zfs get copies,sync,recordsize,compression. Un dataset sync-heavy aveccopies=2est un suspect de première ligne.
Étape 4 : Est-ce qu’un disque lent (ou mauvais) traîne le vdev ?
- Sur les mirrors, un côté lent peut créer des comportements de latence étranges selon la politique de lecture et l’ordonnancement.
- Sur RAIDZ, un disque malade peut bottleneck sévèrement les reconstructions et les scrubs/resilvers.
Étape 5 : Confirmez que vous n’avez pas accidentellement élargi le rayon d’explosion
zfs get -r copies tanket cherchez un héritage inattendu.- Vérifiez si un dataset « temporaire » avec
copies=3est devenu parent de tout parce que quelqu’un aime les raccourcis.
Erreurs courantes : symptômes et corrections
Erreur 1 : Mettre copies=2 à la racine du pool
Symptôme : l’utilisation du pool augmente de façon inattendue ; la latence d’écriture augmente sur de nombreux workloads.
Correction : remettez-le à la racine et appliquez-le explicitement seulement sur les datasets visés.
cr0x@server:~$ sudo zfs inherit copies tank
cr0x@server:~$ sudo zfs set copies=2 tank/critical
Erreur 2 : S’attendre à une protection rétroactive sans réécrire les données
Symptôme : vous avez mis copies=2, mais les scrubs rapportent toujours des erreurs irrécupérables sur d’anciens blocs (ou vous ne voyez pas l’augmentation de capacité attendue).
Correction : planifiez une réécriture/migration du dataset spécifique si vous devez vraiment dupliquer d’anciens blocs. Faites-le avec espace libre vérifié et conscience de la politique de snapshot.
Erreur 3 : Utiliser copies pour « réparer » un design de vdev risqué
Symptôme : vous ne pouvez toujours pas tolérer la perte d’un second disque en RAIDZ1 ; un resilver dégradé est toujours terrifiant.
Correction : redesign avec la parité/mirrors appropriés, ajoutez des hot spares, et utilisez la réplication. copies n’est pas un substitut à l’ingénierie des domaines de panne.
Erreur 4 : Activer copies=2 sur datasets VM ou DB à forte écriture
Symptôme : pics de latence soudains après « amélioration de sécurité », augmentation des temps de txg sync, plus d’IO wait, et propriétaires d’applications mécontents.
Correction : revenez à copies=1 pour ces datasets ; utilisez une redondance appropriée et envisagez SLOG/tuning sync seulement si vous comprenez parfaitement les exigences de durabilité.
cr0x@server:~$ sudo zfs set copies=1 tank/vm
Erreur 5 : Remplir l’espace du special vdev par accident
Symptôme : le pool a de l’espace libre, mais les opérations métadonnées ralentissent ; l’allocation sur le special vdev est élevée ; des pics de latence surviennent lors de builds ou de tempêtes de fichiers.
Correction : réduisez la charge sur le special vdev (ajustez les politiques de placement des datasets, taillez les datasets de petits fichiers), et assurez-vous que la capacité du special vdev est dimensionnée pour le long terme. Évitez de la doubler avec copies à moins que vous n’ayez budgété l’espace.
Erreur 6 : Traiter copies comme un plan de sauvegarde
Symptôme : ransomware, suppression accidentelle, ou une mauvaise automation détruit les données sur toutes les copies instantanément.
Correction : utilisez des snapshots, l’immutabilité quand disponible, et la réplication/les sauvegardes hors site. Les copies supplémentaires restent « à l’intérieur du rayon d’explosion ».
Listes de contrôle / plan étape par étape
Checklist A : Avant d’activer copies=2
- Définir le périmètre du dataset : confirmez que vous pouvez isoler les données critiques dans leur propre dataset (ou un petit sous-arbre).
- Mesurer la baseline : capturez
zpool iostat -v,zpool status, et les métriques datasetused/refer/logicalused. - Confirmer la marge d’espace libre : ne faites pas ça sur un pool déjà proche de la saturation ; la pression sur l’allocateur masquera vos résultats réels.
- Vérifier la rétention des snapshots : comprenez combien de temps les anciens blocs single-copy resteront épinglés si vous churnez les données.
- Confirmer la santé des vdevs : si vous avez déjà des erreurs de checksum, corrigez le matériel d’abord ; ne camouflez pas ça avec des copies supplémentaires.
Checklist B : Activer et valider en sécurité
- Définissez
copies=2seulement sur le dataset ciblé. - Écrivez une petite charge test et vérifiez le delta de la comptabilité d’espace (attendez-vous à plus de croissance sur-disque par écriture logique).
- Surveillez la latence et les symptômes de txg pendant vos pics normaux.
- Exécutez un scrub dans votre cycle de maintenance normal et vérifiez que « 0 errors » reste vrai.
Checklist C : Si vous devez dupliquer des données existantes
- Planifiez l’espace : vous pouvez avoir temporairement besoin d’espace libre supplémentaire pour réécrire.
- Choisissez une méthode de réécriture : une copie contrôlée vers un nouveau dataset (préférée), ou une réécriture in-place (plus risquée).
- Validez avec les checksums : utilisez zfs send/receive quand approprié pour forcer la sémantique de réécriture tout en préservant les snapshots, mais seulement si cela correspond à votre modèle opérationnel.
- Faites vieillir les snapshots : assurez-vous que les anciens blocs disparaissent éventuellement, sinon vous paierez pour les deux mondes indéfiniment.
FAQ
1) Est-ce que copies=2 signifie que je peux survivre à deux pannes disque ?
Non. La tolérance aux pannes disque est déterminée par la disposition de vos vdevs (niveau mirror/RAIDZ). copies ajoute des instances de bloc supplémentaires dans cette disposition ; il ne crée pas un nouveau domaine de panne indépendant.
2) Est-ce que copies protège contre la corruption silencieuse des données ?
ZFS utilise les checksums pour détecter la corruption silencieuse. La redondance la répare. Des copies supplémentaires ajoutent des sources valides additionnelles pour la réparation quand un emplacement est mauvais. Elles améliorent les probabilités pour certains patterns de corruption, mais ne remplacent pas une redondance appropriée et des scrubs.
3) copies=2 est-il utile sur un pool mirror ?
Parfois, pour des petits datasets critiques. Mais les mirrors fournissent déjà plusieurs copies physiques. Sur des workloads chargés en mirror, copies peut être un moyen coûteux d’acheter un petit gain de fiabilité supplémentaire.
4) copies=2 est-il utile sur RAIDZ ?
Plus souvent que sur les mirrors — quand utilisé de façon ciblée. La parité RAIDZ peut reconstruire, mais les périodes dégradées et les UREs sont où des copies allouées indépendamment peuvent améliorer la récupérabilité pour des données à haute valeur.
5) Le réglage copies=2 duplique-t-il automatiquement les données existantes ?
Non. Il affecte les nouvelles écritures. Pour l’appliquer aux blocs existants, vous devez réécrire/migrer les données.
6) Comment copies interagit-il avec la compression ?
La compression se fait par bloc. ZFS stocke le bloc compressé plusieurs fois. Si les données se compressent bien, le coût absolu en espace des copies supplémentaires est plus petit — mais le multiplicateur persiste.
7) copies=3 sera-t-il jamais la bonne réponse ?
Rarement, mais oui : pour des datasets minuscules, existentiels et rarement écrits (par exemple un arbre de bootstrap minimal), où le coût en capacité est négligeable et vous voulez une marge maximale contre des blocs illisibles localisés. Si vous l’envisagez pour des téraoctets, marquez une pause et relisez la question.
8) copies est-il meilleur que la réplication ?
Ce sont des outils différents. copies améliore la survivabilité à l’intérieur d’un pool contre certains problèmes au niveau bloc. La réplication crée une copie indépendante dans un autre pool/système, ce qui aide contre les catastrophes, les erreurs opérateur et les pannes site-level. Si vous ne pouvez en payer qu’un, la réplication gagne généralement.
9) Puis-je définir copies uniquement pour les métadonnées ?
Pas directement comme un toggle « métadonnées seulement » par dataset. Vous pouvez toutefois cibler des datasets riches en métadonnées, et concevoir avec special vdevs et choix de recordsize pour influencer ce qui est considéré « petit ». Mais n’oubliez pas : influencer n’est pas garantir.
10) Quel est le plus grand risque opérationnel d’activer copies ?
La dérive du périmètre et la régression de performance. Les pannes que j’ai vues n’étaient pas « ZFS a cassé » ; elles étaient « quelqu’un a doublé les écritures sur le dataset le plus actif et n’a pas mesuré ».
Conclusion
copies=2 et copies=3 ne sont pas des gadgets, et ce ne sont pas une mise à niveau universelle. Ce sont des leviers de redondance ciblés qui fonctionnent mieux quand vous pouvez pointer un petit dataset et dire : « Si ça prend un mauvais bloc au mauvais moment, on perd une journée (ou une entreprise). »
Utilisez copies comme vous utilisez la suppression d’incendie : concentrée là où le risque est élevé, testée périodiquement (scrubs), et ne la confondez jamais avec « le bâtiment ne peut pas brûler ». Si vous voulez une vraie amélioration de domaine de panne, construisez-la avec le design des vdevs et la réplication. Si vous voulez une marge supplémentaire pour quelques blocs critiques sans reconstruire le monde, copies peut être judicieux — mais ne la payez pas partout.