Le courant tombe. Les ventilateurs ralentissent. Votre téléphone s’allume. Et vous restez avec cette lente angoisse : est-ce que ZFS a « géré » la situation,
ou vous vous êtes juste offert un week-end d’imports de pool, de vdevs dégradés et d’explications embarrassantes ?
Un arrêt propre déclenché par l’UPS est l’un de ces contrôles ennuyeux et peu glamour qui font la différence entre « on a perdu le courant »
et « on a perdu la confiance ». Mais il ne protège pas ce que la plupart des gens pensent. Il protège la cohérence et
la prévisibilité — pas le matériel, pas la physique, et certainement pas l’idée que le RAID est un champ de force.
Ce qu’un arrêt propre protège réellement (et ce qu’il ne protège pas)
Définissons « arrêt propre » comme la production le définit : l’OS et les services s’arrêtent dans une séquence ordonnée, ZFS
vide et commit ce qu’il doit, et le pool est exporté ou au moins laissé dans un état connu et cohérent.
L’UPS n’est que le messager. Le workflow d’arrêt est la protection.
Ce que cela protège
-
Travail de replay du ZFS intent log (ZIL) : Avec un arrêt ordonné, vous réduisez la quantité de travail synchrone
restante à rejouer au moment de l’import. Moins de replay signifie moins de latence au démarrage et moins de mauvaises surprises pour les applications
qui détestent les fenêtres de récupération. -
Opportunités de cohérence au niveau applicatif : Les bases de données peuvent faire un checkpoint, vider leurs caches ou refuser les écritures.
Un système de fichiers peut être crash-consistent tout en étant incohérent vis-à-vis des applications. Un arrêt propre vous permet de régler cette seconde partie. -
Comportement d’amorçage/import prévisible : Un arrêt propre évite les imports qui « coincent », les récupérations de txg lourdes et
le jeu du « pourquoi le pool met 20 minutes à s’importer ». -
Risque réduit de pannes en cascade : Si le courant vacille ou que l’UPS s’épuise au milieu du chaos, vous voulez que la machine
soit déjà arrêtée, pas en train d’écrire à moitié des métadonnées pendant que la batterie rend ses dernières forces. -
Personnes et processus : Un arrêt propre signifie que les alertes se déclenchent dans le bon ordre, que les logs sont écrits, et que vous pouvez
distinguer « panne de courant » et « incident de stockage ».
Ce que cela ne protège pas
-
Données jamais commit : Si une application a mis des écritures en tampon sans faire de fsync, elle peut les perdre même lors d’un arrêt propre
— sauf si l’application participe (ou que l’OS force cela en arrêtant correctement les services). -
Pannes matérielles causées par des événements électriques : Surtensions, sous-tensions et alimentations bon marché peuvent toujours endommager du matériel. Un UPS aide,
mais ce n’est pas un talisman. -
Mauvaises hypothèses sur « sync=disabled » : Si vous avez désactivé sync pour des benchs, un arrêt propre ne fera pas réapparaître des écritures reconnues
qui étaient en RAM. -
Caches d’écriture de firmware ou contrôleurs sans protection contre la perte d’alimentation : Si votre HBA ou disque ment sur les flushes,
votre système de fichiers peut tout faire correctement et perdre quand même des données. ZFS ne peut pas contrecarrer la physique. -
Corruption silencieuse déjà présente : ZFS détectera beaucoup de corruptions et réparera quand la redondance existe,
mais un arrêt propre ne rendra pas un disque défectueux rétroactivement sain.
Une citation qui ressemble toujours à de la doctrine ops : « Tout échoue, tout le temps. »
— Werner Vogels.
La démarche mature est de décider quelles défaillances deviennent ennuyeuses.
Blague #1 : Un UPS, c’est comme un parapluie — utile, mais si vous tentez d’arrêter un ouragan avec, vous allez juste être plus mouillé et plus en colère.
Cohérence en cas de crash ZFS en termes opérationnels
ZFS est transactionnel. Il prépare des changements puis les commit par groupes de transactions (txg). Quand un txg commit, les structures sur disque
sont mises à jour de manière conçue pour rester cohérentes après un crash. C’est la promesse centrale : vous pouvez perdre
des modifications récentes non commit, mais vous ne devriez pas avoir un système de fichiers à moitié mis à jour nécessitant une reconstruction à la fsck.
Le piège est que « cohérent » n’est pas « sans indisponibilité » et pas « sans perte de données ». C’est « pas de désordre structurel ». Et le
deuxième piège est que le reste de la pile — le ZIL, le SLOG, l’application, l’hyperviseur, le réseau —
peut encore se liguer pour allonger votre journée.
Les parties qui comptent pendant une perte de courant
-
TXG (transaction group) : Regroupe données et métadonnées modifiées, puis commit. Un crash signifie : le dernier txg commit est sûr ;
le txg en cours est abandonné ou rejoué selon le besoin. -
ZIL (ZFS Intent Log) : Pertinent uniquement pour les écritures synchrones. Il stocke des enregistrements d’intention pour que, après un crash,
ZFS puisse rejouer ce qui avait été promis comme « commit » aux applications utilisant fsync/O_DSYNC. -
SLOG (Separate Log device) : Dispositif optionnel pour stocker le ZIL plus rapidement (et plus sûrement, si protégé contre la perte d’alimentation).
Ce n’est pas un cache d’écriture pour tout. C’est un journal spécialisé pour les écritures sync. - ARC : Cache RAM. Excellent pour la performance. Inutile pour la durabilité quand l’alimentation est coupée.
- L2ARC : Cache de lecture secondaire. Pas un outil de durabilité. Au redémarrage c’est surtout « agréable, mais vous êtes froid à nouveau ».
Six à dix faits rapides et contexte historique (parce qu’ops a une mémoire)
-
ZFS a été créé chez Sun Microsystems au début des années 2000 pour remplacer la séparation gestionnaire de volumes + système de fichiers,
car cette séparation causait de réelles douleurs opérationnelles à l’échelle. -
Les systèmes de fichiers traditionnels s’appuyaient souvent sur fsck après des arrêts non propres ; le modèle copy-on-write de ZFS visait à éviter ce
cycle de reconstruction en gardant l’état disque auto-cohérent. -
Le « ZIL » n’est pas un journal pour toutes les écritures ; il concerne spécifiquement la sémantique des écritures synchrones. Cette distinction embrouille encore
beaucoup de monde et alimente de mauvais achats de SLOG. -
Les baies de stockage d’entreprise utilisaient historiquement une cache d’écriture avec batterie pour ack les écritures en sécurité ; le chemin sync de ZFS est
une approche logicielle qui dépend toujours d’un comportement honnête des flushs matériels. -
Les premiers SSD grand public avaient la fâcheuse habitude de mentir sur l’achèvement des écritures et de manquer de condensateurs pour les flushs, ce qui rendait « sync »
moins significatif que ce que l’on pensait. - OpenZFS est devenu une continuation communautaire après que la gouvernance d’Oracle sur ZFS ait créé un écosystème forké ; les meilleures pratiques opérationnelles se sont répandues via les vendeurs et des rapports d’incidents éprouvés.
- L’essor de la virtualisation et du NFS/iSCSI a rendu la sémantique synchrone plus courante dans les labs domestiques et les environnements SMB, augmentant l’importance réelle de la correction ZIL/SLOG.
-
« Intégration UPS » voulait autrefois dire câbles série et démons fournis par les vendeurs ; maintenant c’est surtout USB HID et outils UPS réseau (NUT),
ce qui est plus simple — et plus facile à mal configurer.
L’arrêt propre ne sert pas à rendre ZFS « plus cohérent ». ZFS est déjà conçu pour être crash-consistent.
L’arrêt propre sert à réduire le replay, réduire l’ambiguïté de récupération et donner le temps aux applications de clore proprement leurs opérations.
Objectifs de l’intégration UPS : le contrat que vous voulez
Ne traitez pas l’intégration UPS comme « installer un démon et espérer ». Traitez-la comme un contrat en trois clauses :
détecter les événements de puissance, décider en fonction du runtime, et arrêter dans le bon ordre. Si vous ne pouvez pas énoncer votre contrat en une phrase,
vous n’avez pas de contrat — vous avez des impressions.
Clause 1 : Détecter l’événement de puissance de manière fiable
L’USB est pratique. L’USB est aussi la première chose qui devient instable quand hubs, câbles bon marché et mises à jour du kernel se rencontrent.
Si c’est de la production, préférez un UPS réseau ou un serveur NUT dédié qui reste en ligne plus longtemps que n’importe quel hôte.
Clause 2 : Décider en fonction du runtime, pas du théâtre du pourcentage de batterie
Le pourcentage de batterie n’est pas un plan. C’est un ressenti avec des chiffres. Vous voulez des estimations de runtime, plus une marge de sécurité,
et que le déclencheur d’arrêt se produise tant que l’UPS est encore stable. Le mode brownout n’est pas l’endroit où vous voulez découvrir qu’un script d’arrêt contient une faute de frappe.
Clause 3 : Arrêter dans le bon ordre
Pour ZFS, le « bon ordre » signifie généralement : arrêter les applications qui génèrent des écritures, vider/arrêter les exports de stockage réseau, puis arrêter l’OS.
Si vous exécutez des VM sur ZFS, l’hyperviseur a besoin de temps pour les éteindre proprement avant que l’hôte ne tombe.
Blague #2 : La seule chose plus optimiste que « on réparera après la coupure », c’est « l’UPS va s’en occuper ».
Plan de diagnostic rapide
Quand quelqu’un dit « on a eu un événement de puissance et ZFS est lent/étrange », vous voulez un triage rapide qui trouve le goulot
en quelques minutes, pas des heures. Voici l’ordre qui rapporte généralement.
Premier point : confirmer quel type d’arrêt vous avez eu
- Était-ce un arrêt systemd propre, ou une perte de puissance brutale ?
- Le démon UPS a-t-il déclenché ? A-t-il appelé la commande d’arrêt ? L’hôte a-t-il atteint poweroff ?
- Le pool s’est-il importé automatiquement, ou a-t-il attendu/planté ?
Deuxième point : vérifier l’état du pool et si vous êtes en replay ou en resilver
- Le pool est-il
ONLINE,DEGRADED, ou s’important lentement ? - Un scrub/resilver est-il en cours, et bride-t-il les IO ?
- Y a-t-il des erreurs de checksum (ce qui change toute la conversation) ?
Troisième point : décider si le problème est la latence des écritures synchrones (ZIL/SLOG) ou des IO généraux
- Si les applis se plaignent de latence fsync, concentrez-vous sur la santé du SLOG, la profondeur de file d’attente et le comportement des flushs.
- Si tout est lent, regardez la latence des vdevs, un disque mourant, des resets de contrôleur, ou un pool coincé en récupération.
Quatrième point : vérifier l’ordre d’arrêt des services
- Les exports NFS/iSCSI se sont-ils arrêtés avant que ZFS et le réseau ne tombent ?
- Les bases de données ont-elles reçu un signal d’arrêt et eu le temps de faire un checkpoint ?
- Les VM se sont-elles éteintes, ou l’hôte s’est-il arrêté sous elles ?
Tâches pratiques : commandes, sorties, décisions (12+)
Voici les tâches que j’exécute réellement après des événements de power ou lors du travail d’intégration UPS. Chacune a : une commande, une sortie réaliste,
ce que la sortie signifie, et la décision que vous prenez. Les commandes supposent Linux + OpenZFS ; ajustez les chemins pour votre distro.
Task 1: Confirm last shutdown was clean (journald)
cr0x@server:~$ journalctl -b -1 -u systemd-shutdown --no-pager | tail -n 20
Dec 26 01:12:41 server systemd-shutdown[1]: Syncing filesystems and block devices.
Dec 26 01:12:44 server systemd-shutdown[1]: Sending SIGTERM to remaining processes...
Dec 26 01:12:46 server systemd-shutdown[1]: Sending SIGKILL to remaining processes...
Dec 26 01:12:47 server systemd-shutdown[1]: Unmounting file systems.
Dec 26 01:12:48 server systemd-shutdown[1]: Deactivating swaps.
Dec 26 01:12:48 server systemd-shutdown[1]: Detaching loop devices.
Dec 26 01:12:49 server systemd-shutdown[1]: All filesystems unmounted.
Dec 26 01:12:49 server systemd-shutdown[1]: Powering off.
Signification : Le chemin d’arrêt ressemble à une séquence ordonnée. En cas de perte de courant, vous verriez souvent une coupure abrupte des logs.
Décision : Si c’est propre, concentrez-vous moins sur « ZFS a-t-il été corrompu » et plus sur « les applis se sont-elles arrêtées proprement et l’UPS a-t-il déclenché correctement ».
Task 2: Check if the UPS daemon logged “on battery” and “low battery” events (NUT)
cr0x@server:~$ journalctl -u nut-monitor --since "today" --no-pager | egrep -i "on battery|low battery|shutdown" | tail -n 20
Dec 26 01:10:02 server upsmon[2314]: UPS ups@localhost on battery
Dec 26 01:12:05 server upsmon[2314]: UPS ups@localhost battery is low
Dec 26 01:12:06 server upsmon[2314]: Executing automatic power-fail shutdown
Signification : Les événements UPS ont été détectés et traités. Si vous ne voyez que « on battery » mais pas l’arrêt, vos seuils de déclenchement sont mauvais.
Décision : Si « battery is low » arrive trop tard (juste avant la perte de courant), augmentez la marge d’arrêt (seuil runtime) et retestez.
Task 3: Query UPS status live (NUT upsc)
cr0x@server:~$ upsc ups@localhost
battery.charge: 96
battery.runtime: 2480
battery.voltage: 27.3
device.mfr: APC
device.model: Smart-UPS 1500
input.voltage: 121.0
output.voltage: 120.0
ups.status: OL
ups.load: 22
Signification : ups.status: OL signifie alimentation secteur. Le runtime est en secondes ici. La charge est modeste.
Décision : Utilisez le runtime (battery.runtime) comme entrée pour la décision d’arrêt. Configurez l’arrêt quand le runtime descend sous la fenêtre requise + marge.
Task 4: Confirm the pool state and error counters
cr0x@server:~$ sudo zpool status -x
all pools are healthy
Signification : Aucun problème connu. C’est ce que vous voulez après une panne.
Décision : Si tout est sain, n’entamez pas de « rituels de récupération » qui ajoutent du risque. Passez à la vérification applicative et aux contrôles de performance.
Task 5: Full pool status with vdev errors (after a nasty outage)
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: DEGRADED
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 00:12:31 with 2 errors on Thu Dec 26 01:44:09 2025
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 2 (repairing)
errors: Permanent errors have been detected in the following files:
tank/data/app.db
Signification : Ce n’est plus « juste » une coupure. Vous avez des erreurs de checksum et un fichier marqué comme définitivement endommagé.
Décision : Arrêtez l’application affectée, restaurez ce fichier depuis des backups/snapshots, et enquêtez sur le disque sdd (SMART, câblage, resets du contrôleur). Ne minimisez pas les erreurs de checksum.
Task 6: Check whether a resilver/scrub is in progress and its impact window
cr0x@server:~$ sudo zpool status tank | sed -n '1,20p'
pool: tank
state: ONLINE
scan: resilver in progress since Thu Dec 26 01:20:12 2025
312G scanned at 1.02G/s, 88.4G issued at 289M/s, 3.50T total
88.4G resilvered, 2.46% done, 03:18:44 to go
Signification : Un resilver est en cours et va capter la bande passante et les IOPS.
Décision : Si c’est une charge production, planifiez les jobs IO-intensifs hors de la fenêtre de resilver et ajustez zfs_resilver_delay/zfs_scan_idle seulement si vous comprenez les compromis.
Task 7: Check import history and whether the pool was exported
cr0x@server:~$ sudo zpool history -il tank | tail -n 20
2025-12-26.01:12:48 zpool export tank
2025-12-26.01:12:49 system: shutdown initiated by upsmon
2025-12-26.01:18:02 zpool import tank
Signification : Quelqu’un (ou l’automatisation) a exporté le pool avant poweroff. C’est une excellente hygiène et réduit l’ambiguïté à l’import.
Décision : Si vous ne voyez pas d’exports lors des événements d’arrêt, envisagez d’ajouter un export contrôlé dans votre chemin d’arrêt UPS — prudemment, avec un bon ordre.
Task 8: Confirm dataset sync settings (avoid accidental “fast but unsafe”)
cr0x@server:~$ sudo zfs get -r sync tank | head -n 15
NAME PROPERTY VALUE SOURCE
tank sync standard default
tank/data sync standard inherited from tank
tank/data/postgres sync standard local
tank/vm sync disabled local
Signification : tank/vm a sync=disabled. Ce dataset reconnaît les écritures sans garantir la durabilité.
Décision : Si tank/vm héberge des disques de VM ou des bases, remettez-le en standard (ou always si approprié) et investissez dans un SLOG adapté si la latence sync motive ce choix.
Task 9: See whether you even have a SLOG and what it is
cr0x@server:~$ sudo zpool status tank | egrep -A3 "logs|cache|special"
logs
nvme0n1p2 ONLINE 0 0 0
Signification : Il y a un device de log dédié. Bien — si c’est le bon type de device.
Décision : Validez que le SLOG est doté d’une protection contre la perte d’alimentation (PLP). S’il ne l’a pas, vous avez construit un « device rapide pour crash ».
Task 10: Confirm SLOG device health and error history (SMART)
cr0x@server:~$ sudo smartctl -a /dev/nvme0 | egrep -i "model|percentage used|media|power cycles|unsafe shutdowns"
Model Number: INTEL SSDPE2KX040T8
Percentage Used: 3%
Media and Data Integrity Errors: 0
Power Cycles: 38
Unsafe Shutdowns: 7
Signification : « Unsafe Shutdowns » non nul est courant sur la durée de vie d’un device, mais s’il augmente à chaque panne, vous n’arrêtez pas proprement de façon routinière.
Décision : Corrélez les comptes d’unsafe shutdown avec les pannes et les tests UPS. S’ils augmentent lors de tests planifiés, votre déclencheur d’arrêt est trop tardif ou l’ordre est mauvais.
Task 11: Check kernel logs for drive/controller resets around the outage
cr0x@server:~$ dmesg -T | egrep -i "reset|link is down|I/O error|ata[0-9]" | tail -n 20
[Thu Dec 26 01:10:11 2025] ata3: link is slow to respond, please be patient (ready=0)
[Thu Dec 26 01:10:15 2025] ata3: COMRESET failed (errno=-16)
[Thu Dec 26 01:10:19 2025] sd 2:0:0:0: [sdd] tag#18 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[Thu Dec 26 01:10:19 2025] blk_update_request: I/O error, dev sdd, sector 812345672 op 0x1:(WRITE) flags 0x0 phys_seg 1 prio class 0
Signification : Ce n’est pas ZFS qui dramatise ; c’est le kernel qui vous dit que le chemin de stockage était instable.
Décision : Traitez cela d’abord comme un incident matériel/câblage/contrôleur. Les erreurs ZFS sont souvent en aval d’erreurs de transport.
Task 12: Measure pool latency quickly (iostat) and decide if you’re bottlenecked on sync writes
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 2.01T 1.49T 110 980 12.8M 94.1M
raidz2-0 2.01T 1.49T 110 980 12.8M 94.1M
sda - - 30 220 3.1M 21.1M
sdb - - 28 235 3.2M 22.4M
sdc - - 27 245 3.3M 23.0M
sdd - - 25 280 3.2M 27.6M
logs - - 0 600 0.0K 52.0M
nvme0n1p2 - - 0 600 0.0K 52.0M
-------------------------- ----- ----- ----- ----- ----- -----
Signification : Le device de log prend beaucoup d’opérations/ bande passante — signe classique d’une charge heavy en sync. Si la latence y est élevée, les applis le ressentiront.
Décision : Si les plaintes de performance coïncident avec l’activité du log, concentrez-vous sur la performance/PLP du SLOG et sur la nécessité réelle du workload pour des écritures sync.
Task 13: Check ZFS event history for import/replay-related hints
cr0x@server:~$ sudo zpool events -v | tail -n 25
TIME CLASS
Dec 26 2025 01:18:02.412345678 sysevent.fs.zfs.pool_import
pool: tank
guid: 1234567890123456789
Dec 26 2025 01:18:04.998877665 sysevent.fs.zfs.config_sync
pool: tank
Signification : Vous voyez les événements d’import et leur timing ; cela aide à corréler « le boot a paru lent » avec des opérations d’import réelles.
Décision : Si les événements d’import sont fréquents et associés à des crashs, corrigez la fiabilité de l’arrêt avant de chasser des micro-optimisations.
Task 14: Verify NFS/iSCSI services were stopped cleanly before shutdown
cr0x@server:~$ systemctl status nfs-server --no-pager
● nfs-server.service - NFS server and services
Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled)
Active: active (running) since Thu 2025-12-26 01:18:22 UTC; 12min ago
Docs: man:rpc.nfsd(8)
Main PID: 1842 (rpc.nfsd)
Status: "running"
Signification : Il tourne maintenant, mais il faut toujours vérifier s’il s’est arrêté avant le dernier shutdown.
Décision : Récupérez les logs du boot précédent pour le timing d’arrêt des services. Si NFS est resté actif pendant que ZFS tentait de se calmer, vous avez du travail d’ordonnancement à faire.
Task 15: Validate systemd ordering for UPS-triggered shutdown hook
cr0x@server:~$ systemctl list-dependencies shutdown.target --no-pager | head -n 25
shutdown.target
● ├─systemd-remount-fs.service
● ├─systemd-poweroff.service
● ├─umount.target
● ├─final.target
● └─systemd-shutdown.service
Signification : Cela montre le parcours d’arrêt. Votre démon UPS devrait déclencher un arrêt normal, pas un « kill -9 everything and pray ».
Décision : Si votre intégration UPS contourne systemd (scripts personnalisés appelant poweroff bizarrement), refactorez pour utiliser un arrêt standard afin que les services arrêtent correctement.
Task 16: Test shutdown trigger without actually powering off (NUT upsmon -c fsd)
cr0x@server:~$ sudo upsmon -c fsd
Network UPS Tools upsmon 2.8.0
FSD set on UPS [ups@localhost]
Signification : Ceci simule la gestion d’un « forced shutdown ». Selon la config, cela peut lancer l’arrêt immédiatement.
Décision : Exécutez ceci pendant une fenêtre de maintenance et observez l’ordre d’arrêt des services et le comportement d’export du pool. Si c’est chaotique, corrigez avant la prochaine vraie panne.
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 faisait tourner un hôte de virtualisation sur ZFS pour des services internes. Ils avaient un UPS. Ils avaient de la confiance.
Ils avaient aussi une hypothèse critique : « Si l’UPS est connecté en USB, l’arrêt se fera toujours. »
Le jour où cela a foiré n’a pas été dramatique — juste une chute de tension rapide et un générateur qui a mis plus de temps que prévu à démarrer.
L’hôte ne s’est pas arrêté. L’UPS a essayé de le signaler, mais le périphérique USB s’était ré-énuméré différemment après une mise à jour du kernel,
et le démon de monitoring regardait silencieusement le mauvais chemin de périphérique. Aucune alerte, parce que « le démon UPS tourne » était
leur seul contrôle de santé.
Après le retour de l’alimentation, le pool ZFS s’est importé. Pas de corruption. Tout le monde s’est détendu trop vite. Puis le système de fichiers de la VM a montré
une cohérence au niveau fichier mais une incohérence au niveau applicatif : une base de données qui avait ack des écritures s’appuyait sur
des sémantiques de flush hôte qu’ils n’avaient pas vérifiées. La VM a booté, la DB a râlé, et le « court événement électrique »
est devenu une panne étagée pendant que les équipes se disputaient pour savoir si c’était « stockage » ou « l’appli ».
La correction a été ennuyeuse : ils ont ajouté un serveur NUT sur une petite machine avec alimentation stable, utilisé du monitoring réseau, et ajouté
une validation périodique explicite : interroger l’état de l’UPS et alerter si l’UPS disparaît ou si le démon rapporte des données périmées.
Ils ont aussi audité les réglages de dataset sync et arrêté de croire que USB = fiabilité.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Un autre service utilisait ZFS pour un datastore NFS. La performance était « correcte » jusqu’à l’arrivée d’un nouveau workload : une ferme de build qui faisait beaucoup
d’opérations métadonnées et exigeait une latence prévisible. L’équipe a cherché les perf et trouvé le switch magique : sync=disabled
sur le dataset. La latence a chuté. Les graphiques étaient beaux. Une série de high-fives a suivi, ce qui devrait toujours déclencher une alerte de monitoring.
Des mois plus tard, une panne de courant a frappé. L’UPS a initié un arrêt propre et l’hôte s’est éteint proprement. Ils se sont encore félicités.
Puis des utilisateurs ont signalé des artefacts de build manquants et des jobs « réussis » produisant des résultats corrompus.
Rien n’était structurellement corrompu. ZFS était cohérent. Mais les données applicatives comprenaient des écritures ack qui avaient vécu en RAM et n’avaient jamais atteint le stockage stable — parce qu’ils avaient demandé à ZFS de mentir pour la vitesse.
Le postmortem a été gênant car la panne était courte et le système « s’est arrêté proprement ». Voilà le piège :
un arrêt propre vous protège de certains modes de défaillance, mais pas de la désactivation volontaire des garanties de durabilité. L’optimisation
avait transformé « perte de courant rare » en « incident d’intégrité des données inévitable ».
La remédiation a été de réactiver sync et d’ajouter un SLOG approprié avec PLP. Ils ont également séparé les workloads :
les datasets de cache de build ont des réglages différents des stockages d’artefacts. Le tuning de perf est passé de « activer un bit dangereux » à
« concevoir des niveaux de stockage comme des adultes ».
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe de services financiers utilisait iSCSI sur ZFS pour quelques systèmes internes plus critiques qu’ils n’en avaient l’air.
Leur intégration UPS n’était pas tape-à-l’œil. Elle était documentée, testée trimestriellement, et traitée comme partie du change management.
Ils avaient une règle : chaque chemin d’arrêt doit pouvoir être testé sans tirer une prise.
Ils utilisaient un serveur NUT dédié et configuraient les clients pour initier l’arrêt quand le runtime tombait sous un seuil incluant
« temps pour stopp services » plus une marge. La procédure d’arrêt arrêtaient d’abord les targets iSCSI, puis envoyait aux services applicatifs l’ordre d’arrêt,
puis laissait ZFS se calmer. Ils n’exportaient pas manuellement les pools dans des scripts aléatoires ; ils s’appuyaient sur l’ordre d’arrêt standard,
et là où ils ajoutaient des hooks, c’était sous forme d’unités systemd avec dépendances claires.
Quand une vraie panne est arrivée — plus longue que d’habitude — les systèmes se sont arrêtés de manière prévisible, avec des logs propres. Au retour du courant, le démarrage a été ennuyeux.
Les imports ont été rapides. Pas de resilver. Pas d’erreurs mystérieuses. Les utilisateurs n’ont pour la plupart rien remarqué.
Le meilleur : pendant la revue post-incident, personne n’a disputé ce qui s’était passé, car les logs rendaient tout évident et la procédure avait été répétée. « Ennuyeux » était le critère de succès, et ils l’ont atteint.
Erreurs fréquentes : symptôme → cause → correction
1) Symptom: pool import takes forever after outages
Cause racine : arrêts non propres répétés entraînant plus de travail de récupération ; parfois aggravés par un disque marginal ou des resets de contrôleur.
Correction : vérifiez que l’UPS déclenche plus tôt ; consultez journalctl pour un arrêt propre ; inspectez dmesg pour des resets de lien ; remplacez câbles/HBA instables avant d’ajuster ZFS.
2) Symptom: apps report “database corruption” but ZFS status is clean
Cause racine : incohérence applicative due à sync désactivé, fsync manquant, ou perte abrupte d’une VM.
Correction : restaurez depuis backups/snapshots ; réactivez sync ; assurez l’ordre d’arrêt des VM ; validez les réglages DB (mode durabilité) et les sémantiques de stockage.
3) Symptom: NFS clients hang during outage and come back with stale handles
Cause racine : ordre d’arrêt incorrect : les exports restent actifs pendant que le stockage disparaît, ou les clients ne voient pas un arrêt propre du serveur.
Correction : ordonnancement systemd : arrêter nfs-server (ou la target iSCSI) tôt dans l’arrêt ; assurez-vous que l’UPS déclenche un arrêt standard et non un script kill.
4) Symptom: UPS “works” in normal times but fails during real outages
Cause racine : le monitoring existe mais n’est pas validé ; instabilité USB ; démon connecté mais déconnecté du device.
Correction : alertez sur la fraîcheur de la télémétrie UPS ; préférez un UPS réseau ; exécutez des tests FSD simulés ; enregistrez les lignes de log attendues et vérifiez-les.
5) Symptom: sync write latency spikes after adding a SLOG
Cause racine : le device SLOG est plus lent ou sans PLP, provoquant des stalls de flush ; ou il est sur un bus partagé avec contention.
Correction : choisissez un SSD/NVMe entreprise avec PLP ; isolez-le ; validez avec zpool iostat et SMART ; retirez un SLOG mauvais plutôt que de le subir.
6) Symptom: checksum errors appear after power events
Cause racine : corruption réelle due à un disque mourant, un chemin d’alimentation instable, ou des problèmes de contrôleur ; parfois révélée par un scrub après reboot.
Correction : traitez comme un incident matériel ; exécutez des tests SMART ; reseat/remplacez les composants ; restaurez les fichiers corrompus depuis des copies saines ; relancez un scrub après les corrections.
7) Symptom: system shuts down too late, battery dies mid-shutdown
Cause racine : seuil d’arrêt configuré sur « low battery » au lieu de « runtime suffisant pour finir l’arrêt », ou estimation runtime mal calibrée.
Correction : configurez l’arrêt sur runtime restant avec marge ; mesurez le temps réel d’arrêt ; incluez le temps pour l’arrêt des VM et l’export du stockage.
8) Symptom: after outage, pool is ONLINE but performance is terrible
Cause racine : resilver/scrub en cours, ou un disque a une latence élevée ; ARC froid ; ou les applis rejouent leur propre récupération.
Correction : vérifiez la ligne scan de zpool status ; inspectez les IO par vdev avec zpool iostat -v ; identifiez le device lent ; communiquez la fenêtre de récupération attendue aux propriétaires d’applis.
Listes de contrôle / plan étape par étape
Étape par étape : construire une intégration UPS qui vous protège réellement
- Décidez l’objectif : « L’hôte s’éteint proprement avant que l’UPS n’atteigne X secondes de runtime ; les applis s’arrêtent dans l’ordre ; les imports sont rapides. »
- Mesurez le temps d’arrêt : chronométrez un arrêt complet des services et du poweroff. Ajoutez une marge. Ne devinez pas.
- Choisissez l’architecture : si plusieurs hôtes, exécutez un serveur de monitoring UPS dédié (NUT) et faites souscrire les clients.
- Configurez les déclencheurs sur le runtime, pas sur le pourcentage : réglez l’arrêt quand runtime < (temps d’arrêt mesuré + marge).
- Validez l’ordre des services : arrêtez d’abord les services générant beaucoup d’écritures (bases, hyperviseurs), puis les exports (NFS/iSCSI), puis l’OS.
-
Auditez les options de durabilité ZFS : trouvez tout
sync=disabledet justifiez-le par écrit. - Validez la correction du SLOG : si vous utilisez un SLOG, exigez PLP et monitorisez la santé du device.
- Testez sans couper l’alimentation : simulez FSD et vérifiez les logs et le comportement attendus.
- Alertez sur la fraîcheur de la télémétrie UPS : si le démon ne peut pas lire l’état UPS, vous devez le savoir avant la panne.
-
Faites un contrôle d’import après le test : après chaque test, vérifiez
zpool status, les erreurs, et le temps d’import.
Checklist de réponse après une panne : après le retour du courant
- Vérifiez si l’arrêt était propre : logs du boot précédent (
journalctl -b -1). - Vérifiez la santé du pool :
zpool status -xpuiszpool status -vcomplet si quelque chose cloche. - Vérifiez les erreurs du kernel :
dmesgpour resets et erreurs I/O. - Vérifiez s’il y a un scrub/resilver : attendez-vous à un impact de performance et estimez le temps restant.
- Validez les datasets critiques : confirmez les réglages
sync, la présence du SLOG, et toute erreur de checksum. - Puis validez les applications : récupération DB, intégrité des VM, et reconnexions des clients.
FAQ
1) Un arrêt propre empêche-t-il la corruption ZFS ?
Il réduit le risque et le travail de récupération, mais ZFS est conçu pour être crash-consistent même sans arrêt propre. L’arrêt propre protège principalement
la cohérence applicative, réduit le replay du ZIL et évite le chaos matériel/transport pendant la perte d’alimentation.
2) Si ZFS est crash-consistent, pourquoi avoir un UPS ?
Parce que crash-consistent n’est pas « sans conséquences ». Les imports peuvent être plus lents, les applis peuvent perdre du travail ack (selon les réglages),
et des pertes brutales répétées stressent le matériel. De plus : vos objectifs d’uptime incluent généralement « ne pas redémarrer de façon inattendue ».
3) Un SLOG est-il nécessaire pour la sécurité ?
Non. Un SLOG est un outil de performance pour les workloads synchrones. La sécurité vient des sémantiques sync correctes et d’un comportement honnête des flushs matériels.
Si vous ajoutez un SLOG, il doit être fiable (idéalement PLP) ou vous pouvez empirer la situation.
4) Que fait réellement sync=disabled ?
Il dit à ZFS d’acknowledger les écritures synchrones sans attendre qu’elles soient commit de manière sûre. Vous gagnez en vitesse et vous échangez la durabilité.
Si votre appli croit avoir commit des données, elle peut se tromper après un crash — même avec un arrêt propre si le timing est défavorable.
5) Dois-je exporter le pool pendant l’arrêt ?
Cela peut aider en rendant le prochain import plus propre, mais vous devez le faire dans le bon ordre. Si des services ont encore des fichiers ouverts ou
des clients écrivent, l’export peut bloquer ou échouer. Préférez l’ordre d’arrêt standard ; ajoutez des hooks d’export seulement si vous pouvez les tester.
6) Pourquoi mon scrub a démarré après le reboot ?
Certains systèmes ou admins planifient des scrubs et ils se lancent au reboot ; dans d’autres cas, vous le lancez manuellement pour valider.
Lancer un scrub après une panne est une bonne habitude quand l’événement était non propre ou si vous suspectez une instabilité matérielle — attendez-vous à un impact sur la perf.
7) L’UPS indique 40 %. Pourquoi est-il tombé plus tôt ?
Les changements de charge, l’âge de la batterie, la température et l’étalonnage affectent tous le runtime. Le pourcentage n’est pas un prédicteur fiable sous charge variable.
Basez vos décisions sur des estimations de runtime et effectuez régulièrement des tests contrôlés pour calibrer.
8) NUT vs apcupsd : lequel utiliser ?
Si vous avez un seul UPS APC connecté à un hôte, apcupsd est simple. Si vous avez plusieurs hôtes, des vendeurs UPS mixtes,
ou voulez un serveur de monitoring réseau, NUT est généralement mieux adapté.
9) Comment savoir si mon ordre d’arrêt est correct ?
Vous le testez. Simulez un forced shutdown (fenêtre de maintenance), puis inspectez les logs pour confirmer : les applis se sont arrêtées d’abord, les exports se sont arrêtés,
ZFS n’était pas en pleine activité, et l’hôte s’est éteint avec du temps en réserve.
10) Après une panne, dois-je lancer immédiatement zpool scrub ?
Si l’arrêt était propre et que zpool status -x est sain, vous pouvez souvent attendre votre schedule régulier.
Si l’arrêt était non propre, ou vous voyez des erreurs I/O, ou vos workloads sont critiques, lancez un scrub plus tôt — après avoir stabilisé le matériel.
Conclusion : prochaines étapes pour éviter les surprises à 3 h du matin
Un arrêt propre déclenché par l’UPS ne confère pas l’immortalité aux disques, aux bases ou aux mauvaises idées. Il vous achète un atterrissage contrôlé :
moins de promesses en vol, moins de travail de récupération, et un système qui se comporte de façon prévisible quand la lumière revient.
C’est ce pour quoi vous payez.
- Mesurez votre vrai temps d’arrêt (incluant l’arrêt VM/appli) et réglez des déclencheurs basés sur le runtime avec marge.
- Validez la télémétrie UPS (alertes de fraîcheur) et préférez le monitoring réseau pour les environnements multi-hôtes.
- Auditez les réglages de durabilité ZFS et cessez d’utiliser
sync=disabledcomme stratégie de perf pour des données importantes. - Vérifiez la réalité du SLOG : PLP, monitoring de santé, et suppression si c’est le mauvais device.
- Répétez : exécutez des tests de shutdown simulés et confirmez que les logs montrent un arrêt ordonné et un comportement d’import propre.
Si vous faites ces cinq choses, les coupures de courant deviennent une gêne plutôt qu’un rebondissement scénaristique. Et c’est bien l’essentiel.