ZFS : Détecter la corruption silencieuse — quoi scruber, quand et pourquoi

Cet article vous a aidé ?

La plupart des pannes sont bruyantes : un contrôleur lâche, un lien tombe, un disque sort du pool comme un acteur perturbateur qui quitte la réunion trop tôt. La corruption silencieuse est l’inverse. Vos applications continuent de renvoyer des HTTP 200 tandis que vos données pourrissent discrètement. Puis un jour vous restaurez une sauvegarde, lancez un rapport, ouvrez une photo, relancez une vidéo ou démarrez une base de données, et vous découvrez ce que « checksum mismatch » fait ressentir dans l’estomac.

ZFS est l’un des rares systèmes de fichiers grand public qui traite « mon stockage dit qu’il a écrit les données » comme une hypothèse à vérifier, pas comme une promesse. Les scrubs sont la manière de la vérifier à grande échelle. Bien faits, ils sont ennuyeux, réguliers et salvateurs. Mal faits, ils sont soit du théâtre — soit la raison pour laquelle votre courbe de latence production ressemble à un sismographe.

Corruption silencieuse : ce que c’est (et pourquoi vous ne le remarquerez pas)

La corruption silencieuse des données survient lorsque des bits changent sans que votre logiciel n’en soit informé. Pas d’erreur I/O. Pas de kernel panic. Pas de contrôleur RAID qui hurle. La lecture réussit et renvoie des octets — juste pas les octets que vous aviez écrits. C’est ce qui en fait un problème de fiabilité, pas seulement un problème matériel.

Voici quelques mécanismes fréquents :

  • Erreurs média qui ne se manifestent pas comme des erreurs. Les disques peuvent renvoyer des lectures « réussies » avec des données erronées à cause de défauts internes, bugs de firmware, secteurs marginaux ou algorithmes de récupération qui devinent incorrectement.
  • Mauvaises écritures. Perte de puissance, erreurs de cache d’écriture, ou câbles/contrôleurs instables peuvent faire qu’une écriture atterrit de façon incorrecte ou incomplète.
  • Corruption mémoire. Les données étaient correctes sur le disque, mais la RAM a inversé un bit avant que la checksum soit calculée ou avant l’écriture.
  • Problèmes DMA/câblage. Un HBA, un backplane ou un câble légèrement défaillant peut corrompre les données en transit. Le disque a fait exactement ce qu’on lui a demandé. Le problème, c’est que vous lui avez demandé la mauvaise chose.

Les systèmes de fichiers classiques ont généralement deux choix : faire confiance à la pile en dessous, ou greffer des checksums partiels pour les métadonnées seulement. ZFS ne fait pas confiance. Il vérifie.

Une consolation sèche : la corruption silencieuse est rare sur des systèmes bien construits. Un avertissement sec : « rare » n’est pas une stratégie. « On a RAID » non plus.

Blague #1 : RAID signifie « Redundant Array of Inexplicable Decisions » quand vous supposez qu’il vérifie vos données. Le plus souvent, ce n’est pas le cas.

Comment ZFS détecte la corruption : checksums, auto-guérison et limites

ZFS vérifie les données de bout en bout en stockant une checksum pour chaque bloc (données et métadonnées) et en la validant à la lecture. Cela compte parce que la checksum est stockée séparément des données qu’elle protège — typiquement dans le pointeur de bloc parent — donc un secteur défectueux unique ne peut pas commodément endommager à la fois les données et sa checksum.

Ce que « bout en bout » signifie en pratique

Quand une application écrit un bloc :

  1. ZFS calcule une checksum du contenu du bloc.
  2. ZFS écrit le nouveau bloc sur disque (copy-on-write), puis met à jour les métadonnées pour y pointer, y compris la checksum.
  3. Plus tard, quand le bloc est lu, ZFS recalcule la checksum et la compare à celle stockée.

Si la checksum ne correspond pas, ZFS sait que les données sont incorrectes. C’est déjà important : la détection vaut mieux que l’échec silencieux. Mais ZFS peut aussi réparer si vous lui avez donné de la redondance.

Auto-guérison : seulement si vous avez une copie correcte

Avec des mirrors ou RAIDZ, ZFS peut lire une autre réplique/ensemble de parité, trouver une version correcte et réécrire la copie défaillante. C’est la « self-healing » dont on entend parler. Sans redondance (pool sur disque unique), ZFS détecte toujours la corruption, mais il ne peut pas conjurer des données correctes à partir du néant.

Ceci est le modèle mental non négociable :

  • Les checksums détectent la corruption.
  • La redondance répare la corruption.
  • Les scrubs forcent la vérification à grande échelle.

Ce que les scrubs ne sont pas

Un scrub n’est pas un bouton magique « réparez mon pool ». C’est un parcours systématique de lecture et de vérification de l’ensemble des données et métadonnées du pool, réparant ce qu’il peut en utilisant la redondance. Il ne :

  • Ne corrige pas la corruption qui existe identiquement dans toutes les répliques (données mal écrites de manière cohérente).
  • Ne corrige pas la corruption au niveau applicatif (l’application a écrit n’importe quoi ; ZFS l’a fidèlement conservé).
  • Ne remplace pas les sauvegardes ni la gestion de versions. Si la corruption est ancienne et que vous la découvrez tard, vous aurez peut-être besoin de copies historiques.

Et un scrub n’est pas la même chose qu’un resilver. Resilver est la reconstruction ciblée après remplacement ou rattachement d’un périphérique. Scrub est la vérification périodique de tout.

