ZFS zpool split : Cloner un pool miroir pour migration ou PRA

Cet article vous a aidé ?

Il existe deux types de migrations : celles que vous planifiez, et celles que votre stockage vous impose à 2h du matin après une mise à jour du firmware « mineure ». Si vous utilisez des pools ZFS en miroir, zpool split est l’un des rares outils qui peut transformer une migration en une opération contrôlée et majoritairement ennuyeuse : vous détachez littéralement un côté de vos miroirs et repartez avec un second pool.

Ce n’est pas un conte de fées marketing de « clonage instantané ». Séparer un pool est une décision lourde : vous changez la posture de redondance, vous créez une seconde identité pour le stockage, et vous faites des promesses à votre futur vous concernant l’importabilité, les points de montage, les clés de chiffrement et l’état du dernier transaction group (TXG) au moment où vous avez déclenché l’opération. Bien fait, c’est une amorce PRA propre ou un démarrage rapide pour une migration. Fait à la légère, c’est un aller simple vers « pourquoi la production a monté la copie PRA et a commencé à écrire dessus ? ».

Ce que zpool split est vraiment (et n’est pas)

zpool split prend un pool qui contient des vdevs en miroir et crée un nouveau pool en séparant les membres des miroirs. Conceptuellement : chaque vdev miroir est une paire (ou plus) de disques ; split vous permet de détacher un disque de chaque miroir pour former un nouveau pool avec la même structure de datasets et les mêmes métadonnées. Ce n’est pas une copie de blocs ; c’est une réaffectation de la propriété des disques existants.

C’est pour cela que c’est rapide. Cela explique aussi la première règle du split : vous n’obtenez un « pool complet » que si vous avez suffisamment de miroirs pour donner un membre de chaque vdev miroir. Si votre pool est un seul vdev miroir de deux disques, un split peut quand même créer un nouveau pool — mais vous transformez en pratique un disque en pool mono-disque. Cela peut être acceptable pour un staging de migration temporaire, et inacceptable pour un usage auquel vous tiendriez pendant le long terme.

Ce pour quoi c’est efficace

  • Staging de migration : Split, expédiez les disques (ou déplacez-les dans un nouveau châssis), importez, et vous avez transféré l’identité du pool sans transfert réseau.
  • Création d’un seed PRA : Split pour créer rapidement un pool PRA initial, puis utilisez des zfs send incrémentaux pour le maintenir à jour.
  • Duplication d’environnement rapide : Cloner un arbre de datasets de production pour un job d’analyse ponctuel, puis détruire le pool split ensuite.

Ce que ce n’est pas

  • Ce n’est pas une sauvegarde. Si vos données sont corrompues, vous obtiendrez volontiers deux copies de la corruption.
  • Ce n’est pas un mécanisme de snapshot. Le pool split reflète l’état du pool à la frontière de TXG au moment du split, pas un snapshot de dataset que vous pouvez parcourir.
  • Ce n’est pas un substitut à une stratégie de réplication. C’est un outil de la boîte, pas la boîte entière.

Blague n°1 : Splitter un pool miroir, c’est comme photocopier la clé de votre maison en la sciant en deux — vous aurez bien deux clés, mais votre serrure risque d’avoir son avis.

Faits & contexte historique (le « pourquoi » du bouton)

ZFS a une longue mémoire, comme les ingénieurs qui ont construit des workflows opérationnels autour de lui. Voici des faits et points de contexte qui expliquent pourquoi zpool split existe et comment il a fini dans des runbooks réels :

  1. ZFS a été conçu autour du stockage en pool, pas de périphériques par système de fichiers. C’est pourquoi des opérations comme split agissent sur la topologie du pool, pas sur « un système de fichiers » comme le faisaient des outils plus anciens.
  2. Les miroirs ont toujours été les vdev « opérationnellement amicaux ». En production, les miroirs sont populaires car ils se réparent rapidement, se dégradent de façon prévisible et tolèrent mieux le remplacement de disques hétérogènes que les vdevs parité.
  3. Le format sur disque est portable entre systèmes partageant les mêmes feature flags. Importer un pool sur un autre hôte est normal, mais uniquement si les feature flags s’alignent et que l’OS les prend en charge.
  4. Split est une transformation de topologie, pas un déplacement de données. C’est pourquoi c’est instantané comparé à zfs send, et aussi pourquoi cela change immédiatement votre redondance.
  5. Historiquement, les migrations « sneakernet » étaient courantes. Avant que le 10/25/40/100GbE bon marché ne soit omniprésent (et avant qu’on lui fasse confiance à 95% d’utilisation pendant 12 heures), déplacer des disques était une voie de migration légitime.
  6. Les checksums de ZFS ont rendu « déplacer les disques » plus sûr que les anciens systèmes de fichiers. Lors de l’import à l’autre bout, vous disposez d’une vérification bout en bout via scrub et checksums par bloc.
  7. Les GUIDs de pool et les chemins de périphériques sont volontairement abstraits. ZFS suit les GUIDs des vdevs ; les noms de périphériques de l’OS peuvent changer et le pool peut toujours s’importer — si vous aviez utilisé des chemins stables by-id dès le départ.
  8. Les feature flags ont transformé « ça s’importe partout » en « ça s’importe où il faut ». Activer des fonctionnalités plus récentes peut empêcher l’import sur des plateformes plus anciennes ; split ne change pas cela, mais vous force à l’affronter.
  9. Les environnements de boot et le root-on-ZFS rendent le split plus intéressant. Splitter un pool contenant l’OS est possible, mais vous entrez alors dans le domaine de la compatibilité du bootloader et des host IDs.

