Tout va bien jusqu’à ce que le pool cesse d’aller bien. Un jour vous lancez un zfs send de routine ; le lendemain quelqu’un vous envoie sur Slack une capture d’écran contenant checksum error comme si c’était un horoscope. Vous exécutez zpool status, il indique vaguement « corrupted data », et votre confiance subit un petit mais mesurable coup d’IOPS.
C’est là que zdb intervient. C’est le débogueur de ZFS : une lampe torche qui peut aussi faire office de laser. Il peut vous dire ce que ZFS voit réellement sur disque, pas seulement ce que les outils haut niveau rapportent poliment. C’est aussi l’outil que l’on évite jusqu’à en avoir besoin — parce qu’il est tranchant, parfois sous-documenté, et qu’il n’hésite pas à vous montrer des vérités inconfortables.
Ce qu’est zdb (et ce qu’il n’est pas)
zdb est l’outil d’introspection de ZFS. Si zpool est votre tableau de bord de flotte et zfs votre interface produit, zdb est la console de l’ingénieur avec la plaque arrière enlevée. Il lit les structures sur disque et peut imprimer les métadonnées internes : pointeurs de blocs, ensembles d’objets, datasets, metaslabs, le MOS (Meta Object Set), les feature flags, le DDT (dedup tables), la comptabilité des spacemaps, et plus encore. Ce n’est pas « un outil de réparation » au sens miraculeux du terme. C’est un outil de vérité. Les réparations se font typiquement par scrub, resilver, remplacement de matériel ou restauration depuis des copies connues saines.
La peur autour de zdb n’est pas irrationnelle. C’est un « debugger » au sens littéral : il vous montre la plomberie, y compris les endroits où la plomberie peut exploser. Et il a des options qui peuvent être coûteuses ou perturbatrices si vous les exécutez négligemment sur une machine de production en période de pointe. La plupart du temps, vous l’utiliserez en mode lecture seule, de façon non destructive. Vous demanderez : « Qu’est-ce que ZFS voit ? » et non « Puis-je toucher ceci jusqu’à ce que ça change ? »
Ce pour quoi zdb est excellent
- Confirmer la comptabilité d’espace : pourquoi
dfdiffère dezfs list, pourquoi le « used » ne colle pas, et où sont passés les octets. - Expliquer la performance : fragmentation des metaslabs, comportement du recordsize, ratios de compression, blocs indirects, et pourquoi un vdev hurle.
- Investiguer la corruption : faire le lien entre les erreurs rapportées et les datasets, parfois jusqu’aux objets/blocs, surtout combiné à
zpool status -vet la sortie du scrub. - Comprendre les features : vérifier ce qui est activé, utilisé ou requis sur un pool.
- Forensique : parfois identifier des objets associés à des chemins, et parfois comprendre ce qui a changé entre des snapshots.
Ce que zdb n’est pas
- Pas un outil de surveillance de routine : ce n’est pas pour des cronjobs qui s’exécutent toutes les heures sur tous les pools. Ne normalisez pas l’exécution de scans profonds comme « observabilité ».
- Pas un bouton magique « undelete » : ZFS est copy-on-write ; les snapshots sont votre undelete. Si vous n’en avez pas, zdb peut aider en forensique mais rarement par miracle.
- Pas un substitut aux scrubs :
zpool scrubest la méthode pour valider et réparer les checksums. zdb peut pointer et expliquer ; scrub peut corriger (si la redondance existe).
Un état d’esprit utile : zdb est un microscope, pas un défibrillateur. Si vous essayez de « ramener le pool », vos vrais outils sont le remplacement matériel, les options d’import/recovery, les sauvegardes et le calme.
Faits historiques et contexte qui comptent vraiment
Un peu de contexte rend zdb moins mystique et plus… mécanique. Voici quelques points concrets qui influencent la façon de le considérer.
- ZFS est né chez Sun Microsystems comme un système de fichiers + gestionnaire de volumes orienté intégrité bout en bout, et zdb fait partie de cette culture « faire confiance, mais vérifier » intégrée aux outils.
- zdb existe parce que les métadonnées ZFS sont riches : ensembles d’objets, dnodes, pointeurs de blocs, checksums et spacemaps sont des citoyens de première classe. L’outil est essentiellement un imprimeur de métadonnées avec un avis.
- Les implémentations modernes de ZFS ont divergé (Illumos, OpenZFS, ports fournisseurs). La sortie et les flags de zdb peuvent différer selon plateforme et version — considérez les exemples en ligne comme des croquis, pas comme des évangiles.
- Les feature flags ont remplacé les numéros de version dans l’évolution du format on-disk des pools. zdb est une des façons les plus claires de voir quelles features sont activées et actives sur un pool.
- Le copy-on-write change les récits de « corruption » : les anciens blocs ne sont pas réécrits en place. C’est excellent pour la cohérence et les snapshots, mais cela change la façon de raisonner sur « le fichier qui a été corrompu hier ».
- La sémantique scrub/resilver compte : ZFS peut réparer grâce à la redondance s’il sait quelle copie est correcte (via les checksums). zdb vous aide à comprendre où et pourquoi le scrub s’est plaint.
- La déduplication a toujours été un couteau aigu : le DDT est gourmand en métadonnées et peut devenir le goulot d’étranglement de performance. zdb expose des stats DDT qui expliquent « pourquoi tout est lent » mieux que la plupart des tableaux de bord.
- La fragmentation des metaslabs est réelle et se manifeste comme une douleur de l’allocateur. zdb vous donne une visibilité au niveau de l’allocateur quand « les disques ne sont pas pleins mais les écritures sont lentes ».
- Historiquement, zdb a été étiqueté « pour les développeurs » dans le ton, pas dans la capacité. En production, c’est aussi un outil pour les SRE — quand il est utilisé de façon intentionnelle et parcimonieuse.
Et oui : zdb peut sembler lire un dump hexadécimal qui a des prétentions. Mais c’est structuré, cohérent, et une fois que vous apprenez une poignée de sorties, il devient un outil pratique — pas hanté.
Règles de sécurité : comment ne pas transformer le debug en incident
Règle zéro : ne lancez pas de commandes zdb lourdes sur un pool déjà chancelant à moins de comprendre le coût. Quand la latence flambe, votre « vérification rapide » peut être la goutte d’eau finale.
Garde-fous opérationnels
- Privilégiez les opérations en lecture seule et évitez les options qui scannent chaque bloc à moins d’être hors-pointe ou sur une réplique.
- Capturez le contexte d’abord :
zpool status,zpool get,zfs get,arcstat(si disponible), et les stats I/O côté OS. zdb n’est pas le premier outil, c’est l’outil « montre-moi les internes ». - Verrouillez vos attentes de version : les flags de zdb diffèrent. Lancez
zdb -?et faites confiance à l’aide locale plus qu’à votre mémoire musculaire. - Ne « optimisez » pas uniquement sur la base de zdb : il montre les internes, pas l’expérience utilisateur. Corrélez toujours avec la latence applicative, les profondeurs de file d’attente et les logs d’erreur.
- N’essayez jamais les flags de récupération sur la seule copie : si vous testez des options d’import/recovery, entraînez-vous sur un clone ou une réplique sauvegardée par snapshot en premier.
Blague n°1 : zdb, c’est comme ouvrir le capot en conduisant — techniquement possible, socialement mal vu.
Une citation fiabilité à garder sous la main
L’espoir n’est pas une stratégie.
— General Gordon R. Sullivan
zdb est ce que vous utilisez quand vous arrêtez d’espérer et que vous commencez à prouver.
Modèle mental : ce que zdb voit et que zfs/zpool ne montreront pas
ZFS est en couches. Quand vous tapez zfs list, vous demandez à une bibliothèque sympathique : « Quels datasets connais-tu ? » Quand vous tapez zdb, vous demandez : « Qu’est-ce qui est écrit sur disque, dans le MOS, dans les ensembles d’objets, dans les arbres de blocs ? » Cette différence compte quand les métadonnées sont incohérentes, quand le pool est partiellement importé, ou quand vous faites de la forensique.
Les quelques noms internes dont vous avez besoin
- Pool / SPA : l’allocator de stockage — logique de pool de plus haut niveau.
- MOS (Meta Object Set) : le « filesystem » des métadonnées du pool. Si le MOS est mécontent, tout est mécontent.
- Dataset : la notion ZFS de filesystem/volume/snapshot, avec propriétés et références aux blocs.
- Ensemble d’objets : la collection d’objets (dnodes) pour un dataset.
- Dnode : métadonnées décrivant un objet (fichier, répertoire, ZVOL block device, etc.).
- Pointeur de bloc (blkptr) : référence à un bloc, incluant taille, checksum, txg de naissance, et DVAs physiques (où il se trouve).
- TXG : transaction group. Une séquence temporelle de changements commités ensemble.
- Metaslab : unité d’allocateur d’espace par vdev. La fragmentation et l’espace libre y vivent.
La plupart des usages de production de zdb entrent dans deux catégories : (1) « dis-moi pourquoi l’espace/la perf semblent incorrects », et (2) « dis-moi quel bloc/objet est cassé et à quel point c’est grave ». Si vous gardez cette séparation en tête, vous choisirez de meilleures commandes et éviterez de descendre en spéléologie par plaisir.
Playbook de diagnostic rapide (vérifier d’abord/puis/ensuite)
Ceci est la version on-call. Vous avez le droit d’être fatigué, pas le droit d’être aléatoire.
Premier : établissez si vous avez un problème de fiabilité ou de performance
- Signaux de fiabilité : checksum errors, I/O errors, vdevs degraded/faulted, scrub errors, erreurs de lecture/écriture inattendues.
- Signaux de performance : latence élevée avec pool « healthy », écritures lentes, lectures lentes, espace presque plein, comportement étrange d’espace libre, ARC misses, thrash de l’allocateur.
Deuxième : décidez si zdb est nécessaire
- Si
zpool statuspointe clairement vers un disque et que la redondance peut réparer, faites cela en premier (remplacer, resilver, scrub). zdb est utile mais pas toujours nécessaire. - Si le symptôme est « l’espace ne colle pas », « metaslabs fragmentés », « quel dataset consomme de l’espace », ou « quelles features sont actives », zdb est souvent le chemin le plus rapide.
- Si le pool n’importe pas, zdb peut vous dire si les labels/MOS semblent sains avant de lancer des options de récupération.
Troisième : lancez les requêtes zdb les moins coûteuses qui répondent à la question
- Configuration du pool et feature flags : confirmez ce à quoi vous avez affaire et si un mismatch d’import est probable.
- Comptabilité d’espace : vérifie « où est passé mon espace » sans parcourir chaque bloc.
- Stats des metaslabs : vérifie la fragmentation et le comportement d’allocation.
- Inspection ciblée d’objets : uniquement quand vous avez déjà un dataset/objet suspect.
Si vous cherchez rapidement un goulot d’étranglement : déterminez si vous êtes contraint par (a) la latence d’un vdev unique, (b) l’allocation/fragmentation, (c) dedup/DDT, (d) petites écritures recordsize, (e) comportements sync writes/log device, ou (f) des erreurs matérielles classiques. zdb aide surtout pour (b) et (c), et pour expliquer (a) après coup.
Tâches pratiques : commandes, signification des sorties et décisions à prendre
Ce sont des choses réelles que vous pouvez faire en production sans transformer votre box de stockage en projet scientifique. Chaque tâche inclut une commande, un exemple de sortie, ce que cela signifie, et la décision opérationnelle que vous en tirez.
Task 1: Confirm the pool’s on-disk view and top-level health clues
cr0x@server:~$ sudo zdb -C tank
MOS Configuration:
vdev_tree:
type: 'root'
id: 0
guid: 12345678901234567890
children[0]:
type: 'raidz'
id: 0
guid: 9876543210987654321
ashift: 12
nparity: 2
children[0]:
type: 'disk'
path: '/dev/disk/by-id/ata-SAMSUNG_SSD_1'
guid: 1111
children[1]:
type: 'disk'
path: '/dev/disk/by-id/ata-SAMSUNG_SSD_2'
guid: 2222
features_for_read:
com.delphix:hole_birth
org.openzfs:embedded_data
org.openzfs:project_quota
Ce que cela signifie : Ceci imprime la config MOS : topologie vdev, ashift, GUIDs et les features requises pour la lecture. C’est la source de vérité « ce que le disque dit que le pool est ».
Décision : Si les chemins de périphérique OS ont changé, les GUIDs correspondent toujours — c’est bon. Si features_for_read inclut quelque chose que votre hôte cible ne supporte pas, l’import ailleurs échouera. Planifiez les upgrades en conséquence.
Task 2: List datasets and space at the pool’s internal accounting level
cr0x@server:~$ sudo zdb -Lbbbs tank
Dataset tank [ZPL], ID 50, cr_txg 4, 1.23G used, 7.88T available
Dataset tank/home [ZPL], ID 54, cr_txg 120, 310G used, 7.55T available
Dataset tank/vm [ZVOL], ID 61, cr_txg 2201, 2.10T used, 5.75T available
Ce que cela signifie : zdb résume l’utilisation des datasets depuis les structures internes de ZFS, pas depuis df. Il peut mettre en évidence des datasets que vous aviez oubliés (surtout des zvols).
Décision : Si un dataset vous surprend, arrêtez de deviner. Confirmez avec zfs list -o space et décidez si vous avez besoin de quotas, réservations ou de nettoyer des snapshots.
Task 3: Inspect feature flags and whether they’re active
cr0x@server:~$ sudo zdb -S tank
Storage pool tank:
version: 5000
features:
async_destroy
enabled
active
embedded_data
enabled
active
spacemap_histogram
enabled
active
Ce que cela signifie : Le pool utilise des feature flags ; « enabled » signifie que le pool les supporte, « active » signifie qu’elles ont été utilisées et sont désormais requises pour la compatibilité complète.
Décision : Si vous prévoyez une migration de pool vers un appliance/hôte plus ancien, les features « active » sont vos blocages de compatibilité. Ne l’apprenez pas au milieu d’une migration.
Task 4: Validate vdev labels and GUIDs (disk identity sanity)
cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-SAMSUNG_SSD_2
------------------------------------
LABEL 0
------------------------------------
version: 5000
name: 'tank'
state: 0
txg: 902341
pool_guid: 12345678901234567890
vdev_guid: 2222
top_guid: 9876543210987654321
Ce que cela signifie : Ceci lit le label ZFS sur disque. C’est ainsi que vous prouvez « ce disque appartient à ce pool », indépendamment des noms Linux.
Décision : Quand quelqu’un a interverti des câbles ou qu’un contrôleur a renuméroté les disques, ceci évite de remplacer le mauvais disque. Si un label de disque pointe vers un autre pool, arrêtez-vous et enquêtez avant toute action destructive.
Task 5: Check metaslab fragmentation and allocation health
cr0x@server:~$ sudo zdb -mm tank
Metaslab statistics for pool 'tank':
vdev 0: raidz
metaslabs: 512
free space: 5.75T
fragmentation: 62%
largest free segment: 128M
Ce que cela signifie : La fragmentation ici est de l’ordre de l’allocateur, pas de la « fragmentation des fichiers ». Une fragmentation élevée avec un largest-free-segment petit signifie que les allocations deviennent coûteuses, surtout pour les grands blocs.
Décision : Si la fragmentation est élevée et que les écritures sont lentes, vous pouvez (a) libérer de l’espace (supprimer + zpool trim si SSDs, selon la configuration), (b) ajouter des vdevs pour augmenter la capacité et réduire la pression d’allocation, ou (c) planifier une réécriture/migration. Ne tentez pas de « défragmenter » ZFS ; ce n’est pas le bon modèle.
Task 6: See space maps and histogram hints (is space accounting weird?)
cr0x@server:~$ sudo zdb -DD tank
DDT-sha256-zap-duplicate: 1248 entries, size 1.10M on disk, 2.40M in core
DDT-sha256-zap-unique: 98122 entries, size 86.0M on disk, 210M in core
Ce que cela signifie : Ce sont des informations sur la table de dédup. « In core » indique une pression mémoire quand la dédup est activée et utilisée.
Décision : Si la dédup est activée et que votre ARC/mémoire est serrée, attendez-vous à une dégradation des performances sous charge. Si la dédup n’est pas critique, planifiez une migration plutôt que d’espérer qu’elle se comporte bien.
Task 7: Identify what object number corresponds to a file path (targeted forensics)
cr0x@server:~$ sudo zdb -vvv tank/home 2>/dev/null | head -n 20
Dataset tank/home [ZPL], ID 54, cr_txg 120, 310G used, 7.55T available
Object Number Type
1 1 ZFS plain file
2 2 ZFS directory
3 3 ZFS plain file
Ce que cela signifie : Dumper la liste complète d’objets est coûteux ; même un échantillon montre le modèle d’objets. Sur de nombreux systèmes, vous utiliserez des approches plus ciblées (comme trouver d’abord un inode) plutôt que de tout dumper.
Décision : Si vous enquêtez sur un fichier connu, ne forcez pas un scan complet. Utilisez le mapping inode/objet (tâche suivante) pour n’inspecter que l’essentiel.
Task 8: Map a Linux inode to a ZFS object and inspect its blocks
cr0x@server:~$ stat -c 'inode=%i path=%n' /tank/home/app/logs/badfile.log
inode=914227 path=/tank/home/app/logs/badfile.log
cr0x@server:~$ sudo zdb -dddd tank/home 914227 | sed -n '1,25p'
Object lvl iblk dblk dsize dnsize bonus type
914227 1 128K 16K 512K 512 320 ZFS plain file
path /app/logs/badfile.log
gen 7241
size 501760
parent 912000
Indirect blocks:
0 L1 0:10000:20000 20000L/10000P F=1 B=81234/81234 cksum=on
Ce que cela signifie : Sur de nombreuses plateformes, les numéros d’objet ZFS correspondent aux inodes. zdb -dddd imprime le dnode et l’arbre de blocs. Les champs de type DVA montrent où résident les blocs ; les paramètres de checksum et de niveaux montrent la structure.
Décision : Si zpool status -v référence un fichier et que vous pouvez le mapper à un objet, vous pouvez déterminer s’il s’agit d’un petit objet isolé ou d’un dommage métadonnée plus large. Si c’est isolé et que vous avez de la redondance, scrub/resilver réparera probablement ; sinon restaurez ce fichier depuis un snapshot/sauvegarde.
Task 9: Check pool space accounting at the MOS level (why “used” doesn’t add up)
cr0x@server:~$ sudo zdb -b tank | sed -n '1,40p'
Traversing all blocks...
blocks = 14723918
leaked = 0
compressed = 1.82T, uncompressed = 2.61T, ratio = 1.43x
bp logical = 2.61T, bp physical = 1.82T
Ce que cela signifie : C’est une traversée complète des blocs. Cela peut être coûteux. « leaked=0 » est bon : pas de blocs alloués mais inaccessibles détectés par la traversée.
Décision : Utilisez ceci quand vous suspectez des fuites ou des incohérences sévères de comptabilité et que vous pouvez supporter le scan. Si c’est un pool occupé, planifiez hors-pointe ou exécutez sur une réplique.
Task 10: Understand compression effectiveness per dataset
cr0x@server:~$ sudo zdb -DDDDD tank/vm | sed -n '1,25p'
Dataset tank/vm [ZVOL], ID 61, cr_txg 2201
bp logical = 2.40T, bp physical = 2.33T, ratio = 1.03x
compression: lz4
Ce que cela signifie : La compression est activée mais n’apporte presque rien. Pour des images VM, c’est courant selon le filesystem invité et l’entropie des données.
Décision : Ne désactivez pas la compression par réflexe ; lz4 est peu coûteux et peut aider les métadonnées et les blocs zéro. Mais n’attendez pas qu’elle « sauve » de l’espace sur des données déjà compressées. Planifiez la capacité raisonnablement.
Task 11: Inspect a specific block pointer (deep corruption work)
cr0x@server:~$ sudo zdb -bbbb tank 0:10000:20000
Block 0:10000:20000
size=131072L/65536P compression=lz4
birth=81234 fill=1
cksum=sha256 2f3a...9c1d
DVA[0]=<0:10000:20000>
Ce que cela signifie : Vous regardez un pointeur de bloc par DVA. C’est de la « chirurgie », généralement utilisée pour corréler des checksum errors reportées avec des emplacements physiques.
Décision : Si l’inspection d’un pointeur de bloc indique un DVA unique sur un seul appareil qui échoue régulièrement, cela renforce l’option de remplacement de l’appareil ou d’enquête sur le chemin contrôleur. Si plusieurs DVAs sont impactés, vous pourriez faire face à une corruption plus large ou à des problèmes I/O systémiques.
Task 12: Print ZIL and intent log hints (sync write pain)
cr0x@server:~$ sudo zdb -iv tank | sed -n '1,60p'
ZFS_DBGMSG(zil): zil_claim: txg 902340 replayed 0 blocks
ZFS_DBGMSG(zil): zil_itxg_clean: cleaned up log blocks
Ce que cela signifie : Sur certaines plateformes, zdb peut émettre des informations liées au ZIL. Cela aide à confirmer si la relecture du log a eu lieu et si le pool se croit propre.
Décision : Si une appli se plaint de writes sync récents manquants après un crash, confirmez si le replay du ZIL a eu lieu. Si non, vous enquêtez sur les sémantiques d’import et si le pool a été importé en lecture seule ou avec des flags de récupération.
Task 13: Spot a too-small ashift after the fact (performance and wear)
cr0x@server:~$ sudo zdb -C tank | grep -n 'ashift'
18: ashift: 9
Ce que cela signifie : ashift est la taille de secteur que ZFS utilise pour l’alignement. ashift: 9 signifie des secteurs 512B. Sur les SSD modernes et nombre de HDD, l’alignement 4K (ashift 12) est le choix sensé.
Décision : Si ashift est trop petit, vous ne pouvez pas le changer in-place. Planifiez une migration ou une reconstruction. Si la performance est acceptable actuellement, planifiez quand même — car l’amplification d’usure est un incident à combustion lente.
Task 14: Check whether you’re paying the “special vdev” tax or enjoying the benefit
cr0x@server:~$ sudo zdb -C tank | sed -n '1,120p' | grep -n "special" -n
74: children[1]:
75: type: 'special'
76: id: 1
77: guid: 3333
Ce que cela signifie : Un special vdev peut stocker les métadonnées (et optionnellement les petits blocs). Cela peut être un gain de performance, ou un désastre s’il est sous-dimensionné ou non redondant.
Décision : Si vous avez un special vdev, traitez-le comme du storage tier-0 avec redondance et monitoring. S’il meurt et qu’il n’est pas redondant, votre pool peut devenir inutilisable. Ce n’est pas un périphérique « sympa à avoir » ; il est structurel.
Task 15: Confirm what ZFS thinks the pool’s uberblock history looks like (import paranoia)
cr0x@server:~$ sudo zdb -u tank | head -n 20
Uberblock[0]
magic = 0000000000bab10c
version = 5000
txg = 902341
guid_sum = 2222222222222222
timestamp = 2025-12-26 12:41:03
Uberblock[1]
txg = 902340
timestamp = 2025-12-26 12:40:52
Ce que cela signifie : Les uberblocks sont les « checkpoints » utilisés pour l’import du pool. Voir plusieurs uberblocks récents avec une progression txg monotone est réconfortant.
Décision : Si l’uberblock le plus récent est loin de ce qui est attendu ou si les timestamps semblent incorrects, suspectez des écritures incomplètes, des problèmes de cache du contrôleur, ou un disque qui ne persiste pas réellement les données. Cela change votre plan de récupération : cessez de faire confiance à « ça devrait être là ».
Blague n°2 : la sortie de zdb est la chose la plus proche qu’ont les ingénieurs stockage de la poésie — surtout parce que personne d’autre ne peut la lire.
Trois mini-récits d’entreprise venus du pays du “ça semblait raisonnable”
1) L’incident causé par une mauvaise hypothèse : « s’il importe, c’est bon »
Une entreprise de taille moyenne exploitait une plateforme VM basée sur ZFS sur une paire de serveurs de stockage. Après un événement d’alimentation, un nœud revenait et importait le pool, et semblait « suffisamment sain ». L’admin ne voyait pas de vdevs degraded. Le cluster hyperviseur a recommencé à démarrer des VMs. Tout le monde a respiré.
Deux jours plus tard, plusieurs VMs ont commencé à journaliser des erreurs filesystem. Puis une instance de base de données a planté avec des complaints de checksum à l’intérieur du guest. ZFS rapportait une liste croissante de checksum errors, mais seulement durant certains patterns de lecture. L’équipe a supposé un « bit rot », lancé un scrub, et est retournée en réunion.
Le scrub n’a pas vraiment avancé. Il rampait et se bloquait parfois. Pendant ce temps, des pics de latence frappaient les VMs pendant les heures de bureau. Ils ont remplacé un disque qui semblait « lent », mais les erreurs ont persisté. C’est alors que quelqu’un a enfin exécuté zdb -u et zdb -l sur les appareils suspects.
Les labels montraient quelque chose de moche : un chemin contrôleur présentait de manière intermittente des données obsolètes. Le pool avait importé parce que les métadonnées étaient assez cohérentes, mais les uberblocks « les plus récents » n’étaient pas aussi récents que l’équipe le supposait. zdb -u a révélé un écart suspect dans la progression des txg après l’événement d’alimentation. Combiné aux logs kernel, cela pointait vers un problème de cache d’écriture/flush — le storage acknolegeait des écritures qui n’ont jamais atteint le média stable.
La correction n’était pas une incantation filesystem. C’était matériel et politique : remplacer le contrôleur, valider les paramètres de cache, et lancer des scrubs avec isolation I/O. Ils ont restauré un petit ensemble de disques VM affectés depuis des snapshots répliqués vers l’autre nœud. La leçon retenue : le succès d’un import n’est pas la même chose que l’intégrité. zdb n’a rien « réparé » ; il a prouvé que la timeline mentait.
2) L’optimisation qui a mal tourné : la dédup comme miracle d’économie
Une grande équipe plateforme interne a reçu la directive : « Réduire l’empreinte de stockage. » Ils ont remarqué de nombreux templates VM et couches de conteneurs dupliqués. Quelqu’un a proposé d’activer la dédup ZFS sur le pool principal. Un court test semblait prometteur : l’espace a diminué sur un petit dataset, tout le monde a applaudi discrètement.
Ils ont activé la dédup plus largement. Au début, tout semblait bien. Puis est arrivé le lundi. La latence a augmenté, puis de nouveau. Les nœuds de stockage ont commencé à swapper sous charge. Les écritures ont ralenti. Les lectures ont commencé à se mettre en file. Ce n’était pas catastrophique ; c’était pire : une panne au ralenti où tout le monde ajoute des tableaux de bord jusqu’à ce que les tableaux de bord commencent aussi à timeout.
Ils ont lancé zdb -DD et ont vu les tailles du DDT et les estimations in-core. Ce n’était pas subtil. Le pool payait une taxe métadonnée qui n’entrait pas en RAM, si bien que chaque I/O devenait une chasse au trésor dans des métadonnées froides. Les hit ratios ARC ont chuté ; le CPU était occupé à faire du travail réel que personne ne voulait.
Désactiver la dédup ne supprime pas les blocs déjà dédupliqués sur disque. Ils étaient désormais engagés dans ce choix au niveau on-disk. Le plan de sortie est devenu un plan de migration : répliquer les datasets vers un nouveau pool avec dedup off, valider, basculer, puis finalement détruire l’ancien pool. Cela a demandé du temps, de la gestion du changement et de la patience.
L’optimisation qui a mal tourné n’était pas « la dédup est mauvaise ». Le vrai mode d’échec était de l’activer sans modéliser la mémoire, la charge de travail et le coût opérationnel de sortie. zdb a rendu le coût visible. Il n’a pas rendu la décision réversible.
3) La pratique ennuyeuse mais correcte qui a sauvé la mise : labels, spares et imports répétés
Une équipe d’entreprise exploitait plusieurs pools ZFS à travers plusieurs racks. Rien de fancy. Ils faisaient trois choses de manière cohérente : (1) chaque disque avait des chemins by-id stables suivis dans l’inventaire, (2) chaque pool avait des hot spares et des procédures de remplacement claires, et (3) trimestriellement, ils répétaient les étapes d’import et de récupération sur un hôte de staging en utilisant des snapshots répliqués.
Une nuit, un nœud de stockage a cassé sévèrement. L’équipe hardware a remplacé un backplane, et soudain l’OS a énuméré les disques différemment. L’admin junior de garde a fait la chose ennuyeuse correcte : avant de remplacer quoi que ce soit, il a lancé zdb -C sur le pool et zdb -l sur quelques appareils pour vérifier l’appartenance et les GUIDs.
Ils ont découvert que deux disques étaient présents mais derrière un chemin différent, et qu’un disque « manquant » était en fait là — simplement renommé. Sans cette vérification, ils auraient pu hors-ligner le mauvais disque et pousser le pool en état degraded lors de l’import.
Le pool a importé proprement. Un scrub a été planifié. La performance est restée stable. Personne n’a écrit de postmortem parce que rien n’a cassé. Le vrai gain était la procédure : inventaire + vérification des labels + répétition. zdb a été l’acteur silencieux qui a rendu le « calme et correct » possible.
Erreurs courantes (symptôme → cause racine → correction)
1) Symptom: “zfs list says one thing, df says another”
Cause racine : Vous mélangez des points de vue : espace logique dataset vs. espace physique pool, snapshots, refreservation, et le fait que df rapporte la vue du filesystem après des propriétés comme refquota.
Correction : Utilisez zfs list -o space en premier lieu, puis confirmez avec zdb -Lbbbs pool pour la vue interne. Si un dataset a une refreservation ou une grosse utilisation de snapshot, ajustez quotas/réservations et mettez en place une politique de rétention des snapshots.
2) Symptom: Pool is “ONLINE” but scrub finds checksum errors repeatedly
Cause racine : Un appareil/chemin contrôleur renvoie des données incorrectes de façon intermittente, ou vous avez des secteurs latents que la redondance corrige parfois mais pas toujours.
Correction : Remplacez le disque ou le contrôleur suspect, pas seulement « scrub plus fort ». Utilisez zdb -l pour confirmer l’identité du disque, et corrélez les emplacements d’erreur. Lancez un scrub après la remédiation matérielle.
3) Symptom: Writes slow down dramatically when pool is ~80–90% full
Cause racine : Pression d’allocateur et fragmentation des metaslabs ; de l’espace libre existe mais pas en segments utiles.
Correction : Vérifiez les stats metaslab via zdb -mm. Libérez de l’espace (supprimez données et snapshots) pour baisser l’utilisation, ou ajoutez de la capacité vdev. À long terme : n’exploitez pas des pools aussi pleins si vous tenez à la latence.
4) Symptom: After enabling dedup, everything feels like it’s running through molasses
Cause racine : Les métadonnées DDT ne tiennent pas en RAM, provoquant des misses de cache constants et beaucoup d’I/O aléatoires.
Correction : Utilisez zdb -DD pour quantifier. Si c’est déjà actif, planifiez une migration hors dedup. Si ce n’est pas encore activé, ne l’activez pas sans modèle mémoire et plan de sortie.
5) Symptom: Pool import fails on a different host “even though it’s the same disks”
Cause racine : Les feature flags requises pour la lecture ne sont pas supportées par la version ZFS de l’hôte cible.
Correction : Utilisez zdb -C pool et zdb -S pool pour voir les features requises/actives. Mettez à jour l’hôte cible ou choisissez une stratégie de compatibilité avant de déplacer les disques.
6) Symptom: Small random writes are terrible, sync-heavy workload stalls
Cause racine : SLOG absent/mal configuré, ou problèmes de latence d’appareil ; aussi mismatch recordsize/volblocksize pour la charge.
Correction : Validez le comportement de l’intent log et la latence des appareils. zdb peut fournir des indices, mais vous déciderez généralement en fonction de la charge. Pour les zvols, définissez volblocksize correctement à la création ; pour les filesystems, ajustez recordsize et les patterns I/O applicatifs.
7) Symptom: Replacing a disk doesn’t reduce errors; the “wrong disk” got pulled
Cause racine : Confiance dans les noms de périphériques OS comme /dev/sdX au lieu d’identifiants stables et des labels on-disk.
Correction : Identifiez toujours les disques via /dev/disk/by-id et vérifiez avec zdb -l avant d’hors-ligner/remplacer.
Listes de contrôle / plan étape par étape
Checklist A: Before you run zdb on production
- Notez la question que vous tentez de répondre (espace ? performance ? corruption ? import ?).
- Capturez le baseline :
zpool status,zpool get all pool,zfs get all dataset(ou au moins les propriétés pertinentes). - Vérifiez la charge : si la latence est déjà élevée, évitez les commandes de traversée de blocs.
- Confirmez plateforme/version : lancez
zdb -?et vérifiez que les flags existent comme attendu. - Privilégiez les commandes ciblées (
-C,-S,-mm,-l) avant les traversées complètes. - Consignez les sorties dans un ticket ou doc d’incident. La sortie zdb est une preuve.
Checklist B: Space mystery (“pool is full but I don’t see the data”)
- Vérifiez l’utilisation des snapshots et des clones au niveau dataset (haut niveau d’abord).
- Utilisez
zdb -Lbbbs poolpour confirmer l’utilisation interne des datasets et trouver les surprises (zvols, datasets cachés). - Si vous suspectez des fuites/incohérences de comptabilité et que vous pouvez vous permettre le coût, lancez
zdb -b poolhors-pointe. - Point de décision : si l’espace est retenu par des snapshots, corrigez la rétention et automatisez le pruning ; si c’est la pression de fragmentation, ajoutez de la capacité ou migrez.
Checklist C: Corruption investigation (“checksum errors”)
- Depuis
zpool status -v, identifiez les fichiers/datasets affectés s’ils sont listés. - Confirmez l’état de redondance : degraded ? faulted ? combien d’erreurs ?
- Vérifiez l’identité du disque suspect avec
zdb -lavant de remplacer quoi que ce soit. - Si vous pouvez mapper à un fichier, mappez inode → objet et inspectez via
zdb -dddd dataset object. - Point de décision : si la redondance existe, scrub après remédiation matérielle ; sinon, restaurez les objets affectés depuis snapshot/sauvegarde.
- Après : planifiez un scrub et revoyez câblage/logs contrôleur. ZFS vous dit souvent que quelque chose est cassé ; il ne remplace pas la discipline de root-cause.
Checklist D: Performance regression (“it was fast last week”)
- Confirmez l’état de remplissage du pool et la fragmentation via
zdb -mmet les stats normales du pool. - Vérifiez si la dédup est en jeu et à quoi ressemble le DDT (
zdb -DD). - Confirmez
ashiftet la disposition vdev viazdb -C. - Point de décision : si la fragmentation est élevée, réduisez l’utilisation/ajoutez vdev ; si la dédup épuise la mémoire, migrez ; si la disposition vdev est incorrecte, planifiez une reconstruction.
FAQ
Is zdb safe to run on a live production pool?
Pour l’essentiel, oui si vous vous en tenez aux résumés de configuration/labels/metaslabs. Évitez les traversées complètes (comme le block walking) pendant les pics de charge. Traitez-le comme un diagnostic consommateur d’I/O et CPU.
Will zdb repair corruption?
Non. Il diagnostique. Les réparations viennent de la redondance (scrub/resilver) ou des restaurations depuis snapshots/sauvegardes. zdb vous aide à comprendre l’étendue et la cause probable.
Why does zdb output differ between servers?
Les implémentations et versions de ZFS diffèrent. Les flags et formats de sortie peuvent changer. Vérifiez toujours zdb -? sur l’hôte que vous utilisez et n’assumez pas qu’un extrait de blog correspond à votre plateforme.
When should I use zdb instead of zpool/zfs?
Quand vous avez besoin de la vérité interne : feature flags, labels, fragmentation metaslab, stats DDT, historique d’uberblock, ou détails d’objet/bloc que les outils haut niveau masquent.
Can zdb help me find what’s holding space after I delete files?
Indirectement. zdb peut valider l’utilisation des datasets et parfois révéler que des snapshots/clones retiennent des blocs. La « correction » est généralement la politique de rétention des snapshots, pas plus de zdb.
Does zdb help with “deleted file recovery”?
Parfois pour la forensique, mais opérationnellement la bonne réponse est les snapshots. Si vous n’avez pas de snapshots, zdb peut identifier des objets, mais la récupération est peu fiable et longue.
What’s the single most useful zdb command to memorize?
zdb -C pool. Il vous dit ce que le pool est : disposition vdev, ashift et exigences de features. Il évite les erreurs stupides lors de remplacements et migrations.
How do I know if dedup is hurting me?
Si dedup est active et que les besoins in-core du DDT dépassent la mémoire disponible, vous verrez des misses de cache et une amplification I/O. zdb -DD pool fournit des indices de taille DDT qui corrèlent fortement avec la douleur.
Can zdb explain why my pool is slow even though it’s not full?
Oui, via la fragmentation metaslab et les stats d’allocation (zdb -mm). « Pas plein » n’est pas synonyme de « facile à allouer ». La fragmentation peut faire qu’un pool à moitié vide se comporte comme un parking saturé.
Conclusion : quoi faire la prochaine fois avant de paniquer
zdb n’est pas effrayant parce qu’il est dangereux. Il est effrayant parce qu’il est honnête. Il vous montrera volontiers que votre pool est compatible avec moins d’hôtes que vous ne le pensiez, que votre ashift était un mauvais choix de vie, ou que votre plan d’« économies d’espace » est en réalité une fournaise à métadonnées.
Prochaines étapes pratiques qui rapportent :
- Entraînez-vous sur un pool non critique : lancez
zdb -C,zdb -S,zdb -mmetzdb -ljusqu’à ce que les sorties vous paraissent familières. - Standardisez l’identification des disques en utilisant les chemins by-id et les vérifications de labels avant les remplacements. Faites-en une politique, pas un acte héroïque.
- Notez votre séquence de « diagnostic rapide » et conservez-la dans le runbook on-call. zdb est le plus efficace quand il répond à une question précise.
- Budgétez du temps pour les décisions irréversibles : dedup, special vdevs, ashift et disposition vdev sont de l’architecture. zdb vous montrera les conséquences ; il ne peut pas les défaire.
Quand le pool se comporte mal, vous n’avez pas besoin de plus de mystère. Vous avez besoin de preuves. zdb est des preuves — délivrées dans un dialecte qui récompense la patience et punit l’improvisation.