Une idée paraphrasée qui a bien vieilli : paraphrased idea de John Allspaw (opérations/fiabilité) : « Les systèmes échouent de manière désordonnée et surprenante ; vous avez besoin de boucles de rétroaction qui vous disent quand la réalité diverge des hypothèses. » Les scrubs sont l’une de ces boucles de rétroaction.

Ce qu’un scrub fait réellement

Un scrub ZFS parcourt l’arbre des blocs du pool et émet des lectures pour chaque bloc alloué. Pour chaque bloc, il vérifie la checksum. Si la checksum échoue et que la redondance existe, ZFS lit des copies/parités alternatives, répare la copie défaillante et enregistre l’événement. S’il n’y a pas de redondance ou si les dégâts sont irrécupérables, vous verrez des erreurs permanentes.

Profil de la charge d’un scrub

Les scrubs sont principalement des lectures à peu près séquentielles au niveau vdev, mais le schéma d’accès dépend de la fragmentation et du recordsize. Sur un pool calme avec de gros records, les scrubs peuvent être polis. Sur un pool fortement fragmenté avec beaucoup de petits blocs aléatoires, les scrubs se comportent comme une tempête de lectures aléatoires au ralenti.

Les scrubs sont en concurrence avec votre charge réelle pour :

  • Bande passante disque et IOPS
  • Profondeur de file d’attente HBA/contrôleur
  • ARC (cache) et bande passante mémoire
  • CPU (checksumming, décompression, parité)

Si votre pool est en RAIDZ et que le CPU est faible, les checksums plus la reconstruction de parité peuvent coûter plus que prévu. Sur les CPUs modernes c’est généralement acceptable. Sur des machines « on a acheté le truc le moins cher qui boote », ça peut devenir épicé.

Ce qui est vérifié

Le scrub vérifie les blocs alloués, pas l’espace libre. Il valide à la fois les métadonnées et les blocs de données. Si vous avez des snapshots, le scrub couvre aussi les blocs référencés par les snapshots, car ces blocs sont toujours alloués. C’est pourquoi les scrubs sur des pools avec beaucoup de snapshots peuvent durer une éternité : vous avez demandé à ZFS de conserver de vieux blocs, et il va les vérifier.

Pourquoi les scrubs comptent même si vous « ne lisez jamais de vieilles données »

Vous les lisez. Peut-être pas aujourd’hui, mais la première fois que vous aurez besoin de ces anciennes données est généralement le pire moment pour découvrir qu’elles sont corrompues. Les scrubs transforment « on a appris la corruption lors d’un incident » en « on a appris la corruption un mardi matin et on l’a réparée avant que quelqu’un ne le remarque ». Cette différence peut changer une carrière.

Que scruber (et ce qu’il ne faut pas confondre avec un scrub)

Scrubez le pool. Pas un dataset. Pas un répertoire. L’intégrité ZFS est une propriété au niveau du pool. Votre unité de vérité est zpool.

Cibles de scrub : la liste pratique

  • Pools de production avec redondance (mirror/RAIDZ) : scrubez régulièrement. Vous souhaitez une réparation automatique tant que c’est encore réparable.
  • Pools de sauvegarde : scrubez encore plus religieusement. Des sauvegardes non vérifiées ne sont que des archives optimistes.
  • Pools mono-disque : les scrubs détectent toujours la corruption, mais ne prétendez pas qu’ils la « réparent ». Associez-les à de bonnes sauvegardes et, de préférence, ajoutez de la redondance.
  • Stockage froid avec lectures rares : les scrubs sont votre seul chemin de lecture de routine. Sans scrubs, vous êtes à un « jour de restauration » du regret.

Ne confondez pas avec :

  • Tests SMART qui valident des signaux de santé des disques, pas la correction bout en bout de vos données.
  • Lectures de patrol RAID (RAID matériel) qui lisent des bandes mais ne valident généralement pas la correction visible par l’application.
  • Vérifications de système de fichiers sur des systèmes non-ZFS qui valident surtout la cohérence des métadonnées, pas la correction des données.
  • Sauvegardes qui ne sont pas une vérification à moins que vous testiez réellement la restauration ou au moins vérifiiez les checksums des objets stockés.

Quand scruber : des calendriers qui survivent au réel

On demande souvent la cadence « correcte » pour les scrubs. Il n’y en a pas. Il y a seulement une cadence qui correspond à votre tolérance au risque, à la température des données, à la taille des dispositifs et à votre budget opérationnel.

Voici la ligne de base opinionnée qui fonctionne dans la plupart des équipes :

  • Pools de production polyvalents : scrub mensuel.
  • Pools de sauvegarde/archivage : scrub mensuel, parfois bihebdomadaire si le pool est large et que le RTO de restauration est critique.
  • Bases de données à fort churn et clusters VM : scrub mensuel, mais contrôlez l’impact (fenêtres hors-pointe, réglages, monitoring). Si le mensuel est trop perturbant, réglez le problème d’I/O plutôt que d’arrêter la vérification.
  • Pools très volumineux (centaines de To+) : la fréquence doit tenir compte de la durée du scrub. Si un scrub prend 20 jours, « mensuel » devient une comédie. Vous devrez peut-être augmenter la bande passante disponible, réduire le churn de snapshots ou répartir les charges.

Deux contraintes comptent plus que les calendriers :

  1. Temps pour détecter vs temps pour échouer. Si vous avez des erreurs de secteur latentes qui s’accumulent, vous voulez les découvrir avant qu’un autre disque ne tombe et que la redondance soit compromise.
  2. Temps d’achèvement du scrub. Un scrub qui ne se termine jamais est un rituel, pas un contrôle.