Quand utiliser split vs send/receive vs réplication

Si vous avez un pool en miroir et un accès physique aux disques, split est le moyen le plus rapide de créer un second pool avec le même arbre de datasets. Mais « rapide » n’est pas synonyme de « meilleur ». Voici comment je décide.

Utilisez zpool split lorsque

  • Vous avez des vdevs en miroir et pouvez prêter temporairement un côté.
  • Vous avez besoin d’un seed PRA rapide et votre fenêtre de réplication réseau est inacceptable.
  • Vous souhaitez migrer un gros pool vers du nouveau matériel sans saturer les liens pendant des jours.
  • Vous pouvez tolérer une réduction temporaire de la redondance sur la source (car après le split, la source a moins de membres du miroir).

Préférez zfs send | zfs receive lorsque

  • Vous avez besoin de sémantique point-in-time : snapshots, incrémentaux, options de rollback.
  • Vous ne pouvez pas réduire la redondance en production, même brièvement.
  • Vos vdevs ne sont pas des miroirs (RAIDZ ne peut pas être split de cette manière).
  • Vous devez transformer des propriétés lors de la migration (recordsize, chiffrement, layout des datasets), et souhaitez un contrôle délibéré.

Préférez une vraie réplication lorsque

  • Vous avez besoin d’un PRA continu et audité avec des objectifs RPO et RTO.
  • Vous devez conserver des points historiques (politiques de rétention de snapshots).
  • Vous avez plusieurs cibles en aval ou devez répliquer à travers des frontières de confiance.

Blague n°2 : Le transfert de données le plus rapide reste un humain portant des disques — jusqu’à ce que quelqu’un les mette dans un sac à dos avec un aimant, et là vous avez inventé de l’art performance.

Précontrôle : que confirmer avant de splitter

Splitter un pool est facile. Splitter un pool et être confiant sur ce qui arrive ensuite est là où les adultes gagnent leur café.

Confirmer la topologie : uniquement des miroirs

Vous avez besoin de vdevs en miroir. Si votre pool inclut des vdevs RAIDZ, zpool split ne fera pas ce que vous attendez. Les pools à topologie mixte sont courants dans les environnements « on a grandi au fil du temps » — confirmez ce que vous avez réellement.

Confirmer les feature flags et le support OS cible

Si vous splittez un pool sur un hôte avec des fonctionnalités ZFS plus récentes activées, puis tentez d’importer sur un appliance plus ancien, vous pouvez obtenir un refus d’import. C’est le mode d’échec n°1 « ça a marché en labo » que j’ai vu en migrations d’entreprise.

Confirmer la gestion des clés de chiffrement

Le chiffrement natif ZFS (au niveau des datasets) se déplace avec les données sur disque. Le pool split contiendra des datasets chiffrés ; importer n’est pas équivalent à monter. Assurez-vous que l’hôte destinataire a accès aux clés et que vous savez si les clés se chargent automatiquement ou manuellement.

Confirmer que vous avez des ID de périphérique stables

Sur Linux, /dev/sdX est une suggestion, pas un contrat. Utilisez /dev/disk/by-id pour plus de sécurité. Sur la destination, l’énumération des périphériques sera différente ; ZFS peut généralement les retrouver, mais votre temps de dépannage explose si vous ne pouvez pas mapper « ce numéro de série » à « ce membre de vdev ».

Confirmer la stratégie de points de montage

Après le split et l’import, les datasets peuvent se monter automatiquement. C’est acceptable jusqu’au moment où ils montent sur le mauvais hôte avec de mauvais chemins, et soudainement vous avez deux serveurs écrivant sur des copies différentes en pensant être autoritaires. Planifiez votre stratégie de points de montage et la posture canmount avant d’importer.

Tâches pratiques : commandes et comment lire la sortie

Les tâches suivantes sont écrites comme si vous êtes sur un hôte Linux avec OpenZFS. Ajustez les noms de services et les chemins pour votre plateforme. Chaque tâche est quelque chose que j’ai soit exécutée en conditions réelles, soit souhaitée avoir exécutée avant que le pager ne se présente.

