
🌐 Aussi en: English · Deutsch · Español
HP3, mon HPE MicroServer Gen10 Plus v2, tourne de nouveau sous Debian 13 avec OpenZFS. Pourquoi il a de nouveau quitté Windows, c’est une histoire pour un autre article. Celui-ci parle de la restauration qui a suivi, et d’un réglage qui se cachait à la vue de tous pendant deux systèmes d’exploitation et deux articles de blog.
Le plan était ennuyeux, comme une restauration doit l’être : un nouveau pool RAIDZ1 sur les trois mêmes SSD WD Red SA500, des datasets par utilisateur, puis environ 1,7 To recopiés depuis un disque USB avec rsync. Même méthode que d’habitude : je prends les décisions, mon co-admin IA (Claude) lance les commandes et surveille les chiffres. Ce sont justement les chiffres qui ont commencé à paraître anormaux.
🐌 Sept mégaoctets par seconde. Par SSD.
La copie se traînait à 25 à 35 Mo/s. L’estimation annonçait environ seize heures. Même des choses simples comme zfs create ou zpool status restaient bloquées pendant des minutes, en attendant que le groupe de transactions suivant ait fini de se synchroniser. Puis zpool iostat -l a montré le vrai problème :
$ zpool iostat -vl storage 5 1
bandwidth total_wait disk_wait
read write read write read write
storage 3.42K 22.7M 1ms 233ms 1ms 65ms
raidz1-0 3.42K 22.7M 1ms 233ms 1ms 65ms
ata-WD_Red_SA500_..._00458 1.14K 7.57M 1ms 262ms 1ms 68ms
ata-WD_Red_SA500_..._01387 1.14K 7.58M 1ms 258ms 1ms 72ms
ata-WD_Red_SA500_..._02050 1.14K 7.58M 1ms 181ms 1ms 57ms
$ cat /proc/pressure/io
some avg10=94.05 avg60=90.06 avg300=80.24
full avg10=88.82 avg60=84.62 avg300=75.87Environ 7,5 Mo/s par disque avec 65 ms de latence, et la machine passait près de 90 % de son temps à attendre les entrées-sorties. Ce sont des SSD SATA annoncés à bien plus de 500 Mo/s en écriture séquentielle. 65 ms, c’est le territoire des disques durs. En fait, c’est pire : un disque dur correct fait mieux que ça.
🕵️ Suspect numéro un : TRIM, et je connaissais déjà la chanson
TRIM était le premier suspect, et pas seulement en théorie. Je m’étais déjà fait avoir une fois. Quand j’ai migré ces SSD de Windows vers Linux pour la première fois, j’ai installé Debian sur des disques auparavant chiffrés avec BitLocker. Les chiffres étaient aussi catastrophiques qu’aujourd’hui, et cette fois-là, un TRIM avait réglé le problème. Alors quand les mêmes symptômes sont revenus, l’impression de déjà-vu s’est imposée.
Pourquoi BitLocker et les SSD font si mauvais ménage lors d’une réinstallation ? Tout tient à la façon dont un SSD voit le monde. Il ne sait pas ce qu’est un fichier. Il ne connaît que des blocs logiques, et un bloc est « utilisé » dès que quelque chose y a été écrit, jusqu’à ce que quelqu’un dise explicitement « tu peux oublier celui-là ». Ce quelqu’un, c’est TRIM (discard dans le jargon Linux). Un système de fichiers l’envoie quand il supprime des fichiers. Un mkfs ou un zpool create tout neuf par-dessus d’anciennes données ne le fait pas forcément pour tout le disque.
BitLocker rend la situation aussi mauvaise que possible. Des données chiffrées sont impossibles à distinguer d’un bruit aléatoire, il n’y a donc rien à compresser ni à dédupliquer dans le disque. Et une fois qu’un volume a été chiffré et utilisé pendant un moment, une grande partie de la mémoire flash contient ce que le SSD doit considérer comme des données précieuses. Ensuite, j’écrase le tout avec un nouveau système. La table de partitions est neuve, le système de fichiers est neuf, mais personne ne dit au SSD que tous ces anciens blocs sont désormais des déchets. De son point de vue, le disque est toujours plein.
Ça fait mal, parce que la flash ne peut pas être réécrite sur place. Elle s’écrit par pages et s’efface par blocs beaucoup plus grands. Un disque qui se croit plein n’a plus aucun bloc pré-effacé. Pour chaque nouvelle écriture, son ramasse-miettes doit d’abord trouver un bloc, copier ailleurs les pages encore « valides » (l’ancien bruit chiffré), effacer le bloc, et seulement ensuite écrire les nouvelles données. Une écriture de l’hôte se transforme en plusieurs écritures internes (amplification d’écriture). Le débit s’effondre, la latence explose, et en plus le disque s’use plus vite.
La bonne méthode, que je note ici pour que mon moi futur l’applique vraiment : avant de confier des SSD d’occasion à un nouveau système de fichiers, on les libère entièrement. Cela détruit tout ce qui se trouve sur le disque, et c’est justement le but :
# Before zpool create / mkfs — irreversibly wipes the drive!
blkdiscard /dev/disk/by-id/ata-WD_Red_SA500_2.5_2TB_...
# Check that the drive supports TRIM at all (non-zero DISC-GRAN/DISC-MAX):
lsblk --discard /dev/sdXSur un SSD SATA au repos, blkdiscard prend généralement de quelques secondes à quelques minutes pour tout le disque. Le faire après coup avec zpool trim sur un pool en service fonctionne aussi. ZFS ne libère alors que l’espace qu’il n’utilise pas. Mais c’est plus lent, ça entre en concurrence avec les vraies entrées-sorties, et ça n’aide qu’à partir du moment où ça tourne.
Il existe une troisième option que je n’ai remarquée que plus tard, en fouillant le BIOS pour autre chose (voir plus bas) : le RBSU de HPE intègre SATA Secure Erase et SATA Sanitize. C’est la version firmware de la même idée. Le disque jette lui-même tout son contenu, y compris ses propres tables de correspondance, et revient aussi neuf qu’au premier jour, avec chaque bloc libre. Pour des SSD qui vont de toute façon être effacés, c’est sans doute la remise à zéro la plus propre qui soit, et elle ne nécessite aucun système en marche. Même avertissement, en plus gros : cela efface entièrement le disque.
Cette fois, j’avais sauté cette étape, nous avons donc lancé un zpool trim storage complet au beau milieu de la restauration. Quarante minutes plus tard, il en était à 2 %, et la copie était à peine plus rapide. TRIM faisait partie du problème, mais ce n’était pas la partie qui avait transformé des SSD en lecteurs de disquettes. Quelque chose de plus fondamental clochait aussi. Et une fois qu’on sait quoi, un TRIM qui se traîne à 2 % devient lui aussi logique.
💡 Suspect numéro deux : un mot dans sysfs
$ for d in sda sdb sdc sdd; do echo "$d $(cat /sys/block/$d/queue/write_cache)"; done
sda write through
sdb write through
sdc write through
sdd write through
$ hdparm -W /dev/disk/by-id/ata-WD_Red_SA500_2.5_2TB_...
write-caching = 0 (off)Write through. Le cache d’écriture des disques eux-mêmes était désactivé. Chaque SSD dispose d’un petit tampon DRAM : il reçoit les écritures, répond « c’est fait » puis les écrit en flash par gros morceaux efficaces. Sans lui, le disque doit terminer chaque écriture sur la flash avant de répondre. Pour un SSD, c’est à peu près la pire façon de travailler, car la flash s’écrit par grandes pages et s’efface par blocs encore plus grands. Beaucoup de petites écritures séparées, cela veut dire des écritures lentes et une usure supplémentaire.
Qui l’a désactivé ? Pas Debian, qui ne touche pas à ce réglage. Le journal du noyau donne la réponse, deux secondes après la mise sous tension, bien avant que quoi que ce soit ne s’exécute en espace utilisateur :
$ dmesg | grep -i "write cache"
[ 2.101312] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled
[ 2.101316] sd 3:0:0:0: [sdc] Write cache: disabled, read cache: enabled
[ 2.101332] sd 5:0:0:0: [sdd] Write cache: disabled, read cache: enabled
[ 2.101407] sd 4:0:0:0: [sdb] Write cache: disabled, read cache: enabled
[ 3.644946] sd 6:0:0:0: [sde] Write cache: enabled, read cache: enabled ← USB stick
[ 530.822448] sd 7:0:0:0: [sdf] Write cache: enabled, read cache: enabled ← USB diskLes quatre SSD SATA internes démarrent en disabled, tandis que les deux périphériques USB démarrent en enabled. Les disques SATA sont livrés avec le cache d’écriture activé, donc quelque chose le désactive pendant le POST, et ce quelque chose, c’est le firmware du serveur. HPE semble régler par défaut « cache d’écriture des disques désactivé » pour les disques SATA, et comme je l’ai découvert, il ne permet pas de le changer (voir plus bas). Les indices pointent clairement vers la plateforme, pas vers Linux.
⚡ Une commande plus tard
$ for d in /dev/disk/by-id/ata-WD_Red_SA500_2.5_2TB_*[0-9]; do hdparm -W1 "$d"; done
setting drive write-caching to 1 (on)
write-caching = 1 (on)
...| Cache d’écriture désactivé | Cache d’écriture activé | |
|---|---|---|
| Débit de la restauration rsync | 25–35 MB/s | 85–95 MB/s |
| Pression E/S (PSI, some avg60) | ~90 % | ~30–45 % |
| Durée estimée de la restauration | ~16 heures | ~6 heures |
| Goulot d’étranglement | les SSD | le disque USB 2,5″ depuis lequel je copiais |
En direct, au milieu de la copie, sans redémarrage. Les SSD ont cessé d’être le problème : ils attendaient désormais un disque dur USB portable. Une fois la restauration terminée, j’ai aussi lancé un benchmark propre.
📊 Le benchmark propre : mêmes disques, un seul interrupteur
Une fois la restauration terminée et le pool de nouveau au repos (environ 1,3 To utilisés, TRIM toujours en pause), j’ai relancé les mêmes tests dd que dans l’article d’origine sur le NAS, deux fois : une fois avec le cache d’écriture des disques de nouveau désactivé, une fois activé. Cette fois, j’ai pris au sérieux les leçons de cet article : un dataset de test dédié avec compression=off, un fichier de 1 Gio de données aléatoires servi depuis la RAM (/dev/shm) pour que /dev/urandom ne devienne pas le goulot d’étranglement, un fsync à la fin, et des lectures en O_DIRECT pour que l’ARC n’embellisse pas les chiffres de lecture.
zfs create -o compression=off storage/bench
head -c 1G /dev/urandom > /dev/shm/rand.bin
dd if=/dev/shm/rand.bin of=/storage/bench/t bs=1M conv=fsync # buffered + fsync
dd if=/dev/shm/rand.bin of=/storage/bench/t bs=1M oflag=direct conv=fsync # O_DIRECT
dd if=/dev/shm/rand.bin of=/storage/bench/t4k bs=4k count=5000 oflag=direct,dsync
dd if=/storage/bench/t of=/dev/null bs=1M iflag=direct # read| Test | Cache désactivé | Cache activé | Facteur |
|---|---|---|---|
| Écriture séquentielle 1M, avec tampon + fsync | 8 MB/s | 547 MB/s | ~68× |
| Écriture séquentielle 1M, O_DIRECT | 2 MB/s | 239 MB/s | ~120× |
| Écriture 4K, O_DIRECT + dsync | 292 kB/s | 334 kB/s | ~1× |
| Lecture séquentielle 1M, O_DIRECT | 972 MB/s | 865 MB/s | – |
Deux mégaoctets par seconde. Sur des SSD. La première tentative utilisait un fichier de 4 Gio comme l’article d’origine. Cache désactivé, elle atteignait 3 Mo/s et aurait duré bien plus d’une demi-heure, alors j’ai réduit à 1 Gio. C’est un résultat en soi.
Ce que dit vraiment le tableau :
- Les écritures sont multipliées par 70 à 120. Ce n’est plus un gain d’optimisation. C’est la différence entre « cassé » et « qui fonctionne ».
- Les lectures ne changent pas. Évidemment, c’est un cache d’écriture. La petite différence n’est que du bruit d’une exécution à l’autre.
- Les écritures synchrones en 4K ne s’améliorent pas du tout, et c’est normal. Avec
dsync, chaque écriture de 4K se termine par un vidage du cache, qui se vide donc aussi vite qu’il se remplit. Pour les charges riches en écritures synchrones (bases de données, NFS en sync, VM), la réponse n’est pas le cache du disque. C’est un périphérique de journal séparé pour ZFS (SLOG) ou des SSD avec protection contre les coupures de courant. Le cache d’écriture n’a rien de magique. Il empêche simplement le disque de faire chaque écriture de la manière la plus pénible possible. - Par rapport à l’article d’origine (138 Mo/s avec tampon, 15,4 Mo/s en O_DIRECT), les chiffres sans cache sont encore pires aujourd’hui. Je soupçonne que c’est le deuxième problème de cet article qui joue : à l’époque, les disques étaient neufs, cette fois ils étaient pleins d’anciennes données BitLocker et le TRIM n’avait pas encore tourné. Deux choses manquaient, et chacune aggrave l’autre.
🔙 Le moment où je relis mon propre blog
Voici la partie un peu gênante. Ce sont les trois mêmes SSD dans la même machine, sur lesquels j’ai déjà écrit deux fois. Les deux fois, les chiffres me disaient exactement ça, et les deux fois j’ai trouvé une explication plausible et je suis passé à autre chose.
Premier raté : Building a RAIDZ1 NAS on Debian 13 with OpenZFS. J’avais mesuré 138 Mo/s en écriture avec tampon et 15,4 Mo/s en O_DIRECT, soit environ neuf fois plus lent. J’avais même écrit que cela « m’avait suffisamment surpris pour le vérifier deux ou trois fois ». Puis je l’avais expliqué par le regroupement en groupes de transactions de ZFS : les écritures avec tampon sont fusionnées en écritures de bandes complètes, O_DIRECT contourne ce mécanisme. Cette partie est vraie. Mais l’explication était trop confortable. Avec le cache du disque désactivé, chaque écriture non regroupée doit attendre la flash elle-même, et c’est ce qui transforme « un peu plus lent » en « neuf fois plus lent ». Même le « bon » chiffre méritait un second regard : 138 Mo/s sur trois SSD SATA, ce n’est pas brillant.
Deuxième raté : Enough YAML for Now, côté Windows. Parité Storage Spaces sur les mêmes disques : 88 Mio/s en écriture séquentielle, 461 IOPS en écriture aléatoire et une latence au 99e centile de plus d’une seconde. J’avais accusé la parité : « Les lectures sont excellentes. Les écritures, c’est… la parité. » Le coût lecture-modification-écriture de la parité est bien réel. Mais j’avais aussi lancé DiskSpd avec -Sh, qui désactive volontairement le cache d’écriture du disque pendant le test. Le benchmark mesurait « sans cache d’écriture » par conception, et c’était justement ainsi que le serveur tournait au quotidien de toute façon. Le pire cas et la réalité de tous les jours étaient identiques, et je ne me suis jamais demandé pourquoi.
Deux systèmes d’exploitation, deux benchmarks, deux explications qui semblaient raisonnables, un réglage que personne n’a vérifié. La leçon n’est pas « les benchmarks mentent ». C’est que j’ai comparé les chiffres à mes attentes envers le logiciel et jamais à la fiche technique du matériel. 15 Mo/s en écriture sur un SSD auraient dû être un signal d’alarme, quel que soit le système de fichiers au-dessus.
🛡️ Est-ce sûr de l’activer ?
C’est la question évidente : si HPE le désactive, il y a peut-être une raison.
Il y a une raison, et elle ne s’applique en grande partie pas ici. Le cache du disque est de la RAM volatile. Si le courant est coupé, tout ce qui s’y trouve et n’est pas encore en flash est perdu. Les SSD d’entreprise ont des condensateurs pour cela (« power-loss protection »), les SSD grand public et NAS n’en ont généralement pas. En plus, un serveur HPE classique utilise un contrôleur RAID Smart Array avec son propre cache protégé par batterie. Dans cette architecture, le cache du disque est au mieux superflu et au pire un risque, le désactiver est donc le choix prudent. Pour un constructeur qui ne sait pas quel système, quel système de fichiers ni quel contrôleur vous utiliserez, « désactivé » est la valeur par défaut sûre.
Sur un système de fichiers moderne, un cache d’écriture est sûr, car le système de fichiers indique au disque quand les données doivent se trouver sur un support stable. À chaque moment important, ZFS, ext4 et NTFS envoient un vidage du cache et ne considèrent rien comme validé tant que le disque ne l’a pas confirmé. ZFS fonctionne en plus en copie sur écriture, donc après un plantage on a soit le dernier état cohérent, soit le nouveau, jamais un mélange des deux. Le seul vrai danger, c’est un disque qui confirme des vidages qu’il n’a jamais effectués (firmware bon marché et douteux), ou, sous Windows, la case « Désactiver le vidage du tampon d’écriture du cache Windows sur le périphérique ». Cette case-là, c’est vraiment la case « j’aime vivre dangereusement ».
Et dans mon cas, les trois serveurs HP sont de toute façon derrière un onduleur. Ce qui reste sur ma liste, c’est de faire en sorte que HP3 s’arrête proprement quand la batterie faiblit (NUT). Un onduleur qui se vide pendant que le serveur continue d’écrire ne fait que retarder la coupure.
💾 SSD, disques durs et le PC sous votre bureau
- Les SSD souffrent le plus. La flash s’écrit par pages et s’efface par blocs. Sans cache, le disque ne peut pas regrouper les petites écritures, chacune coûte donc plus de temps et plus d’usure. C’est comme ça qu’on arrive à 7,5 Mo/s.
- Les disques durs y perdent aussi, surtout en écriture aléatoire, car le disque ne peut plus réordonner les requêtes pour minimiser les mouvements de la tête. L’écriture séquentielle souffre moins.
- Les PC de bureau ordinaires sont presque toujours épargnés. Les BIOS grand public ne touchent pas à ce réglage, et Windows laisse « Activer le cache d’écriture sur le périphérique » activé pour les disques internes. Mon hôte de rebond, une carte mère de bureau ordinaire, affiche
write backpour son disque dur de 8 To comme pour son SSD NVMe. Le NVMe a lui aussi un cache d’écriture volatile, contrôlé par le système et activé par défaut. - Les disques USB sous Windows sont l’exception que vous avez sans doute déjà ressentie. Ils sont réglés par défaut sur « Suppression rapide », où Windows renonce de son côté à la mise en cache en écriture différée pour que vous puissiez retirer la clé sans l’éjecter. C’est l’une des raisons pour lesquelles les grosses copies vers une clé USB paraissent souvent plus lentes sous Windows que sous Linux.
Vérifiez par vous-même :
# Linux
cat /sys/block/*/queue/write_cache
dmesg | grep -i "write cache"
hdparm -W /dev/sdX # SATA
# Windows (PowerShell)
Get-PhysicalDisk | Get-StorageAdvancedProperty # IsDeviceCacheEnabled, IsPowerProtected🔧 Pour que ça tienne
hdparm -W1 est volatile : le disque le réinitialise au prochain cycle d’alimentation, et le firmware le désactive à nouveau à chaque démarrage. La correction doit donc elle aussi s’appliquer à chaque démarrage. Pour l’instant, c’est une règle udev :
# /etc/udev/rules.d/69-ssd-write-cache.rules
# HPE firmware disables the SATA SSD write cache at boot (write through).
# ZFS and ext4 issue cache flushes, so enabling it is safe.
ACTION=="add|change", KERNEL=="sd[a-z]", SUBSYSTEM=="block", ENV{ID_BUS}=="ata", \
ATTR{queue/rotational}=="0", RUN+="/usr/sbin/hdparm -W1 /dev/%k"Elle ne concerne que les disques ATA internes non rotatifs, le SSD système en profite donc aussi et les périphériques USB ne sont pas touchés.
Le BIOS ne serait-il pas un meilleur endroit ? En théorie, oui : un réglage du firmware s’applique avant le chargement de tout système, survit à une réinstallation et couvre aussi les installateurs et les systèmes de secours. J’ai donc redémarré dans le RBSU (F9) et cherché. Sous System Configuration → BIOS/Platform Configuration → Storage Options → SATA Controller Options, le MicroServer Gen10 Plus v2 propose exactement trois entrées :
- Embedded SATA Configuration : SATA AHCI Support
- SATA Secure Erase
- SATA Sanitize
C’est tout. Pas de « Drive Write Cache », rien non plus dans les options de performance. En mode AHCI, le firmware désactive le cache et ne vous laisse aucun moyen de le changer. (Les contrôleurs Smart Array ont bien une « Physical Drive Write Cache Policy », mais passer cette machine en mode RAID pour accéder à ce réglage cacherait les disques à Linux et emporterait le pool ZFS avec eux. Hors de question.) La règle udev n’est donc pas une ceinture de sécurité à côté de la vraie solution. Elle est la solution, appliquée par le système à chaque démarrage, parce que rien d’autre ne le fera.
Cela signifie aussi qu’elle doit faire partie de l’installation, et non d’une liste de choses à ne pas oublier après coup. Si la prochaine réinstallation oublie ce seul fichier, on revient à 7,5 Mo/s, et probablement à un nouvel article de blog.
Les deux autres serveurs HP ont très certainement le même réglage par défaut. Ce sera leur tour une fois que j’aurai décidé de leur sort.
🎯 À retenir
J’ai écrit deux articles remplis de benchmarks soigneux : données compressibles contre incompressibles, ARC contre cache de pages, fichiers de test remplis de zéros de DiskSpd. C’étaient de bonnes leçons, et toutes parlaient du logiciel qui me mentait. Pendant ce temps, le matériel était parfaitement honnête : un mot dans sysfs, une ligne dans dmesg, et une leçon sur TRIM que j’avais déjà apprise une fois après l’installation sous BitLocker et aussitôt oubliée. Je n’ai jamais regardé.
La prochaine fois qu’un chiffre me paraît bizarre, la première question ne sera pas « comment mon système de fichiers l’explique-t-il ? » mais « qu’est-ce que ce matériel est censé faire ? ». Un SSD SATA à 15 Mo/s n’est pas une curiosité intéressante du système de fichiers. C’est un réglage, ou un TRIM manquant, ou dans mon cas les deux. 🔍💾
Ma liste de contrôle pour réutiliser des SSD dans un serveur, désormais :
- D’abord libérer.
blkdiscardsur chaque SSD d’occasion avant de créer le pool (ou SATA Secure Erase / Sanitize dans le BIOS), surtout si BitLocker ou un autre chiffrement intégral y était actif. - Livrer la règle udev avec l’installation sur les machines HPE en mode AHCI. Le BIOS ne le fera pas pour vous.
- Vérifier le cache d’écriture.
dmesg | grep -i "write cache"et/sys/block/*/queue/write_cache. On doit lire « write back ». - Comparer à la fiche technique, pas à ses attentes envers le système de fichiers.
- Ensuite seulement, faire des benchmarks, avec des données incompressibles, sur un pool au repos.
📚 Dans la même série : le NAS RAIDZ1 (en anglais)
- Building a RAIDZ1 NAS on Debian 13 with OpenZFS: Datasets, Compression, and the Lies dd Told Me
- RAIDZ1 NAS Addendum: How Scrub and Trim Actually Get Scheduled — and the Alert That Wasn’t
- Everybody Smile — We’re Taking a Snapshot! Moving From rdiff-backup to ZFS on the RAIDZ1 NAS
- Second Addendum: ZED Watches My Pool’s Health, Not Its Waistline