Les scrubs interagissent aussi avec le risque de resilver. Si vous différez les scrubs pendant un an et perdez ensuite un disque, le resilver lira d’énormes quantités de données, et c’est à ce moment que les erreurs latentes apparaissent. Mieux vaut trouver et réparer les erreurs latentes pendant un scrub quand le pool est sain.

Blague #2 : Sauter les scrubs parce que « performance » revient à sauter les nettoyages dentaires à cause du « temps ». Vous paierez quand même, juste avec plus de hurlements.

Quand éviter de lancer un scrub

  • Juste avant une grosse migration, un exercice de restauration ou une rééquilibrage des données.
  • Pendant des périodes de performance dégradée connues (rebuilds, resilvers, réplication lourde).
  • Quand vous êtes déjà en perte de redondance (pool dégradé). Dans ce cas, décidez délibérément : scruber un pool dégradé peut stresser les disques restants, mais peut aussi révéler tôt des blocs illisibles. Faites-en un compromis conscient.

Tâches pratiques : commandes, sorties et décisions (12+)

Tout ce qui suit est prévu pour être copié-collé et exécuté. La clé n’est pas la commande. La clé est la décision que vous prenez après l’avoir lancée.

Task 1: Check overall pool health and the last scrub result

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data corruption.
action: Restore the file in question if possible. Otherwise restore the entire pool from backup.
  scan: scrub repaired 0B in 03:12:41 with 2 errors on Sun Feb  4 02:11:03 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        tank/data/app.db

Ce que cela signifie : Le pool est ONLINE, mais ZFS a trouvé des erreurs permanentes dans un fichier. « Repaired 0B » indique qu’il n’a pas pu guérir ces blocs à partir de la redondance, ou que les blocs endommagés étaient dans des métadonnées d’une façon qui a empêché la réparation.

Décision : Traitez cela comme un incident pour ce dataset. Restaurez l’objet affecté depuis une source connue (sauvegarde, copie de snapshot ailleurs). Si c’est un mirror et que c’est toujours irrécupérable, suspectez que la corruption a été écrite de façon identique des deux côtés.

Task 2: Start a scrub (and know what you just did)

cr0x@server:~$ sudo zpool scrub tank

Ce que cela signifie : Vous avez demandé à ZFS de commencer à scanner les blocs alloués et à vérifier les checksums.

Décision : Lancez les scrubs dans une fenêtre contrôlée sauf si vous répondez à une suspicion de corruption. Si vous le lancez pendant la charge, ne soyez pas surpris des graphiques.

Task 3: Monitor scrub progress

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Feb  4 01:13:22 2026
        1.20T scanned at 824M/s, 620G issued at 415M/s, 8.40T total
        0B repaired, 7.38% done, 05:20:11 to go
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : « Scanned » vs « issued » est important. Scanned est le progrès logique ; issued est l’I/O effectivement envoyée. Si issued est largement en retard, quelque chose bride l’I/O ou le scrub est en concurrence avec la charge.

Décision : Si l’ETA explose ou que le débit issued s’effondre pendant les heures ouvrées, envisagez de mettre en pause et de replanifier, ou de résoudre la contention (voir le playbook de diagnostic).

Task 4: Pause a scrub (because production exists)

cr0x@server:~$ sudo zpool scrub -p tank

Ce que cela signifie : Le scrub est mis en pause et peut être repris plus tard. (Le support dépend de l’implémentation ZFS ; sur OpenZFS c’est courant.)

Décision : Si vous mettez régulièrement des scrubs en pause, vous n’avez probablement pas assez de marge I/O. Corrigez cela, sinon vous finirez par ne plus scruber du tout.

Task 5: Stop a scrub (the blunt instrument)

cr0x@server:~$ sudo zpool scrub -s tank

Ce que cela signifie : Arrête le scrub. Le progrès est perdu ; le prochain scrub recommencera depuis le début.

Décision : Stoppez seulement si nécessaire. Préférez pause/reprise quand c’est supporté.

Task 6: Identify which vdev/device is producing checksum errors

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices could not be used because the label is missing or invalid.
  scan: scrub repaired 32M in 02:40:11 with 0 errors on Sun Feb  2 03:02:11 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            sda     ONLINE       0     0    18
            sdb     UNAVAIL      0     0     0  cannot open

errors: No known data errors

Ce que cela signifie : sda renvoie des données corrompues (erreurs CKSUM). sdb est indisponible. Vous fonctionnez sans redondance et votre disque restant est déjà suspect.

Décision : C’est une situation « arrêtez les I/O non essentielles ». Restaurez la redondance immédiatement. Regardez aussi les données SMART pour sda et vérifiez câblage/HBA. Une erreur de checksum est souvent un problème de chemin, pas seulement un disque.

Task 7: Map device names to physical disks (avoid replacing the wrong one)

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'sda|sdb'
lrwxrwxrwx 1 root root  9 Feb  4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K123456 -> ../../sda
lrwxrwxrwx 1 root root  9 Feb  4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K654321 -> ../../sdb

Ce que cela signifie : Vous pouvez identifier le modèle/numéro de série lié à chaque nœud de périphérique. La dénomination des périphériques ZFS doit utiliser des IDs stables quand c’est possible.

Décision : Utilisez les chemins /dev/disk/by-id dans la configuration de votre pool à l’avenir. Lors du remplacement, faites correspondre le numéro de série, pas vos espoirs.

Task 8: Pull SMART health and error counters