Tâche 1 : Inventorier le pool et confirmer les miroirs

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank                         ONLINE       0     0     0
          mirror-0                   ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_AAA  ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_BBB  ONLINE       0     0     0
          mirror-1                   ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_CCC  ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_DDD  ONLINE       0     0     0

errors: No known data errors

Interprétation : Vous voulez que chaque vdev de haut niveau soit mirror-N. Si vous voyez raidz ou des disques uniques, le split sera partiel ou impossible. Vérifiez aussi les erreurs existantes ; splitter un miroir dégradé crée un nouveau pool qui peut être « né malade ».

Tâche 2 : Vérifier la pression I/O actuelle avant toute action perturbatrice

cr0x@server:~$ iostat -x 2 3
Linux 6.8.0 (server)  12/25/2025  _x86_64_ (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           6.12    0.00    1.88    0.74    0.00   91.26

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
nvme0n1          5.0    40.0   640.0  5120.0   2.10   0.15   0.70

Interprétation : Un split est rapide, mais le risque opérationnel vient de ce que vous faites autour (scrubs, exports, imports). Si le pool est déjà saturé (%util proche de 100% et await élevé), planifiez une fenêtre plus calme.

Tâche 3 : Confirmer les feature flags et la posture de compatibilité

cr0x@server:~$ sudo zpool get all tank | egrep 'feature@|compatibility|version'
tank  compatibility  -          default
tank  feature@async_destroy  enabled  local
tank  feature@bookmarks      enabled  local
tank  feature@encryption     enabled  local
tank  feature@edonr          enabled  local

Interprétation : Le pool split héritera de ces features. Si l’hôte de destination ne les supporte pas, l’import peut échouer. Traitez « feature enabled » comme une exigence stricte pour la pile destination.

Tâche 4 : Capturer la liste des datasets et les propriétés critiques (mountpoints, canmount)

cr0x@server:~$ sudo zfs list -r -o name,used,avail,mountpoint,canmount,encryption,keylocation tank
NAME             USED  AVAIL  MOUNTPOINT     CANMOUNT  ENCRYPTION  KEYLOCATION
tank             220G   700G  /tank          on        off         -
tank/apps         80G   700G  /tank/apps     on        aes-256-gcm file:///root/keys/apps.key
tank/home         40G   700G  /tank/home     on        off         -
tank/vm          100G   700G  /tank/vm       on        aes-256-gcm prompt

Interprétation : C’est votre carte « ce qui sera monté où ». Sur un hôte PRA, vous pouvez vouloir canmount=off jusqu’à ce que vous soyez prêt. Notez aussi keylocation et si les clés sont sur fichier ou via prompt.

Tâche 5 : Créer un jeu de snapshots de sécurité (optionnel mais conseillé)

cr0x@server:~$ sudo zfs snapshot -r tank@pre-split-2025-12-25
cr0x@server:~$ sudo zfs list -t snapshot -r tank | tail -5
tank/apps@pre-split-2025-12-25  0B  -
tank/home@pre-split-2025-12-25  0B  -
tank/vm@pre-split-2025-12-25    0B  -

Interprétation : Un split ne requiert pas de snapshots, mais ceux-ci vous donnent un rollback et des options send/receive si le plan « déplacer les disques » tourne mal. C’est une assurance peu coûteuse.

Tâche 6 : Quieter les écrivains risqués (bases de données, images VM) et vérifier

cr0x@server:~$ sudo systemctl stop postgresql
cr0x@server:~$ sudo systemctl stop libvirtd
cr0x@server:~$ sudo lsof +D /tank/vm | head
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

Interprétation : Pour une migration/seed PRA vous voulez au minimum une consistance crash-consistent ; pour des bases de données vous voulez une consistance applicative si possible. Si lsof montre encore des fichiers ouverts sous des datasets critiques, vous n’êtes pas quiescé.

Tâche 7 : Faire un contrôle santé rapide et considérer un calendrier de scrub

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 00:21:33 with 0 errors on Sun Dec 22 02:14:01 2025
config:
...
errors: No known data errors

Interprétation : Si le dernier scrub est ancien ou des erreurs existent, corrigez cela d’abord. Splitter un pool n’est pas le moment pour découvrir qu’un membre de miroir lançait silencieusement des erreurs de checksum.

Tâche 8 : Effectuer le split pour créer un nouveau nom de pool

cr0x@server:~$ sudo zpool split tank tank_dr
cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank                         ONLINE       0     0     0
          mirror-0                   ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_AAA  ONLINE       0     0     0
          mirror-1                   ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_CCC  ONLINE       0     0     0

errors: No known data errors

cr0x@server:~$ sudo zpool status -v tank_dr
  pool: tank_dr
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank_dr                      ONLINE       0     0     0
          ata-SAMSUNG_SSD_1TB_BBB    ONLINE       0     0     0
          ata-SAMSUNG_SSD_1TB_DDD    ONLINE       0     0     0

errors: No known data errors

Interprétation : Sur beaucoup de configurations, le nouveau pool est créé à partir du « côté opposé » de chaque miroir. Notez que tank_dr ici est maintenant indiqué comme ayant des vdevs de haut niveau mono-disques (pas des miroirs) parce que chaque miroir a fourni un disque. C’est la partie que l’on oublie souvent : vous échangez souvent de la redondance contre de la portabilité. Si vous voulez que le pool split soit lui aussi en miroir, vous aurez besoin de disques supplémentaires à attacher plus tard sur la destination.

Tâche 9 : Ajuster immédiatement la posture d’auto-montage sur le pool split (recommandé)

cr0x@server:~$ sudo zfs set canmount=off tank_dr
cr0x@server:~$ sudo zfs set mountpoint=/tank_dr tank_dr
cr0x@server:~$ sudo zfs list -o name,mountpoint,canmount tank_dr
NAME     MOUNTPOINT  CANMOUNT
tank_dr  /tank_dr    off

Interprétation : Cela empêche des montages accidentels sur l’hôte source (ou sur un hôte destination qui importe automatiquement). Vous pouvez réactiver les montages par dataset plus tard.

Tâche 10 : Exporter le pool split pour le déplacement physique

cr0x@server:~$ sudo zpool export tank_dr
cr0x@server:~$ sudo zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  1.81T   220G  1.60T        -         -     3%    11%  1.00x  ONLINE  -

Interprétation : Exportez proprement pour que l’import sur la destination ne ressemble pas à un « pool volé » depuis un hôte encore vivant. Cela réduit les frictions d’import et prévient les conflits d’imports multiples accidentels.

Tâche 11 : Sur la destination, localiser les disques par ID stable et importer en lecture seule d’abord

cr0x@drhost:~$ sudo ls -l /dev/disk/by-id/ | egrep 'SAMSUNG_SSD_1TB_(BBB|DDD)'
lrwxrwxrwx 1 root root  9 Dec 25 09:02 ata-SAMSUNG_SSD_1TB_BBB -> ../../sdb
lrwxrwxrwx 1 root root  9 Dec 25 09:02 ata-SAMSUNG_SSD_1TB_DDD -> ../../sdc

cr0x@drhost:~$ sudo zpool import
   pool: tank_dr
     id: 15277416958755799222
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        tank_dr                    ONLINE
          ata-SAMSUNG_SSD_1TB_BBB  ONLINE
          ata-SAMSUNG_SSD_1TB_DDD  ONLINE

cr0x@drhost:~$ sudo zpool import -o readonly=on -o cachefile=none tank_dr
cr0x@drhost:~$ sudo zpool get readonly tank_dr
NAME     PROPERTY  VALUE     SOURCE
tank_dr  readonly  on        local

Interprétation : L’import en lecture seule est un excellent premier atterrissage. Il vous permet d’inspecter les datasets, valider la structure et confirmer que vous n’avez pas apporté les mauvais disques — sans changer l’état sur disque.

Tâche 12 : Charger les clés de chiffrement et monter de façon délibérée

cr0x@drhost:~$ sudo zfs load-key -r tank_dr/apps
Enter passphrase for 'tank_dr/apps':
cr0x@drhost:~$ sudo zfs mount -a
cannot mount 'tank_dr': legacy mountpoint, use mount(8)

cr0x@drhost:~$ sudo zfs get -o name,property,value tank_dr | egrep 'mountpoint|canmount'
tank_dr  mountpoint  /tank_dr
tank_dr  canmount    off

Interprétation : Si vous avez mis canmount=off, le montage global ne montera pas le dataset racine. C’est intentionnel. Montez les datasets enfants spécifiques dont vous avez besoin, après le chargement des clés et après avoir confirmé que les points de montage ne vont pas entrer en collision avec des chemins locaux.

Tâche 13 : Convertir le pool split en miroirs sur la destination (attacher de nouveaux disques)

cr0x@drhost:~$ sudo zpool status tank_dr
  pool: tank_dr
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank_dr                      ONLINE       0     0     0
          ata-SAMSUNG_SSD_1TB_BBB    ONLINE       0     0     0
          ata-SAMSUNG_SSD_1TB_DDD    ONLINE       0     0     0

errors: No known data errors

cr0x@drhost:~$ sudo zpool attach tank_dr ata-SAMSUNG_SSD_1TB_BBB /dev/disk/by-id/ata-SAMSUNG_SSD_1TB_EEE
cr0x@drhost:~$ sudo zpool attach tank_dr ata-SAMSUNG_SSD_1TB_DDD /dev/disk/by-id/ata-SAMSUNG_SSD_1TB_FFF
cr0x@drhost:~$ sudo zpool status tank_dr
  pool: tank_dr
 state: ONLINE
  scan: resilver in progress since Thu Dec 25 09:24:11 2025
        52.1G scanned at 1.20G/s, 12.4G issued at 290M/s, 220G total
        12.4G resilvered, 5.64% done, 00:12:31 to go
config:

        NAME                              STATE     READ WRITE CKSUM
        tank_dr                           ONLINE       0     0     0
          mirror-0                        ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_BBB       ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_EEE       ONLINE       0     0     0
          mirror-1                        ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_DDD       ONLINE       0     0     0
            ata-SAMSUNG_SSD_1TB_FFF       ONLINE       0     0     0

Interprétation : C’est ainsi que vous restaurez la redondance après avoir expédié un pool split en mono-disques par vdev. Les débits de resilver dépendent de ashift, recordsize, du comportement des disques et de la charge. Planifiez le temps en conséquence.

Tâche 14 : Rendre le pool écrivable et définir cachefile pour la persistance

cr0x@drhost:~$ sudo zpool export tank_dr
cr0x@drhost:~$ sudo zpool import -o readonly=off tank_dr
cr0x@drhost:~$ sudo zpool set cachefile=/etc/zfs/zpool.cache tank_dr
cr0x@drhost:~$ sudo zpool get cachefile tank_dr
NAME     PROPERTY  VALUE                 SOURCE
tank_dr  cachefile /etc/zfs/zpool.cache  local

Interprétation : L’import en lecture seule servait à valider ; maintenant vous passez en mode opérationnel normal. Définir cachefile garantit que le pool est reconnu au reboot (dépend de la plateforme).

Tâche 15 : Valider l’intégrité des données par un scrub après l’import

cr0x@drhost:~$ sudo zpool scrub tank_dr
cr0x@drhost:~$ sudo zpool status tank_dr
  pool: tank_dr
 state: ONLINE
  scan: scrub in progress since Thu Dec 25 10:02:18 2025
        88.3G scanned at 1.10G/s, 88.3G issued at 1.10G/s, 220G total
        0B repaired, 40.15% done, 00:01:52 to go
config:
...
errors: No known data errors

Interprétation : Un scrub après la relocalisation est la pratique mature. Il détecte les problèmes de transport, les câbles défectueux, les HBAs marginaux, et « ce disque qui ne meurt que quand il fait froid ».

Listes de vérification / plan étape par étape

Checklist A : Seed PRA via split (downtime minimal, surprises minimales)

  1. Confirmer que le pool est uniquement en miroirs : zpool status.
  2. Confirmer que le dernier scrub est propre et assez récent pour votre appétit de risque.
  3. Enregistrer les propriétés des datasets : mountpoints, canmount, état du chiffrement.
  4. Créer des snapshots récursifs comme filet de secours et pour futurs incrémentaux.
  5. Quieter les applications à forte churn si vous avez besoin de cohérence applicative.
  6. Exécuter zpool split pour créer tank_dr.
  7. Définir canmount=off et/ou ajuster les mountpoints sur tank_dr pour éviter des montages accidentels.
  8. Exporter tank_dr.
  9. Déplacer les disques, importer en lecture seule sur la destination, confirmer datasets et propriétés.
  10. Charger les clés de chiffrement et monter sélectivement.
  11. Ajouter de nouveaux disques et attacher pour re-mirrorer, laisser le resilver se terminer.
  12. Scrubber, puis passer à la réplication (sends incrémentaux) pour la suite.

Checklist B : Migration vers un nouvel hôte (garder les noms de services et chemins cohérents)

  1. Décider du moment de bascule autoritaire : quand la destination devient-elle écrivable ?
  2. Avant le split : définir canmount=off sur les datasets critiques si vous voulez un montage manuel après import.
  3. Splitter et exporter le nouveau pool.
  4. Sur le nouvel hôte : importer avec -o altroot=/mnt pour inspection si vous voulez zéro risque de montage dans des chemins de production.
  5. Valider : zfs list, zpool status, vérifier que les clés de chiffrement se chargent.
  6. Quand prêt : exporter/importer normalement, définir les mountpoints corrects, activer les montages.
  7. Démarrer les services et valider la santé au niveau applicatif.

Trois mini-récits du monde réel en entreprise (échecs et le cas qui a sauvé la journée)

1) Incident causé par une mauvaise hypothèse : « Le pool split est une sauvegarde »

