Les tests de coupure d’alimentation sont l’une de ces tâches que tout le monde promet de faire « le trimestre prochain », juste après avoir fini « encore une migration ».
Puis un disjoncteur saute, un PDU redémarre, ou un technicien externe débranche le mauvais câble, et soudain vous apprenez la vérité sur votre stockage en direct.
ZFS est réputé résilient, mais il ne peut pas vous protéger de tous les mensonges que votre matériel raconte — surtout autour des caches d’écriture et des accusés de réception « je l’ai bien flushé ».
Ce guide explique comment valider la sécurité sérieusement, sans transformer des données de production en expérience de foire scientifique.
Ce que vous testez réellement (et ce que vous ne testez pas)
« Test de coupure d’alimentation » est utilisé comme s’il s’agissait d’une seule chose. Ce n’est pas le cas. Vous validez une chaîne de promesses :
l’OS, le HBA, le firmware du disque, la politique de cache et la topologie du pool doivent s’entendre sur la notion de « durable ».
ZFS se trouve au milieu pour vous garder honnête. Parfois il réussit. Parfois le matériel le manipule.
Voici ce que vous testez :
- Consistance après crash : après une perte brutale, le pool s’importe proprement et les métadonnées sont cohérentes.
- Durabilité des écritures synchrones : les données reconnues comme sync sont réellement sur un média stable.
- Comportement du ZIL/SLOG sous stress : combien vous perdez en vol, et si la relecture est propre.
- Flux de récupération : combien de temps il faut aux humains pour restaurer le service sans empirer la situation.
- Véracité de votre pile de stockage : si les flushes, barrières et FUA sont respectés de bout en bout.
Ce que vous ne prouvez pas :
- Que la corruption ne peut jamais arriver. Vous réduisez la probabilité et améliorez la détection.
- Que les écritures asynchrones sont durables. Si votre application écrit asynchrone, vous testez le « meilleur effort », pas des garanties.
- Que RAIDZ remplace une sauvegarde. Ce n’est pas le cas, et ZFS ne discutera pas avec vous à ce sujet.
Une citation à garder sous les yeux. La phrase souvent attribuée à Peter Drucker (idée paraphrasée) :
Ce qui est mesuré est géré.
En stockage, ce qui est mesuré est aussi cru. Donc mesurez correctement.
Faits et contexte qui influencent les décisions
Ce ne sont pas des détails. Ce sont les raisons pour lesquelles certaines configurations « évidentes » sont en réalité dangereuses.
- ZFS est copy-on-write (CoW) : il n’écrase jamais des blocs vivants sur place, d’où une consistance globale du pool généralement excellente après un crash.
- ZFS checksumpe tout (métadonnées et données) : il détecte la corruption même quand le disque renvoie fièrement des ordures.
- Le ZIL existe même sans SLOG : l’intention des transactions synchrones est enregistrée quelque part ; un périphérique de log dédié change juste l’endroit.
- Le SLOG n’est pas un cache d’écriture : il accélère les écritures synchrones ; il ne rend pas les écritures asynchrones sûres et ne remplace pas la RAM.
- Les caches d’écriture mentent parfois : certains disques/SSDs ont des caches volatiles qui peuvent accuser réception avant la persistance, sauf si la protection contre la perte de puissance (PLP) est réelle et activée.
- Barrières et flushes sont un contrat : Linux + contrôleur + périphérique doivent honorer les sémantiques de flush/FUA. Un maillon faible rend le « sync » un spectacle coûteux.
- Les scrubs ZFS ne sont pas un fsck : un scrub vérifie l’intégrité via les checksums et répare via la redondance. Ce n’est pas un outil générique « réparez mon pool ».
- Les bugs liés à la perte d’alimentation sont souvent des bugs de timing : le même test peut réussir 99 fois et échouer la 100e parce que le bug se cache dans une petite fenêtre de course.
- Les premières versions populaires de ZFS ont vulgarisé les checksums de bout en bout : pas le premier système de fichiers à le faire, mais celui que beaucoup d’équipes SRE ont découvert à la dure et qu’elles ont ensuite refusé d’abandonner.
Blague n°1 : Les ingénieurs stockage ne croient pas aux fantômes. Ils croient en « latence inexpliquée » et « c’est revenu après un reboot », ce qui revient au même avec de meilleurs graphiques.
Modèle de menace : modes de défaillance importants
Traitez la perte d’alimentation comme un outil d’injection de pannes spectaculaire. Vous visez des classes de défaillances spécifiques.
Si vous ne les nommez pas, vous ferez un « test », vous vous sentirez productif et vous n’apprendrez rien.
1) Crash sans mensonges du stockage (le « bon » crash)
Le kernel s’arrête. L’alimentation est coupée. Les périphériques s’arrêtent instantanément. Au redémarrage, ZFS rejoue les logs d’intention, revient au dernier TXG cohérent,
et vous perdez au maximum les dernières secondes de travail asynchrone. Le travail synchrone survit.
2) Crash avec cache volatile mensonger (le « mauvais » crash)
Votre périphérique ou contrôleur a accusé réception d’écritures qui étaient dans un cache volatile. La perte d’alimentation les efface.
ZFS pouvait les croire durables, donc vous vous retrouvez avec des blocs manquants qui peuvent se manifester par des erreurs de checksum, des erreurs permanentes au scrub,
ou — pire — de la corruption silencieuse si le mensonge s’aligne avec un chemin de checksum valide (rare, mais ne bâtissez pas votre politique sur le « rare »).
3) Crash pendant un resilver/scrub (le « crash sous stress »)
Cela teste les opérations métadonnées de longue durée et leur capacité de reprise. ZFS est généralement solide ici, mais votre goulot d’étranglement peut changer :
un scrub peut amplifier l’IO et révéler des problèmes de file d’attente, des bugs de firmware de contrôleur, ou des disques faibles.
4) Perte partielle d’alimentation / brownout (le « crash bizarre »)
Un shelf disparaît, un autre survit. Une alimentation reste. Les expanders SAS rebootent. NVMe se réinitialise.
Ce sont les pannes où les logs ressemblent à une scène de crime et où vous découvrez si multipath et timeouts sont raisonnables.
5) Erreurs humaines de récupération (le « crash le plus courant »)
Un pool propre peut être transformé en bazar par un import impatient avec des mauvais flags, ou par « corriger » ce qui n’est pas cassé.
Les tests de coupure d’alimentation devraient inclure un runbook de récupération, pas seulement une coupure.
Construire un laboratoire qui dit la vérité
Si vous testez sur le SSD d’un portable avec un seul pool et une charge polie, vous testez le confort émotionnel de l’équipe, pas le système.
Le laboratoire n’a pas besoin d’être cher, mais il doit être honnête.
Règles pour un environnement de test fiable
- Même classe de stockage que la production : mêmes modèles SSD/HDD, même HBA, même famille de firmware. « Assez proche » est là où les données meurent.
- Même philosophie ashift et recordsize : n’« optimisez » pas le labo avec des tailles de blocs différentes en attendant le même comportement en cas de panne.
- Coupure reproductible : une prise PDU commutée, un relais ou un arrêt IPMI. Tirer un câble au hasard n’est pas de la science reproductible.
- Journalisation console hors bande : console série, IPMI SOL ou au moins journaux persistants. Vous voulez les 2 dernières secondes.
- Tests limités dans le temps : définissez ce que « passer » signifie avant de commencer. Sinon vous testerez jusqu’à vous lasser.
Ce que vous devez refléter depuis la production
Reproduisez la topologie du pool, le nombre de vdevs et si vous utilisez un SLOG dédié. Reproduisez votre politique sync.
Reproduisez la compression et le réglage atime. Et oui, reproduisez vos pires workloads.
Ce que vous ne devez pas reproduire
Ne reproduisez pas le manque de monitoring en production. Le labo est l’endroit où vous ajoutez de l’instrumentation supplémentaire.
Vous voulez voir le cadence des TXG, l’activité ZIL, le comportement des flushs des périphériques, et les distributions de latence.
Workloads et métriques : arrêtez le « dd » et commencez à mesurer
« J’ai écrit un gros fichier et tout avait l’air bien » n’est pas un test. C’est une berceuse.
Votre workload doit inclure des écritures sync, du churn de métadonnées, de petits IO aléatoires, et un débit soutenu. Aussi la concurrence.
Comportements clés à déclencher
- Pression de commit synchrone : bases de données, NFS en sync, applications intensives en fsync.
- Mises à jour de métadonnées : tempêtes de create/unlink, snapshots, clones, modifications de propriétés de dataset.
- Activité map d’espace : frees, réécritures et schémas de fragmentation.
- Mix lecture/écriture sous charge : car les pannes n’attendent pas que votre job batch ait fini.
Métriques qui comptent pendant le test
- Distribution de latence des écritures sync : p50/p95/p99, pas seulement la moyenne.
- Temps de commit TXG : des commits longs peuvent étendre la fenêtre de perte de données async et indiquer une douleur de flush de périphérique.
- Utilisation ZIL/SLOG : à quelle fréquence et à quel point vous le sollicitez.
- Erreurs de checksum et d’IO : après le reboot et après le scrub.
- Temps d’import et temps de replay : l’impact opérationnel compte.
Blague n°2 : Si votre plan de test de coupure d’alimentation est « tirer la prise et espérer », félicitations — vous avez réinventé le chaos engineering, mais avec moins de dashboards.
Tâches pratiques : commandes, sorties et décisions (12+)
Ce sont des vérifications et procédures de niveau production que vous pouvez exécuter en labo et — soigneusement — en production pour la validation.
Chaque tâche inclut : commande, ce que signifie la sortie, et quelle décision prendre.
Les exemples supposent OpenZFS sur Linux. Ajustez les noms de périphérique et de pool.
Task 1: Identify pool health and topology
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 00:12:41 with 0 errors on Tue Dec 24 02:10:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N0 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N1 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N2 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N3 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N4 ONLINE 0 0 0
ata-WDC_WD80EFZX-68UW8N5 ONLINE 0 0 0
errors: No known data errors
Signification de la sortie : Vous voulez ONLINE, zéro erreurs, et un scrub récent sans réparations.
Décision : Si vous avez déjà des erreurs de checksum, arrêtez. Corrigez la santé de base avant d’injecter des pannes.
Task 2: Check dataset sync policy (the “did we quietly opt out of safety?” check)
cr0x@server:~$ sudo zfs get -o name,property,value -s local,default sync tank
NAME PROPERTY VALUE
tank sync standard
Signification de la sortie : standard honore les requêtes sync des applications ; disabled ment aux applications ; always force sync pour toutes les écritures.
Décision : Pour valider la sécurité, testez temporairement avec sync=always sur les dataset(s) importants pour vérifier la durabilité réelle.
Task 3: Verify whether you even have a SLOG and what it is
cr0x@server:~$ sudo zpool status tank | sed -n '1,80p'
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
logs
nvme0n1p1 ONLINE 0 0 0
Signification de la sortie : Une section logs indique un périphérique SLOG séparé.
Décision : Si vous comptez sur la performance sync ou NFS sync, validez la protection contre la perte de puissance du SLOG et sa latence.
Task 4: Confirm key dataset properties that affect behavior during failures
cr0x@server:~$ sudo zfs get -o name,property,value recordsize,compression,atime,logbias,primarycache tank/data
NAME PROPERTY VALUE
tank/data recordsize 128K
tank/data compression lz4
tank/data atime off
tank/data logbias latency
tank/data primarycache all
Signification de la sortie : logbias=latency tend à utiliser le SLOG plus agressivement pour les écritures sync ; throughput pousse davantage vers le pool principal.
Décision : Pour les bases de données, logbias=latency avec un SLOG PLP approprié est raisonnable ; sinon vous payez une taxe de latence inutilement.
Task 5: Confirm write cache policy and “volatile cache” risk on SSD/NVMe
cr0x@server:~$ sudo nvme id-ctrl /dev/nvme0n1 | egrep -i 'vwc|oncs|wzsl'
vwc : 0x1
oncs : 0x5f
wzsl : 0x0
Signification de la sortie : vwc: 0x1 indique la présence d’un cache d’écriture volatile. Ce n’est pas automatiquement mauvais — mais cela pose la question : le disque a-t-il du PLP ?
Décision : Si le périphérique a un cache volatile et pas de PLP, ne l’utilisez pas comme SLOG. Considérez les affirmations de durabilité sync comme suspects jusqu’à preuve du contraire.
Task 6: Check SATA drive write cache setting (where lies sometimes begin)
cr0x@server:~$ sudo hdparm -W /dev/sda | head -n 2
/dev/sda:
write-caching = 1 (on)
Signification de la sortie : Le write caching est activé. Beaucoup de disques sont sûrs ; certains ne le sont pas ; les contrôleurs peuvent aussi interférer.
Décision : Si vous ne pouvez pas vérifier la protection contre la perte d’alimentation, envisagez de désactiver le write cache pour les tests de sécurité (en acceptant la perte de performance), ou utilisez des disques d’entreprise avec PLP.
Task 7: Verify that ZFS sees ashift and that it’s sane
cr0x@server:~$ sudo zdb -C tank | egrep 'ashift|vdev_tree' | head -n 20
vdev_tree:
type: 'root'
id: 0
guid: 1234567890123456789
ashift: 12
Signification de la sortie : ashift: 12 signifie des secteurs 4K. Un ashift incorrect peut causer une amplification d’écriture pathologique et des commits TXG longs.
Décision : Si ashift est incorrect, corrigez-le en reconstruisant le pool. Ne rationalisez pas ; le pool ne se souciera pas de vos sentiments.
Task 8: Baseline IO latency and queueing before you start breaking things
cr0x@server:~$ iostat -x 1 3
Linux 6.8.0 (server) 12/26/2025 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
2.31 0.00 1.12 0.45 0.00 96.12
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz aqu-sz %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 12.00 512.00 0.00 0.00 7.20 42.67 0.09 8.40
nvme0n1 0.00 0.00 0.00 0.00 0.00 0.00 80.00 10240.00 0.00 0.00 0.45 128.00 0.04 2.10
Signification de la sortie : Surveillez w_await, aqu-sz et %util. Un SLOG avec un await élevé pendant les tests sync est un signal d’alarme.
Décision : Si la base est déjà saturée, votre test de perte d’alimentation mesurera surtout « à quel point nous étions surchargés », pas la correction.
Task 9: Generate a sync-heavy workload that actually calls fsync
cr0x@server:~$ sudo fio --name=syncwrite --directory=/tank/data/test \
--rw=randwrite --bs=4k --size=2G --iodepth=1 --numjobs=4 \
--fsync=1 --direct=1 --time_based --runtime=60 --group_reporting
syncwrite: (groupid=0, jobs=4): err= 0: pid=22310: Fri Dec 26 10:12:41 2025
write: IOPS=410, BW=1640KiB/s (1679kB/s)(96.1MiB/60001msec)
clat (usec): min=650, max=42000, avg=2400.12, stdev=1100.55
lat (usec): min=670, max=42120, avg=2420.88, stdev=1102.10
Signification de la sortie : Avec --fsync=1 et iodepth=1, vous forcez des points de durabilité fréquents.
Décision : Utilisez ce workload pendant les tests de coupure pour valider si les écritures sync reconnues survivent.
Task 10: Track ZFS latency and queue stats during the test
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.20T 5.80T 20 450 2.5M 1.7M
raidz2-0 1.20T 5.80T 20 210 2.5M 1.2M
sda - - 3 35 420K 220K
sdb - - 3 35 420K 220K
sdc - - 3 35 420K 220K
sdd - - 3 35 420K 220K
logs - - - 240 - 520K
nvme0n1p1 - - - 240 - 520K
Signification de la sortie : Si les écritures s’accumulent dans logs sous pression sync, vous utilisez le SLOG comme prévu. Sinon, votre workload n’est peut-être pas sync, ou logbias/sync diffèrent.
Décision : Si le SLOG est saturé, attendez-vous à une latence sync élevée. Envisagez un SLOG en miroir ou un périphérique meilleur, pas un plus grand pool.
Task 11: Validate pre-crash: snapshot a marker dataset so you can prove what survived
cr0x@server:~$ sudo zfs snapshot -r tank/data@pre_cut_01
Signification de la sortie : Pas de sortie signifie que ça a marché. Vous avez maintenant un état de référence connu et valide.
Décision : Toujours snapshotter avant de couper l’alimentation. Ça transforme « je pense que ça a changé » en un diff réel.
Task 12: After crash: import the pool safely and observe replay
cr0x@server:~$ sudo zpool import
pool: tank
id: 1234567890123456789
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
raidz2-0 ONLINE
sda ONLINE
sdb ONLINE
sdc ONLINE
sdd ONLINE
logs
nvme0n1p1 ONLINE
cr0x@server:~$ sudo zpool import -o readonly=on -N tank
Signification de la sortie : Importer en lecture seule d’abord vous permet d’inspecter sans écrire immédiatement un nouvel état.
Décision : Si vous voyez des avertissements sur des périphériques manquants ou UNAVAIL, arrêtez et vérifiez câblage/réinitialisations de contrôleur avant d’importer en lecture/écriture.
Task 13: Check for last known transaction group and errors in event history
cr0x@server:~$ sudo zpool history -i tank | tail -n 25
2025-12-26.10:14:03 zpool import -o readonly=on -N tank
2025-12-26.10:14:21 zpool export tank
2025-12-26.10:15:10 zpool import tank
Signification de la sortie : Vous pouvez corréler imports/exports avec la timeline du test. Des exports/imports inattendus peuvent indiquer des watchdogs ou une automatisation intrusive.
Décision : Si un agent « aide » en important/exportant, désactivez-le pendant les tests. La déterminisme bat les surprises.
Task 14: Run a scrub and interpret the result
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 00:16:22 with 0 errors on Fri Dec 26 10:32:18 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
logs
nvme0n1p1 ONLINE 0 0 0
errors: No known data errors
Signification de la sortie : « 0 errors » après un crash est ce que vous voulez. Si vous voyez des bytes réparés, vérifiez si c’était préexistant ou induit.
Décision : Toute erreur de checksum après un test contrôlé est un signal sérieux : suspectez des mensonges de flush cache, un SLOG défaillant ou un problème de contrôleur.
Task 15: Compare state pre/post cut using snapshots (prove data loss boundaries)
cr0x@server:~$ sudo zfs snapshot -r tank/data@post_cut_01
cr0x@server:~$ sudo zfs diff -FH tank/data@pre_cut_01 tank/data@post_cut_01 | head
M /tank/data/test/file0001
M /tank/data/test/file0002
- /tank/data/test/tmp_8831
Signification de la sortie : Vous pouvez voir exactement ce qui a changé. Si votre application affirme avoir fait fsync et que les données manquent, vous avez une faille de durabilité.
Décision : Les données fsyncées manquantes ne sont pas une « perte attendue ». C’est un bug ou un mensonge. Escaladez vers la validation matérielle.
Task 16: Check kernel logs for storage resets and flush failures
cr0x@server:~$ sudo journalctl -b -k | egrep -i 'zfs|nvme|sd |scsi|reset|timeout|flush' | tail -n 40
Dec 26 10:15:18 server kernel: nvme nvme0: controller reset occurred
Dec 26 10:15:19 server kernel: sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
Dec 26 10:15:20 server kernel: ZFS: Loaded module v2.2.4-1
Dec 26 10:15:27 server kernel: ZFS: pool tank imported, checkpoint disabled
Signification de la sortie : Les échecs de synchronisation de cache ou les resets de contrôleur autour du crash sont là où la vérité fuit.
Décision : Si les flushs échouent, ne faites pas confiance à la durabilité sync. Corrigez le firmware, le mode HBA, ou remplacez les périphériques.
Comment couper l’alimentation en sécurité (et ce qu’il ne faut pas faire)
L’objectif est de simuler une panne tout en étant capable de récupérer et d’analyser. Ce n’est pas le moment de danser avec les câbles d’alimentation.
Choisissez une méthode reproductible qui n’introduit pas de variables additionnelles.
Méthodes préférées (les plus reproductibles)
- Prise PDU commutée : coupez l’alimentation de l’hôte tout en laissant le réseau et la journalisation intacts ailleurs.
- Arrêt chassis IPMI : cohérent, journalisé et adapté au remote. Ce n’est pas « pur », mais suffisant pour de nombreux scénarios.
- Coupure AC contrôlée par relais : le plus proche du « réel » tout en gardant la répétabilité.
Méthodes qui créent plus de confusion que d’informations
- Retirer des PSU au hasard dans des systèmes redondants : c’est un test de PSU, pas de perte d’alimentation. Utile, mais nommez-le correctement.
- Appuyer frénétiquement sur le bouton de reset : ça ajoute du bruit temporel humain ; vous passerez le post-mortem à débattre des secondes.
- Déclencher un kernel panic comme seul test : ça teste la récupération de crash, pas la perte d’alimentation. C’est un mode de défaillance différent.
Mise en scène de la coupure : à quoi ressemble une bonne hygiène
Démarrez le workload. Laissez-le atteindre l’état stable. Snapshot. Enregistrez les métriques de base. Puis coupez l’alimentation sur une frontière connue (par ex. 30 secondes dans un workload sync).
L’intention n’est pas aléatoire. L’aléatoire est pour les attaquants et les load balancers.
Mode opératoire de diagnostic rapide
Après un test de crash — ou une panne réelle — vous voulez des réponses rapidement. Voici le chemin minimal pour identifier le goulot et le risque.
Faites-le dans l’ordre. Sauter des étapes, c’est transformer un incident mineur en un incident coûteux.
Première étape : le pool s’importe-t-il proprement et qu’est-ce que ZFS pense s’être passé ?
- Exécutez
zpool importetzpool status -vaprès l’import. - Vérifiez périphériques manquants, pool suspendu, ou erreurs de checksum.
- Décision : Si le pool est DEGRADED ou les erreurs non nulles, traitez cela comme un incident d’intégrité des données, pas comme un problème de performance.
Deuxième étape : vérifiez les logs kernel pour resets, timeouts et échecs de flush
- Utilisez
journalctl -b -kavec filtres nvme/sd/scsi/reset/timeout/flush. - Décision : Les échecs de flush ou resets répétés pointent vers des problèmes matériel/firmware/contrôleur. Ne bricolez pas ZFS pour « contourner » des mensonges.
Troisième étape : déterminer si la latence sync est le problème (SLOG ou pool principal)
- Lancez un workload sync (fio avec fsync) et surveillez
zpool iostat -vetiostat -x. - Décision : Si le périphérique
logsest chaud et haute latence, le SLOG est le goulot. Si les vdevs principaux sont chauds, la topologie du pool ou les disques limitent.
Quatrième étape : validez l’intégrité avec un scrub (ne devinez pas)
- Démarrez
zpool scrub, puis surveillez aveczpool status. - Décision : Toute erreur de checksum post-crash signifie que votre chaîne de durabilité est cassée. Escaladez avant de relancer des tests.
Cinquième étape : prouvez les frontières de durabilité au niveau application
- Différenciez les snapshots ou comparez des marqueurs applicatifs (IDs de transaction, positions WAL, numéros de séquence).
- Décision : Si l’application a perdu des commits reconnus, la pile de stockage a accusé réception d’écritures qu’elle n’a pas réellement persistées.
Trois mini-récits d’entreprise depuis le terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Une entreprise de taille moyenne a déplacé un service critique sur ZFS. Bon choix. Ils l’ont aussi placé sur « NVMe rapide » pour le SLOG.
La logique était simple : NVMe est moderne, moderne est durable, et la fiche technique contient des mots comme « flush ».
Leurs exports NFS étaient configurés avec la sémantique sync. L’équipe applicative a célébré : la latence a chuté, les dashboards étaient plus verts,
et tout le monde a décidé silencieusement que le problème de stockage était réglé pour toujours. Puis un événement d’alimentation a eu lieu — bref et réel.
Les hôtes ont redémarré. Les pools se sont importés. Aucune erreur évidente.
Deux jours plus tard, l’étrangeté a commencé : une poignée de fichiers avaient des versions plus anciennes. Pas manquants. Pas visiblement corrompus. Juste… revenus en arrière dans le temps.
Cela a été repéré parce qu’un ingénieur a comparé des artefacts générés avec un manifeste de build qui faisait fsync à la fin.
L’équipe stockage a d’abord suspecté un bug applicatif. L’équipe applicative a suspecté le stockage. Tout le monde se suspectait, ce qui est normal.
La percée est venue d’une ligne de log ennuyeuse : échecs occasionnels de flush et resets de contrôleur pendant des rafales sync lourdes.
Le « NVMe rapide » était un périphérique grand public avec cache d’écriture volatile et sans vraie protection PLP.
Il pouvait accepter des écritures sync rapidement, puis les perdre quand l’alimentation disparaissait. ZFS a fait ce qu’on lui a dit. Le périphérique a fait ce qu’il voulait.
Ils ont remplacé le SLOG par un périphérique d’entreprise capable de PLP et ont rerun les tests de coupure d’alimentation. Les voyages dans le temps ont cessé.
La leçon n’était pas « NVMe mauvais ». C’était « ne présumez pas la durabilité parce que le marketing a écrit ‘data center’ sur la boîte ».
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une autre organisation avait un lourd workload d’écriture et détestait la latence sync. Quelqu’un a proposé un réglage « pragmatique » :
mettre sync=disabled sur le dataset parce que « notre appli est répliquée de toute façon ».
Ce n’était pas un méchant qui fait tourner sa moustache. C’était un ingénieur bien intentionné essayant d’atteindre un SLO de latence avec un budget limité.
L’amélioration des performances a été spectaculaire. Tellement spectaculaire que le changement s’est étendu d’un dataset à plusieurs autres.
Ça a tenu plusieurs trimestres, ce qui signifie que ça a survécu à plusieurs revues, parce que personne n’aime être la personne qui réintroduit la latence.
Ils avaient un UPS. Ils avaient des PSU redondants. Ils avaient la foi.
Puis est venu une mise à jour firmware de stockage et une séquence de reboots d’hôtes. Un hôte a crashé en plein pic d’écriture.
La réplication ne les a pas sauvés parce que le flux de réplication provenait aussi de la même réalité « sync-disabled ».
Ils ont perdu une tranche de transactions reconnues. Pas toutes. Juste assez pour causer des divergences irréconciliables.
Le postmortem a été sombre mais utile. Ils avaient optimisé la mauvaise couche : ils ont retiré le contrat d’honnêteté du système de fichiers au lieu
d’investir dans un SLOG correct et s’assurer que le modèle de durabilité de l’application correspondait à la réalité.
La correction n’était pas seulement de réactiver sync. C’était d’auditer chaque dataset, d’aligner les sémantiques applicatives, et de retester avec injection de pannes.
La chute sèche : ils ont respecté le SLO de latence jusqu’au moment où ils ont heurté le SLO « expliquer à la finance pourquoi des factures ont disparu », qui est plus difficile à grapher.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une troisième société utilisait ZFS pour du stockage de VM. Rien d’extraordinaire. Miroirs pour les vdevs, un SLOG miroir avec PLP, et un calendrier de scrub mensuel.
Ils avaient aussi un rituel : chaque trimestre, exécuter un test de coupure d’alimentation contrôlé en staging après les cycles de patch.
Ce n’était pas un travail excitant. Personne n’a été promu pour ça. C’est ainsi que vous savez que c’était la bonne pratique.
Un trimestre, après une mise à jour du kernel, leur test de coupure en staging a déclenché un délai d’import du pool et une poignée d’erreurs de checksum au scrub.
Pas catastrophique, mais inacceptable. Parce que c’était en staging, ils ont eu le temps. Ils ont rollbacké, bisecté le changement, et découvert
une interaction driver/firmware qui causait des bizarreries NCQ/flush sur un sous-ensemble de SSD SATA sous forte pression sync.
Ils ont mis à jour le firmware des disques et modifié un réglage du contrôleur. Le test est repassé. Puis ils ont patché la production.
Un mois plus tard, une vraie coupure d’alimentation a frappé un rack à cause d’un événement électrique en amont. La production a récupéré proprement.
Personne hors de l’infra n’a remarqué. Ce qui est le but. Le test trimestriel ennuyeux a transformé une panne surprise en un reboot de routine.
La réputation de l’équipe s’est construite sur des non-événements, et c’est le seul genre de renommée honnête.
Erreurs courantes : symptôme → cause racine → correctif
1) Symptom: sync workloads are fast, then post-crash data is missing
Cause racine : cache d’écriture volatile a accusé réception sans persistance (pas de PLP), ou flush/FUA non respectés via le chemin contrôleur.
Correctif : utilisez un SLOG PLP ; vérifiez que le contrôleur est en mode IT/HBA ; mettez à jour le firmware ; confirmez que les commandes de flush réussissent dans les logs ; retestez avec sync=always.
2) Symptom: pool imports but scrub finds checksum errors after every power-cut test
Cause racine : le cache d’écriture du périphérique ment, matériel instable (resets de contrôleur, câble/backplane défectueux), ou la coupure provoque des écritures partielles au-delà de la redondance.
Correctif : inspectez journalctl pour resets/timeouts ; remplacez les composants douteux ; désactivez le write cache pour comparaison ; validez l’alimentation et la redondance des PSU.
3) Symptom: import hangs for a long time after crash
Cause racine : délais d’énumération des périphériques, timeouts multipath, ou un périphérique de log lent/inaccessible (problèmes SLOG pouvant bloquer la relecture).
Correctif : vérifiez les logs de démarrage du kernel pour timeouts de périphériques ; confirmez que le SLOG est présent et sain ; envisagez de retirer le périphérique de log défaillant (en labo) seulement après analyse.
4) Symptom: terrible sync latency, but SLOG looks idle
Cause racine : le workload n’est pas réellement sync (pas de fsync/O_DSYNC), ou les propriétés dataset sync et logbias ne sont pas celles attendues, ou les options d’export/montage NFS diffèrent.
Correctif : générez un workload sync connu (fio avec fsync) ; vérifiez les propriétés du dataset ; validez les paramètres de montage/export NFS ; observez zpool iostat -v.
5) Symptom: after crash, applications complain but ZFS reports “No known data errors”
Cause racine : les attentes de durabilité au niveau application dépassent ce qui a été demandé (écritures async, fsync manquant), ou bug applicatif d’ordre.
Correctif : instrumentez l’application : confirmez les points de fsync, le comportement WAL, ou les marqueurs de commit ; utilisez des diffs de snapshot autour de marqueurs connus ; ne blâmez pas ZFS tant que vous n’avez pas prouvé que l’application a demandé la durabilité.
6) Symptom: scrub takes forever or causes performance collapse after a crash
Cause racine : le pool est déjà proche de la saturation, ou un périphérique lent ralentit le vdev ; l’événement d’alimentation a exposé un disque faible.
Correctif : identifiez les périphériques lents via iostat -x et zpool iostat -v ; remplacez les éléments défaillants ; envisagez d’ajouter des vdevs (pas « des disques plus gros ») si vous avez besoin d’IOPS.
7) Symptom: “zpool status” shows write errors but no checksum errors
Cause racine : problèmes au niveau transport (câbles, HBA, expander) ou timeouts de périphérique plutôt que corruption.
Correctif : vérifiez les logs SMART/NVMe, les messages kernel et le câblage ; ne chassez pas les checksums quand le bus est en feu.
Check-lists / plan pas à pas
Step-by-step: safe power loss test cycle (repeatable)
- Choisir le(s) dataset(s) cible(s) : testez ce qui compte, pas le pool entier par défaut.
- Vérifier la santé du pool :
zpool status -vdoit être propre ; scrub récent préféré. - Enregistrer la configuration : capturez
zpool get alletzfs get allpour les datasets concernés ; sauvegardez les sorties avec timestamps. - Activer la collecte de preuves : assurez-vous d’avoir journal persistant, syslog distant ou capture console hors-bande.
- Créer un marqueur : un petit fichier ou ID de transaction applicatif écrit avec fsync ; snapshot
@pre_cut. - Démarrer le workload : utilisez fio avec fsync pour le comportement sync ; lancez éventuellement un second workload mixte en parallèle.
- Observer l’état stable : collectez 60–120 secondes de
zpool iostat -vetiostat -x. - Couper l’alimentation : via PDU/IPMI/relais ; consignez l’heure exacte et la méthode.
- Restaurer l’alimentation : boot ; n’importez pas en read-write automatiquement si vous pouvez l’éviter.
- Importer en lecture seule d’abord : inspectez la sortie de
zpool import; puis importez normalement si sain. - Valider les marqueurs : vérifiez fichiers marqueurs, diffs de snapshot et cohérence applicative.
- Scrub : lancez
zpool scrub, vérifiez zéro erreurs. - Documenter : enregistrez pass/fail et ce qui a changé. Si vous ne pouvez pas l’expliquer, vous ne l’avez pas testé.
Checklist: “Do not proceed” conditions
- Erreurs de checksum existantes avant le test.
- Échecs de flush ou resets de périphériques dans les logs kernel en fonctionnement normal.
- Périphérique SLOG sans PLP vérifié utilisé pour workloads sync critiques.
- Pool déjà à haute utilisation où les résultats seront dominés par la surcharge.
Checklist: evidence to capture every run
zpool status -vavant et après.zfs getpour sync/logbias/recordsize/compression pour les datasets testés.zpool iostat -vpendant le workload.- Logs kernel autour du reboot : resets de contrôleur, timeouts, échecs de flush.
- Diff de snapshot autour d’un marqueur connu.
- Résultat de scrub après récupération.
FAQ
1) Does ZFS guarantee zero data loss on power failure?
ZFS garantit la consistance sur disque de ses structures, et protège l’intégrité des données avec des checksums.
Il ne garantit pas que les écritures async survivent, et il ne peut pas forcer un matériel malhonnête à persister des données qu’il a prétendues écrites.
2) If my pool imports cleanly after a power cut, am I safe?
Vous êtes plus en sécurité que beaucoup de systèmes de fichiers, mais « s’importe proprement » n’est pas la même chose que « les écritures sync étaient durables ».
Vous avez toujours besoin de marqueurs applicatifs et d’un scrub pour valider l’intégrité et les frontières.
3) Is a SLOG required for power-loss safety?
Non. Un SLOG sert principalement la performance des écritures synchrones. La sécurité vient de sémantiques sync correctes et de périphériques honnêtes.
Un mauvais SLOG peut même réduire la sécurité en concentrant les écritures sync sur un périphérique qui ment lors d’une perte de puissance.
4) Should I set sync=always everywhere?
Pour tester la durabilité et exposer les mensonges matériel : oui, sur les datasets testés. En production : seulement si votre budget de latence le permet.
Sinon, gardez sync=standard et assurez-vous que vos applications demandent fsync quand nécessaire.
5) How do I know if my SSD has power-loss protection?
Les specs du vendeur aident, mais la réponse fiable est le test plus des classes de périphériques entreprises connues pour le PLP.
Si vous ne pouvez pas vérifier le PLP, ne mettez pas ce périphérique en rôle SLOG pour des workloads critiques.
6) Is pulling the plug the best test?
C’est le test le plus littéral, mais pas toujours le plus reproductible. Une prise PDU commutée ou une coupure par relais est meilleure pour un timing consistant.
Utilisez la méthode qui vous donne des résultats reproductibles et des logs propres.
7) What’s the difference between a crash test and a power loss test?
Un test de crash (kernel panic, reboot) arrête l’OS mais laisse souvent l’alimentation des périphériques intacte, donc les caches peuvent être flushés.
Un test de perte d’alimentation retire l’alimentation afin que les caches volatiles n’aient pas de sortie propre. Ce sont des vérités différentes.
8) Can UPS replace power-loss testing?
Non. L’UPS réduit la fréquence et achète du temps, mais n’a pas vocation à réparer les bugs de firmware, les mensonges de flush, ou les événements de puissance partiels.
De plus : les batteries vieillissent, et les opérations de maintenance ont une fâcheuse tendance à « découvrir » que c’était mal entretenu.
9) Do RAIDZ layouts behave differently under power loss compared to mirrors?
La consistance CoW reste, mais opérationnellement les mirrors récupèrent généralement plus vite et offrent de meilleures IOPS, ce qui peut réduire
le temps de récupération et l’impact du scrub. RAIDZ peut être parfaitement sûr ; il peut aussi être plus lent sous stress.
10) If I see checksum errors after a power cut, is my data permanently corrupted?
Pas nécessairement. Avec la redondance, ZFS peut souvent réparer. Mais des erreurs de checksum après un test contrôlé sont une alarme forte.
Traitez cela comme un signal que votre chaîne de durabilité est compromise et corrigez la cause racine avant de faire confiance au système.
Conclusion : étapes pratiques suivantes
Les tests de coupure d’alimentation ne sont pas une question de bravoure. Il s’agit de ne pas déléguer votre confiance à des suppositions.
ZFS vous donne d’excellents primitives — cohérence copy-on-write, checksums, scrub, et visibilité claire de l’état du pool.
Votre travail est de vous assurer que la pile matérielle ne sabote pas ces garanties.
Prochaines étapes qui font réellement avancer :
- Montez un labo qui correspond à la classe et à la topologie de stockage de la production.
- Exécutez un cycle de test scripté avec
sync=alwayssur le dataset cible et un vrai workload fsync. - Coupez l’alimentation de manière reproductible, importez en lecture seule d’abord, puis validez avec des diffs de snapshot et un scrub.
- Si vous utilisez un SLOG, traitez-le comme un composant de durabilité : PLP-capable, surveillé, et testé.
- Transformez les résultats en runbook : procédure d’import, vérifications de logs, validation d’intégrité, et critères « stop the line ».
Le meilleur résultat est ennuyeux : votre test devient une routine, les graphiques sont normaux, et personne ne raconte d’histoire sur vous dans un postmortem.
C’est le genre de renommée que vous voulez.