cr0x@server:~$ sudo smartctl -a /dev/sda
=== START OF INFORMATION SECTION ===
Model Family:     Samsung based SSDs
Device Model:     SAMSUNG MZ7LM960HAJM-00005
Serial Number:    S3Z9NX0K123456
Firmware Version: GXT5204Q
...
SMART overall-health self-assessment test result: PASSED
...
ID# ATTRIBUTE_NAME          VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   100   100   010    Pre-fail  Always       -       0
187 Reported_Uncorrect      100   100   000    Old_age   Always       -       2
199 UDMA_CRC_Error_Count    200   200   000    Old_age   Always       -       38

Ce que cela signifie : « PASSED » n’est pas un blanc-seing. UDMA_CRC_Error_Count pointe souvent vers un problème de câble/backplane/HBA. Reported_Uncorrect signifie que le périphérique a rencontré des erreurs irrécupérables.

Décision : Si les erreurs CRC augmentent, remplacez le câble/le slot du backplane, réenfoncez le disque ou déplacez-le sur un autre port avant de remplacer le disque. Si les uncorrectables augmentent, planifiez le remplacement du disque.

Task 9: Check ZFS error counters over time (baseline matters)

cr0x@server:~$ zpool status -P tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:41 with 0 errors on Sun Feb  2 03:02:11 2026
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          mirror-0                                      ONLINE       0     0     0
            /dev/disk/by-id/ata-SAMSUNG...123456        ONLINE       0     0     1
            /dev/disk/by-id/ata-SAMSUNG...654321        ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Il y a 1 erreur de checksum sur un côté du mirror. Une erreur unique peut être ancienne ou indiquer une tendance actuelle.

Décision : Enregistrez les compteurs maintenant et revérifiez après le prochain scrub et après une période d’I/O intense. Si le compteur bouge, enquêtez sur le chemin et le périphérique. S’il reste stable pendant des semaines, cela peut avoir été transitoire — mais continuez à surveiller.

Task 10: See pool and vdev properties that impact scrub behavior

cr0x@server:~$ zpool get all tank | egrep 'ashift|autoreplace|autotrim|failmode|autoexpand'
tank  ashift       12                    local
tank  autoexpand   off                   default
tank  autoreplace  off                   default
tank  autotrim     on                    local
tank  failmode     wait                  default

Ce que cela signifie : ashift=12 (secteurs 4K) est typique. autotrim affecte le comportement SSD. Ce ne sont pas des réglages de scrub directement, mais ils influencent l’amplification d’écriture, les workflows de remplacement et la stabilité des performances des périphériques.

Décision : Si vous utilisez des SSD, laissez autotrim=on sauf raison impérieuse. Pour l’automatisation du remplacement, réfléchissez bien à autoreplace — l’automatisation est superbe jusqu’à ce qu’elle remplace avec assurance le mauvais élément.

Task 11: Check dataset settings that amplify scrub pain (compression, recordsize, snapshots)

cr0x@server:~$ zfs get -o name,property,value -s local,received recordsize,compression,atime tank/data
NAME       PROPERTY     VALUE
tank/data  compression  lz4
tank/data  recordsize   128K
tank/data  atime        off

Ce que cela signifie : Valeurs raisonnables : compression LZ4, recordsize 128K, atime off. Un recordsize plus petit sur des images VM peut augmenter les métadonnées et la fragmentation, affectant le comportement des scrubs.

Décision : Pour les zvols/datasets de VM, ajustez recordsize/volblocksize délibérément. Ne blâmez pas les scrubs pour une disposition que vous avez choisie.

Task 12: Find out whether errors are tied to a specific file

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 02:58:03 with 1 errors on Sun Feb  2 03:02:11 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        tank/data/logs/2026-01-17.gz

Ce que cela signifie : ZFS peut parfois nommer le fichier affecté. Pas toujours, mais quand il peut, profitez-en.

Décision : Restaurez ou régénérez ce fichier. Pour des logs, vous pouvez accepter la perte ; pour des bases de données, non. Dans tous les cas, considérez cela comme un signal pour investiguer le périphérique/chemin sous-jacent.

Task 13: Verify whether redundancy can heal by forcing reads

cr0x@server:~$ sudo dd if=/tank/data/logs/2026-01-17.gz of=/dev/null bs=1M status=progress
104857600 bytes (105 MB, 100 MiB) copied, 0.42 s, 249 MB/s

Ce que cela signifie : Une lecture brute peut déclencher la vérification de checksum. Si le bloc est corrompu et que la redondance existe, ZFS peut réparer à la lecture (selon les réglages et le chemin d’accès).

Décision : Si la lecture renvoie des erreurs I/O ou que le fichier est illisible, vous devez restaurer depuis une sauvegarde ou un snapshot. Ne tentez pas de « cat » pour contourner une vraie corruption.

Task 14: Inspect I/O pressure during a scrub (Linux example)

cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server)  02/04/2026  _x86_64_ (16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.10    0.00    5.55   18.40    0.00   63.95

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s w_await aqu-sz  %util
sda             820.0  345000.0     0.0   0.00   12.40   420.7      5.0     120.0  5.20   10.2   96.0
sdb             790.0  339000.0     0.0   0.00   11.90   429.1      4.0     100.0  4.80   10.0   94.5

Ce que cela signifie : Les disques sont saturés (~95% util). La latence de lecture (~12 ms) peut être acceptable ou catastrophique selon votre charge.

Décision : Si la latence production souffre, planifiez les scrubs hors-pointe, augmentez le nombre de vdev (plus de spindles) ou séparez les charges. « Ne pas scruber » est la façon dont on devient un exemple à éviter.

Task 15: Confirm you’re not scrubbing because of phantom time jumps or missed runs

cr0x@server:~$ zpool history -i tank | tail -n 12
2026-02-02.03:02:11 zpool scrub tank
2026-02-02.05:58:14 zpool scrub -s tank
2026-02-03.02:01:00 zpool scrub tank
2026-02-03.06:12:09 zpool scrub -p tank
2026-02-04.01:13:22 zpool scrub tank

Ce que cela signifie : Les opérateurs (ou l’automatisation) démarrent/arrêtent des scrubs fréquemment. C’est un signe : soit le calendrier est mauvais, soit l’impact est trop élevé, soit les deux.

Décision : Corrigez le processus : définissez un propriétaire unique (automatisation ou humain), fixez une fenêtre hors-pointe et alertez quand les scrubs ne se terminent pas.

Mode opératoire de diagnostic rapide : trouver le goulet d’étranglement

Quand un scrub est lent ou que des erreurs apparaissent, vous devez répondre rapidement à trois questions : Est-ce qu’il progresse réellement ? Est-il bloqué par l’I/O, le CPU ou autre chose ? Voyons-nous une vraie corruption ou des erreurs de transport ?

Premièrement : le scrub avance-t-il, et les erreurs augmentent-elles ?

  1. Exécutez zpool status deux fois, à 60 secondes d’intervalle.
  2. Comparez « scanned » et « issued », et vérifiez si les compteurs READ/WRITE/CKSUM augmentent.
cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Feb  4 01:13:22 2026
        1.30T scanned at 815M/s, 700G issued at 430M/s, 8.40T total
        0B repaired, 8.10% done, 05:10:11 to go
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors

Si issued ne bouge pas : suspectez un périphérique bloqué, une file de contrôleur figée ou un système qui bride à cause d’une autre charge.

Si les erreurs augmentent : cessez de traiter cela comme un réglage de performance et considérez-le comme une triage d’intégrité des données.

Deuxièmement : est-ce IOPS, débit, CPU ou contention ?

  • Disque saturé : iostat -x montre %util élevé et await croissant → vous êtes limité par le stockage ou en concurrence avec la charge.
  • CPU saturé : top montre usage kernel/système élevé, surcharge de checksum/parité, possiblement compression/décompression. Les taux de scrub peuvent chuter en RAIDZ sur CPU faible.
  • ARC qui tourne : la pression mémoire peut provoquer des lectures supplémentaires ; vérifiez free -h et les outils ARC de votre plateforme.
cr0x@server:~$ top -b -n 1 | head -n 15
top - 02:11:08 up 31 days,  6:22,  2 users,  load average: 12.44, 10.80, 9.21
Tasks: 312 total,   2 running, 310 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.0 us,  0.5 sy,  0.0 ni, 70.0 id,  7.5 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  64256.0 total,   3120.4 free,  23120.9 used,  38014.7 buff/cache
MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  40110.2 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1421 root      20   0       0      0      0 I  18.2   0.0  12:44.21 z_wr_iss
 1412 root      20   0       0      0      0 I  14.7   0.0  10:03.88 z_rd_iss

Décision : Si le CPU est majoritairement idle et l’iowait élevé, vous êtes lié au stockage. Si le CPU est élevé et que les disques ne le sont pas, vous êtes limité par le calcul ou par un autre goulot (par ex. single-thread sur du matériel ancien). Changez une variable à la fois : calendrier, disposition vdev, et marge matérielle.

Troisièmement : les erreurs CKSUM sont-elles « disque défectueux » ou « chemin défectueux » ?

Les erreurs de checksum peuvent être causées par :

  • Corruption réelle du média sur un périphérique
  • Mauvais câble SATA/SAS ou expander
  • Firmware HBA ou pilote instable
  • Instabilité d’alimentation vers un disque/backplane

Corrélez les compteurs CKSUM ZFS avec les erreurs CRC SMART et les logs du noyau.

cr0x@server:~$ dmesg | egrep -i 'ata|sas|scsi|reset|crc|error' | tail -n 10
[123456.789] ata4: hard resetting link
[123457.012] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[123457.345] ata4.00: configured for UDMA/133
[123457.678] ata4.00: failed command: READ DMA EXT
[123457.679] ata4.00: status: { DRDY ERR }
[123457.680] ata4.00: error: { ICRC ABRT }

Décision : Si vous voyez des erreurs ICRC/CRC et des réinitialisations de lien, suspectez d’abord le chemin. Remplacez le câble, changez de port, mettez à jour le firmware HBA. Les disques sont accusés à tort pour bien des fautes.

Trois mini-récits d’entreprise tirés du réel

Mini-récit 1 : L’incident causé par une fausse hypothèse

L’entreprise exploitait une grande plateforme de données qui paraissait moderne de loin : containers, service mesh et dashboards partout. Le stockage était « réglé » par une paire de pools ZFS en miroir par nœud. Ils avaient une « semaine de maintenance » trimestrielle où quelqu’un lançait un scrub s’il s’en souvenait. Le plus souvent, ils ne le faisaient pas.

L’hypothèse erronée était simple : « Les mirrors nous protègent des pannes disque, et l’application réplique les données de toute façon. » Le mirror était traité comme une couverture de confort RAID1, pas comme un système d’intégrité des données. Personne ne s’est demandé à quelle vitesse la corruption serait détectée, ou ce qui se passerait si un mauvais bloc existait des deux côtés du mirror parce que la corruption avait été introduite avant que l’écriture n’atteigne le disque.

Puis est venue une demande de restauration — rien de spectaculaire. Une équipe voulait un ancien dataset pour rejouer un entraînement. Le job a échoué avec des erreurs de checksum sur quelques blocs. Les ingénieurs ont fait ce qu’ils font sous pression : ils ont relancé, redémarré, puis déplacé la charge. Les erreurs ont suivi le mouvement.

Finalement, quelqu’un a exécuté zpool status -v et a vu des erreurs permanentes dans des fichiers qui n’avaient pas été lus depuis des mois. Le pool était techniquement « ONLINE », donc la supervision était silencieuse. Le mirror servait silencieusement des blocs corrompus parce que personne n’avait forcé la vérification des données froides. Un scrub mensuel l’aurait trouvé assez tôt pour réparer à partir de la redondance ou à partir de snapshots encore existants ailleurs. Au lieu de cela, les seules copies restantes des données étaient déjà identiques et incorrectes.

La leçon n’était pas « ZFS a échoué ». ZFS a fait exactement ce qu’il promettait : il a détecté la corruption. Le système a échoué parce que l’organisation traitait la vérification comme optionnelle. Les contrôles d’intégrité non exercés ne sont que des croyances avec de la syntaxe CLI.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Un fournisseur SaaS de taille moyenne utilisait ZFS sur un niveau de stockage partagé. Les scrubs étaient planifiés mensuellement, mais les ingénieurs se sont plaints qu’ils causaient des pics de latence sur les bases de données des locataires. L’équipe a donc fait une « optimisation » : augmenter la fréquence des scrubs à hebdomadaire mais les faire tourner pendant les heures ouvrées à un débit réduit en abaissant la priorité I/O au niveau OS et en laissant le scrub « prendre le temps qu’il faut ».

Sur le papier, cela semblait responsable : un scrub doux et constant plutôt qu’un gros événement mensuel. En pratique, c’est devenu un bruit de fond permanent. Le scrub ne finissait jamais avant la prochaine exécution programmée. Les opérateurs se sont habitués à voir « scrub in progress » comme état normal, si bien que personne n’a remarqué quand les débits de scrub ont chuté de 80% après qu’un HBA ait commencé à journaliser des réinitialisations de lien.

Des semaines plus tard, un disque a lâché. Le resilver a commencé sur un matériel déjà stressé. Le pool effectuait maintenant de lourdes lectures de reconstruction en plus d’un scrub toujours en cours parce que personne ne l’avait arrêté. La latence a grimpé, les timeouts ont suivi, et l’incident est devenu visible pour les clients. La cause racine n’était pas « scrubs hebdomadaires » en soi. C’était la combinaison de scrubs non terminants, de la normalisation d’un état anormal et de contrôles insuffisants durant les états dégradés.

Par la suite, ils ont changé la règle : un scrub doit se terminer dans une fenêtre définie, et aucun scrub ne tourne quand le pool est dégradé ou en resilver sauf approbation explicite. Ils ont aussi ajouté des alertes pour « scrub en cours depuis plus de X » et « débit de scrub émis en dessous de Y pendant Z minutes ». L’optimisation réussie n’était pas le tuning ; c’était de poser des limites sur le travail.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la situation

Une entreprise liée à la finance avait la réputation d’une opé conservative. Pas excitant. Pas à la mode. Mais ils exécutaient des scrubs mensuels sur chaque pool ZFS, et disposaient d’un petit runbook exigeant des opérateurs de noter : dernier scrub, octets réparés et compteurs d’erreurs des périphériques. Ils faisaient aussi des drills de restauration trimestriels sur un échantillon aléatoire de datasets. Les gens se plaignaient que c’était de la paperasse. C’était le but.

Un mois, un scrub a réparé une petite quantité de données sur un pool RAIDZ2 — rien de massif, mais non nul. Les compteurs montraient quelques erreurs de checksum isolées sur un seul périphérique. SMART semblait « correct ». Parce qu’ils suivaient les tendances, ils ont vu que le compteur de checksum avait augmenté depuis le mois précédent. Ils ont remplacé le câble d’abord. Les erreurs ont continué. Ils ont remplacé le disque lors de la maintenance suivante.

Deux semaines plus tard, un autre disque dans le même vdev a commencé à renvoyer des erreurs de lecture. Si le premier disque n’avait pas été remplacé proactivement, ils auraient été en RAIDZ2 avec deux périphériques marginaux pendant une fenêtre de rebuild — précisément quand les erreurs latentes apparaissent. Au lieu de cela, le pool est resté sain, les scrubs propres et l’incident ne s’est jamais produit.

Rien d’héroïque. Pas de war room nocturne. Pas d’escalade directionnelle. Juste une boucle de rétroaction banale : scrub, enregistrer, réagir. L’ennuyeux est une fonctionnalité en ingénierie du stockage.

Erreurs courantes : symptôme → cause racine → correction

1) « Le pool est ONLINE, donc tout va bien »