Dans une entreprise de taille moyenne avec un backend ZFS fortement miroir, une équipe a créé un seed PRA en splittant un pool de production et en expédiant les disques vers un second site. Ils ont correctement fait la mécanique : split, export, import, montage. Ils étaient confiants. Trop confiants.

Deux mois plus tard, un développeur a poussé une migration de schéma qui a supprimé un ensemble de tables d’une manière que l’application n’a pas détectée immédiatement. Le dommage était silencieux : les écritures continuaient, et le monitoring observait les taux de requêtes, pas la correction des données. Quand le problème a été découvert, l’équipe s’est tourné vers « la copie PRA ». Elle contenait les mêmes données manquantes. Bien sûr : ils ne faisaient pas de réplication basée sur snapshots avec rétention ; ils avaient juste créé une seconde copie vivante et re-splitté périodiquement comme « rafraîchissement ».

La mauvaise hypothèse était subtile : « Nous avons un autre pool, donc nous avons la récupération. » Mais la récupération requiert la dimension du temps — l’historique, des points dans le temps, la rétention — et le pool split n’en avait aucun. C’était un clone, pas une sauvegarde.

La correction opérationnelle fut simple mais douloureuse : ils ont mis en place des snapshots disciplinés (avec nommage et rétention), puis de la réplication incrémentale. Ils utilisent encore split pour amorcer rapidement du stockage PRA, mais seulement comme première étape d’un pipeline PRA réel.