Symptôme : Tout semble vert, mais plus tard vous voyez des erreurs permanentes sur de vieux fichiers.

Cause racine : ONLINE signifie seulement que le pool est accessible. Cela ne veut pas dire que toutes les données sont lisibles et correctes.

Correction : Scrubez régulièrement et alertez sur toute ligne errors: dans zpool status, pas seulement sur l’état du pool. Intégrez les résultats de scrub au monitoring.

2) Les scrubs ne se terminent jamais

Symptôme : zpool status affiche toujours « scrub in progress », l’ETA est sans sens, les opérateurs l’ignorent.

Cause racine : Pas assez de marge I/O ; scrub programmé trop fréquemment ; rétention élevée de snapshots ; fragmentation ; contention avec la charge.

Correction : Imposer un SLO d’achèvement : le scrub doit finir en X heures/jours. Réduisez le churn des snapshots, augmentez le parallélisme vdev, planifiez hors-pointe ou séparez les pools par charge.

3) Incrémentation des erreurs CKSUM sur un périphérique mais SMART dit PASSED

Symptôme : zpool status montre des incréments CKSUM ; SMART overall health affiche PASSED.

Cause racine : Souvent le transport : mauvais câble, HBA instable, problème de backplane, expander. La santé SMART n’est pas une vérité absolue sur l’intégrité des données.