La correction culturelle fut le gain le plus important : ils ont arrêté d’appeler le pool split « sauvegarde » dans les tickets et les tableaux de bord. Les mots comptent. Si vous le nommez « sauvegarde », quelqu’un finira par miser l’entreprise dessus.

2) Optimisation qui a mal tourné : « Splittons en heure de pointe ; c’est instantané »

Une autre organisation avait un pool miroir soutenant un cluster de virtualisation. Quelqu’un a proposé un plan malin : faire le split pendant les heures ouvrables parce que le split est instantané, puis exporter et déplacer les disques après la fenêtre de changement du soir. Cela semblait efficace. La première moitié était vraie. La seconde moitié fut celle où la réalité a présenté la facture.

Splitter le pool réduisait immédiatement le nombre de membres de miroir en production. Le pool est resté ONLINE, mais le profil de performance a changé. Quelques charges de travail qui bénéficiaient d’un « parallélisme de lecture accidentel » depuis les miroirs (et d’une certaine chaleur de cache) se sont retrouvées à se disputer davantage les IOPS. La latence a augmenté, pas de façon catastrophique, mais suffisamment pour déclencher des timeouts dans un service interne bavard. Le service a vacillé, les retries ont explosé, et l’effet amplificateur de charge a transformé une petite augmentation de latence en incident mineur.

Ils ont tiré deux leçons pratiques. Premièrement : dans les systèmes réels, les opérations « instantanées » peuvent avoir des effets de second ordre. Retirer des membres de miroir peut modifier l’ordonnancement et le comportement des files d’attente d’une manière que vos benchs en chemin heureux n’ont jamais exercée. Deuxièmement : les migrations ne sont pas que des opérations stockage ; ce sont des événements de performance. Si votre service est réglé au rasoir, les changements de topologie se ressentent.

La remédiation fut simple : faire le split dans une fenêtre calme, et si vous avez besoin de sûreté en journée, faire un seed via snapshot-based replication à la place. Ils ont aussi ajouté une porte de performance pré-split : si la latence au 95e centile est déjà élevée, aucun changement de topologie n’a lieu.

3) Pratique ennuyeuse mais correcte qui a sauvé la journée : IDs stables et exports disciplinés

Une des migrations basées sur split les plus réussies que j’ai vues était presque agressivement peu intéressante. L’équipe avait une règle : les pools sont construits en utilisant systématiquement les chemins stables /dev/disk/by-id, sans exception. Ils avaient aussi l’habitude d’exporter les pools avant tout déplacement physique — même si « on ne fait que redémarrer pour un firmware ».

Lors d’une migration de datacenter, ils ont splitté un pool miroir en un pool de migration, l’ont exporté et déplacé les disques vers de nouveaux hôtes. Sur la destination, l’énumération des périphériques était différente, les HBAs étaient différents, et quelques disques ont fini sur un backplane différent de celui prévu. Rien de tout cela n’a eu d’importance. zpool import a trouvé le pool via les labels, et le nommage by-id a rendu évident quels numéros de série manquaient lorsqu’un câble n’était pas bien branché.

La pratique ennuyeuse a compté encore quand quelqu’un a essayé d’importer le pool sur un hôte « staging » pour inspecter les données pendant que l’hôte destination était en cours d’installation. Parce que le pool avait été exporté proprement, il n’y a pas eu de confusion « le pool était précédemment en usage », pas d’import forcé, pas de risque que deux systèmes croient posséder le pool en même temps.

Rien de dramatique ne s’est produit, ce qui est précisément le point. En production, « rien de dramatique » est une fonctionnalité que vous gagnez par des habitudes qui semblent pédantes jusqu’à ce qu’elles ne le soient plus.

Méthode de diagnostic rapide (quoi vérifier en premier, deuxième, troisième)

Quand une migration basée sur split est lente ou étrange, vous n’avez pas le temps de philosopher. Voici l’ordre de triage rapide que j’utilise pour trouver le goulot et décider d’arrêter, de continuer ou de revenir en arrière.

Premier : Est-ce un problème de santé ZFS ou un problème OS/matériel ?

cr0x@server:~$ sudo zpool status -x
all pools are healthy