Correction : Vérifiez UDMA_CRC_Error_Count (SATA), les logs noyau pour les réinitialisations de lien, réenfoutez/remplacez le câble, changez de port, mettez à jour le firmware HBA. Remplacez le disque si les erreurs persistent.

4) « On a scrubé et ça a réparé ; on a fini »

Symptôme : Le scrub a réparé des octets ; l’équipe hausse les épaules et passe à autre chose.

Cause racine : Un événement de réparation est une alarme, pas une célébration. Quelque chose a renvoyé de mauvaises données.

Correction : Investiguer quel périphérique/vdev a vu des erreurs ; corréler avec SMART et les logs ; lancer un scrub supplémentaire après les changements pour confirmer la stabilité.

5) Scruber un pool dégradé sans réfléchir

Symptôme : La performance s’effondre ; d’autres périphériques échouent pendant le scrub/resilver.

Cause racine : Lectures supplémentaires sur des disques déjà stressés ; le scrub concurrence le resilver ; les fenêtres de rebuild amplifient les erreurs latentes.

Correction : Par défaut : évitez les scrubs pendant un resilver sauf si vous recherchez une corruption suspecte. Priorisez la restauration de la redondance. Si vous scrubez en état dégradé, faites-le intentionnellement avec monitoring et plan de retour arrière.

6) Confondre corruption applicative et corruption stockage

Symptôme : Incohérences logiques dans la base ; ZFS rapporte des scrubs propres.

Cause racine : L’application a écrit de mauvaises données, ou un bug/erreur logique est survenu au niveau de l’application. ZFS l’a stocké fidèlement.

Correction : Utilisez des contrôles applicatifs, des sauvegardes et des snapshots immuables avec rétention. ZFS est nécessaire, pas suffisant, pour la correction logique.

7) Calendrier de scrub copié d’un blog, pas de la réalité du pool

Symptôme : Les scrubs provoquent des impacts clients répétés ou sont désactivés.

Cause racine : Le calendrier ne correspond pas au nombre de périphériques, à la taille du pool ni à la charge métier.

Correction : Commencez par mensuel, mesurez la durée et l’impact. Ajustez la fenêtre et la marge de débit. Traitez le scrub comme un contrôle requis, pas comme un job optionnel.

Checklists / plan étape par étape

Plan de base pour un nouveau pool ZFS (orienté production)

  1. Choisir la redondance intentionnellement : mirrors pour l’IOPS et une guérison simple ; RAIDZ2/3 pour la capacité et la tolérance aux pannes.
  2. Nommer les périphériques par ID stable : construire les pools en utilisant les chemins /dev/disk/by-id.
  3. Définir la cadence de scrub : mensuelle par défaut ; confirmer qu’elle peut se terminer dans votre fenêtre.
  4. Décider de la rétention des snapshots : conservez ce que vous pouvez vous permettre de scruber. La prolifération des snapshots est réelle.
  5. Monitoring : alerter sur (a) scrub non exécuté depuis N jours, (b) scrub a réparé des octets > 0, (c) toute nouvelle erreur READ/WRITE/CKSUM, (d) pool DEGRADED/FAULTED, (e) scrub prenant trop de temps.
  6. Lancer un scrub de test après le passage en production : mesurer le débit et l’impact ; enregistrer la durée de base.

Routine mensuelle d’exploitation (ennuyeuse, répétable, correcte)

  1. Exécuter zpool status et enregistrer les compteurs.
  2. Lancer/confirmer la complétion du scrub.
  3. Examiner le résultat du scrub : octets réparés, compteurs d’erreurs, durée.
  4. Récupérer les résumés SMART pour tous les périphériques ; surveiller CRC/link errors et secteurs réalloués/en attente.
  5. Vérifier au moins une voie de restauration : un petit drill de restauration de dataset ou la vérification des checksums par rapport à des artefacts connus.

Routine d’incident quand vous voyez des erreurs de checksum

  1. Ne pas paniquer en écrivant : évitez les écritures lourdes qui vont churner les métadonnées et compliquer la récupération.
  2. Capturer l’état : sauvegardez zpool status -v, extraits de dmesg, et rapports SMART.
  3. Identifier l’étendue : erreurs permanentes au niveau fichier vs compteurs périphériques seulement.
  4. Stabiliser le chemin matériel : câbles/ports/HBA.
  5. Restaurez la redondance : remplacez les périphériques défaillants/indisponibles.
  6. Scrub à nouveau : confirmer que les erreurs cessent d’augmenter et que le scrub se termine proprement.
  7. Restaurer les objets affectés : depuis sauvegarde/snapshot ; vérifier l’intégrité.