cr0x@server:~$ dmesg | tail -30
[...]
[ 8921.221] ata9.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[ 8921.223] blk_update_request: I/O error, dev sdc, sector 12345678 op 0x0:(READ)

Décision : Si dmesg montre des erreurs/timeouts I/O, arrêtez et stabilisez le matériel avant d’accuser ZFS. ZFS peut survivre à beaucoup de choses, mais il ne peut pas négocier avec un lien SATA qui a son propre art interprétatif.

Second : Un resilver/scrub monopolise-t-il les I/O ?

cr0x@drhost:~$ sudo zpool status tank_dr
  pool: tank_dr
 state: ONLINE
  scan: resilver in progress since Thu Dec 25 09:24:11 2025
        180G scanned, 95G issued, 220G total
        95G resilvered, 43.18% done, 00:08:41 to go

Décision : Si un resilver est actif, les performances sont souvent « conformes à la conception ». Attendez, ou adaptez les attentes. Si le business a besoin de performance tout de suite, envisagez de différer certaines charges jusqu’à la fin du resilver.

Troisième : Êtes-vous CPU-bound, ARC-bound, ou limité par les disques ?

cr0x@drhost:~$ sudo arcstat 2 5
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
09:40:01   812   121     14     0    0    31    4    90   11   42G   64G
09:40:03   905   188     20     0    0    45    5   143   15   42G   64G

Décision : Des taux de miss élevés pendant les tests de migration peuvent donner l’impression que « le stockage est lent » alors qu’il s’agit simplement d’un cache froid. Chauffez les charges ou testez avec des conditions de cache réalistes. Si le CPU est élevé et que vous utilisez chiffrement/compression, vérifiez si vous êtes limité par le CPU.

Quatrième : Les montages et propriétés font-ils quelque chose d’inattendu ?

cr0x@drhost:~$ sudo zfs get -r -o name,property,value canmount,mountpoint tank_dr | head -20
NAME         PROPERTY    VALUE
tank_dr      canmount    off
tank_dr      mountpoint  /tank_dr
tank_dr/apps canmount    on
tank_dr/apps mountpoint  /tank/apps

Décision : Si un dataset enfant pointe toujours vers un point de montage de production (comme /tank/apps), vous pouvez monter par-dessus des répertoires existants sur l’hôte PRA. C’est ainsi que vous finissez par « tester le PRA » en écrasant quelque chose que vous aimiez.

Erreurs courantes (avec symptômes et corrections)

Erreur 1 : Splitter sans réaliser que vous perdez de la redondance

Symptôme : Après le split, le nouveau pool montre des vdevs de haut niveau mono-disques ; l’ancien pool a maintenant moins de membres ; les performances changent ; la posture de risque change.

Correction : Prévoyez de zpool attach des nouveaux disques sur la destination pour restaurer les miroirs, ou acceptez explicitement le risque pour un pool de migration éphémère. Documentez-le dans le ticket de changement ; votre futur vous oubliera.

Erreur 2 : Importer et auto-monter dans des chemins de production

Symptôme : Après import, les datasets se montent sous des chemins qui entrent en collision avec des répertoires existants ; des services commencent à lire/écrire sur la mauvaise copie.

Correction : Importez avec -o altroot=/mnt pour inspection, ou définissez canmount=off avant l’export. N’activez le montage que lorsque vous êtes prêt.

Erreur 3 : Oublier le workflow des clés de chiffrement sur la destination

Symptôme : Le pool s’importe, mais les datasets ne se montent pas ; les applications voient des répertoires vides ; zfs mount échoue avec des erreurs liées aux clés.

Correction : Confirmez zfs get encryption,keylocation,keystatus. Déplacez le matériel de clés de façon sécurisée, testez zfs load-key, et n’assumez pas que « import » équivaut à « utilisable ».

Erreur 4 : Mismatch de feature flags entre source et destination

Symptôme : zpool import refuse avec « unsupported feature(s) » ou similaire.

Correction : Mettez à jour la pile ZFS de la destination pour supporter les feature flags du pool. Si vous devez supporter des systèmes plus anciens, il fallait planifier cela avant d’activer des features sur la source — ZFS ne fait pas de « downgrade ».

Erreur 5 : Utiliser des noms de périphériques instables et perdre la trace des disques

Symptôme : L’import post-mouvement est confus ; vous ne pouvez pas mapper /dev/sdX aux disques réels ; des opérations sur le mauvais disque deviennent probables.

Correction : Construisez et exploitez en utilisant /dev/disk/by-id. Lors du dépannage, utilisez les numéros de série comme vérité terrain.

Erreur 6 : Splitter un pool avec des erreurs existantes ou un miroir dégradé

Symptôme : Le pool split s’importe mais les scrubs montrent des erreurs de checksum ; les resilvers prennent une éternité ; un disque commence à lancer des erreurs I/O.