Faits intéressants et contexte historique

  • Fait 1 : ZFS a été conçu chez Sun Microsystems avec pour objectif explicite l’intégrité des données de bout en bout, pas seulement la gestion de capacité.
  • Fait 2 : Les RAID traditionnels vérifient la parité mais ne valident généralement pas que les données retournées correspondent à ce que le système de fichiers a écrit à l’origine.
  • Fait 3 : ZFS stocke les checksums dans les métadonnées parentales, donc la checksum d’un bloc n’est pas située dans le même secteur que le bloc lui-même.
  • Fait 4 : Le copy-on-write fait que ZFS n’écrase jamais les données actives en place ; il écrit de nouveaux blocs puis bascule les pointeurs, réduisant le risque de « torn write ».
  • Fait 5 : Le scrub vérifie les blocs alloués, y compris ceux retenus par les snapshots ; la rétention de snapshots affecte directement la charge du scrub.
  • Fait 6 : La « self-healing » nécessite de la redondance ; un pool mono-disque peut détecter la corruption mais ne peut pas la réparer.
  • Fait 7 : Les erreurs de checksum peuvent provenir de la couche de transport (câbles/HBA), pas seulement du média disque — SMART « PASSED » ne réfute pas cela.
  • Fait 8 : Resilver et scrub sont des scans différents : le resilver est une reconstruction ciblée après événements de périphérique ; le scrub est une vérification complète du contenu du pool.
  • Fait 9 : Les disques de grande capacité augmentent la fenêtre temporelle où les erreurs latentes de secteur importent, car le rebuild/scrub lit plus de données et prend plus de temps.

FAQ

1) À quelle fréquence dois-je scruber un pool ZFS ?

Le mensuel est la valeur par défaut qui fonctionne dans la plupart des environnements. Si votre scrub ne peut pas finir mensuellement, améliorez la marge/éliminez le churn de snapshots ou changez d’architecture — n’abandonnez pas la vérification.

2) Un scrub ZFS vérifie-t-il l’espace libre ?

Non. Il vérifie les blocs alloués atteignables depuis l’arbre de métadonnées, y compris les blocs référencés par des snapshots. L’espace libre n’est pas scanné car il n’y a rien à vérifier.

3) Quelle est la différence entre scrub et resilver ?

Le scrub est un scan d’intégrité complet des données/métadonnées allouées. Le resilver reconstruit des données sur un périphérique remplacé/retourné pour les vdevs affectés, typiquement seulement les blocs en usage.

4) Si j’ai des mirrors, ai-je encore besoin de scrubs ?

Oui. Les mirrors vous donnent une seconde copie, mais sans scrubs vous pouvez ne pas découvrir la corruption avant de lire le bloc lors d’un incident — ou pendant un resilver quand vous êtes déjà stressé.

5) ZFS peut-il corriger automatiquement la corruption ?

Si la redondance existe et qu’au moins une copie est bonne, ZFS peut réparer une copie mauvaise pendant un scrub (et parfois lors de lectures normales). Si toutes les copies sont incorrectes, il ne peut que détecter.

6) Pourquoi je vois des erreurs CKSUM mais pas d’erreurs READ/WRITE ?

Parce que le périphérique a renvoyé des données avec succès, mais les données ne correspondaient pas à la checksum stockée. Cela pointe vers une corruption silencieuse ou des problèmes de transport (câble/HBA/backplane).

7) Les scrubs sont-ils dangereux pour la santé des disques ?

Ils augmentent la charge de lecture, ce qui peut exposer des disques marginaux. Ce n’est pas une raison pour éviter les scrubs ; c’est une raison de trouver les périphériques faibles sur votre calendrier, pas lors d’une panne.

8) Dois-je scruber différemment les pools SSD et HDD ?

L’objectif d’intégrité est le même. Les SSD scrubbent souvent plus vite grâce à de bonnes lectures aléatoires, mais ils peuvent toujours avoir des bugs de firmware et des problèmes de chemin. Maintenez des scrubs réguliers et surveillez l’usure/SMART.

9) Mon scrub a réparé des octets. Est-ce normal ?

Ça peut arriver, mais ça ne devrait pas être courant. Traitez « repaired » comme un événement d’intégrité : identifiez le chemin du périphérique, vérifiez les logs/SMART, et confirmez que le prochain scrub est propre.

10) Ai-je besoin de RAM ECC pour l’intégrité ZFS ?

L’ECC est fortement recommandé pour les systèmes où la correction des données compte. ZFS peut détecter la corruption sur disque, mais il ne peut pas toujours détecter la corruption introduite en RAM avant que les checksums soient calculées.

Conclusion : prochaines étapes réalisables cette semaine

Si vous utilisez ZFS et que vous ne scrubez pas, vous faites confiance à votre pile de stockage pour être parfaite pour toujours. C’est charmant. Et s’il vous plaît, ne le faites pas.

  1. Définissez un calendrier de scrub (mensuel par défaut) et assurez-vous qu’il se termine.
  2. Ajoutez de l’alerte pour : scrub en retard, scrub a réparé des octets > 0, nouvelles erreurs READ/WRITE/CKSUM, et runtime de scrub dépassant votre fenêtre.
  3. Lancez un scrub maintenant pendant une fenêtre contrôlée, puis enregistrez la durée et le débit comme base.
  4. Quand vous voyez des erreurs de checksum, corrélez avec SMART CRC/réinitialisations de lien avant de remplacer aveuglément le matériel.
  5. Testez les restaurations pour au moins un dataset représentatif. Les scrubs vérifient ce qui existe ; les drills de restauration vérifient que vous pouvez récupérer quand ce n’est pas le cas.

L’objectif n’est pas de « faire confiance à ZFS ». L’objectif est d’opérationnaliser la vérification. Les scrubs sont la partie où vous cessez de croire et commencez à savoir.

← Précédent
« Chemin réseau introuvable » (0x80070035) : la réparation en 5 minutes
Suivant →
Proxmox PBS : Sauvegardes réussissent mais restaurations échouent — la checklist qui les attrape

Laisser un commentaire