Correction : Stabilisez d’abord : remplacez les disques défaillants, effacez les erreurs mentionnées dans zpool status -v, lancez un scrub, puis splittez. Si vous devez splitter sous contrainte, importez en lecture seule sur la destination et scrubbez immédiatement pour évaluer les dégâts.

Erreur 7 : Supposer que split vous donne un « point dans le temps » propre à travers les applications

Symptôme : Les bases de données se rétablissent mais avec des transactions récentes manquantes ou incohérentes ; les systèmes de fichiers VM montrent des replays de journal.

Correction : Quiescez les applications ou utilisez des snapshots coordonnés avec des hooks applicatifs. Split capture l’état du pool, pas la cohérence applicative.

FAQ

1) Est-ce que zpool split copie des données ?

Non. Il réaffecte des membres de miroir pour former un nouveau pool. C’est rapide parce que ce n’est pas un déplacement de blocs ; c’est un changement de propriété des disques existants.

2) Puis-je splitter un pool RAIDZ ?

Non, pas dans le sens « cloner le pool ». zpool split est conçu pour les miroirs. Les vdevs RAIDZ n’ont pas de membres indépendants qui peuvent devenir leurs propres vdevs cohérents.

3) Le pool split aura-t-il les mêmes datasets et snapshots ?

Oui : les datasets, propriétés et snapshots présents au moment du split sont inclus car les données sur disque sont les mêmes. Mais souvenez-vous : ce n’est pas une sauvegarde. Si la source avait une corruption logique, vous avez maintenant deux copies de celle-ci.

4) Que devient l’GUID du pool et les noms ?

Le nouveau pool obtient sa propre identité (nouveau nom de pool, GUID de pool distinct). C’est bien : cela réduit la confusion d’un « même pool importé deux fois », mais vous devez toujours faire attention aux points de montage et à l’automatisation hôte.

5) Puis-je importer le pool split sur un autre hôte pendant que l’original tourne encore ?

Oui, c’est souvent l’objectif. Mais vous devez exporter proprement le pool split, et le traiter comme un système séparé : évitez de monter dans des chemins partagés, et assurez-vous qu’aucune application n’écrive sur les deux copies sauf si c’est explicitement conçu (ce qui est rare).

6) Comment maintenir le pool PRA à jour après le seed initial par split ?

Généralement avec des incrémentaux basés sur snapshots : prenez des snapshots sur la source et zfs send/zfs receive vers le pool PRA. Split est idéal pour la première copie ; la réplication est la suite pour le garder à jour.

7) Qu’en est-il du chiffrement natif — le split le « casse »-t-il ?

Non. Les métadonnées de chiffrement font partie des datasets. Mais opérationnellement, vous aurez besoin des clés sur la destination pour monter les datasets chiffrés. Planifiez la distribution des clés et testez le chargement des clés avant de déclarer victoire.

8) Est-il sûr d’exécuter zpool split pendant que le pool est en ligne et utilisé ?

Cela peut se faire en ligne, mais « sûr » dépend de votre charge et de votre tolérance au risque. Le split lui-même est rapide, mais retirer des membres de miroir change la redondance et peut modifier la latence sous charge. Pour les bases de données et images VM, je préfère quiescer ou le faire dans une fenêtre de faible trafic.

9) Puis-je « annuler » un split ?

Pas avec une seule commande magique. Vous pouvez rattacher des disques et re-mirrorer, ou détruire un pool et rattacher ses disques, mais il faut traiter cela comme un changement de topologie avec des conséquences. Si vous avez besoin de réversibilité, envisagez la réplication par snapshots.

10) Pourquoi importer en lecture seule d’abord ?

Parce que c’est la manière la plus sûre de confirmer que vous avez apporté les bons disques et que le pool est sain sans avancer l’état sur disque. C’est un contrôle économique avant d’exposer des services au pool.

Conclusion

zpool split est l’une de ces fonctionnalités ZFS qui donne l’impression de tricher la première fois qu’on l’utilise : clone instantané de pool, pas de copie réseau, pas d’attente. En production, c’est puissant précisément parce que c’est brutal. Vous ne créez pas une « copie » au sens sauvegarde — vous créez un second pool en sacrifiant des membres de miroir, et vous prenez la responsabilité de la redondance, du comportement des montages, de la compatibilité des features et des clés.

Si vous devez retenir trois choses, retenez celles-ci : vérifiez que vous avez des miroirs, importez en lecture seule d’abord, et contrôlez les montages comme si votre week-end en dépendait (parce que c’est le cas). Split est un excellent moyen de démarrer un plan de migration ou de PRA. Le reste du plan — la cadence ennuyeuse des snapshots, la discipline de réplication, les scrubs et audits — est ce qui transforme cette victoire rapide en un système digne de confiance.

← Précédent
Mises à niveau MariaDB vs Percona Server : comment éviter le mensonge « ça marche en staging »
Suivant →
PL1, PL2 et Tau expliqués : les trois chiffres qui décident de tout

Laisser un commentaire