Rétention des snapshots ZFS : la politique qui prévient les bombes d’espace

Cet article vous a aidé ?

Les snapshots ZFS sont une de ces fonctionnalités qui donnent l’impression de tricher — jusqu’à ce qu’ils se transforment silencieusement en bombe d’espace. Ils ne « prennent pas d’espace » lors de leur création (la plupart du temps), ils ne cassent rien quand on les oublie (au début), et ils ne demandent pas d’attention jusqu’à ce que le pool soit à 97 % et que la latence d’écriture se transforme en film d’horreur.

Cet article traite de la rétention des snapshots comme d’une politique opérationnelle, pas d’un débat philosophique. Nous couvrirons le vrai coût des snapshots, pourquoi « gardez-les tous » est un piège, comment les clones et les holds transforment le nettoyage en scène de crime, et comment construire une politique de rétention qui survit à la réalité d’entreprise : équipes multiples, priorités concurrentes et automatisations pleines de confiance mais pauvres en sagesse.

Pourquoi les bombes d’espace arrivent

En production, les explosions d’espace liées aux snapshots ne proviennent presque jamais de ce que vous croyez. On blâme « trop de snapshots », mais le nombre est rarement le problème. Le problème est le taux de changement, la durée de rétention et les ancres cachées qui empêchent la suppression : clones, holds, dépendances de réplication, et snapshots « temporaires » devenus permanents par négligence.

Un snapshot ZFS est une référence point-in-time vers des blocs. Il est bon marché à créer parce qu’il s’agit de métadonnées et de références — jusqu’à ce que le dataset change. Quand des blocs sont écrasés ou supprimés dans le filesystem vivant, le snapshot référence toujours les anciens blocs, donc ZFS doit les garder. Avec le temps, les snapshots deviennent un musée de blocs écrasés. Les musées sont plaisants. Les musées ont aussi besoin de bâtiments.

Il y a deux mensonges opérationnels qui causent la plupart des bombes d’espace :

  • Mensonge n°1 : « Les snapshots sont gratuits. » Ils sont gratuits à prendre, pas gratuits à conserver.
  • Mensonge n°2 : « Si le dataset fait seulement 2 To, il ne peut pas consommer 10 To. » Avec les snapshots, il le peut absolument — parce que les snapshots préservent des versions historiques des blocs.

Une petite blague, pour l’assainissement du palais : Une politique de rétention de snapshots, c’est comme passer la soie dentaire — tout le monde reconnaît que c’est important, et tout le monde suppose que quelqu’un d’autre le fait.

Faits intéressants et contexte historique

Un peu de contexte aide parce que les snapshots ZFS n’ont pas été conçus comme une « fonctionnalité produit de sauvegarde ». Ils ont été conçus comme un primitif du système de fichiers avec des conséquences.

  1. Les snapshots ZFS sont des constructions métadonnées copy-on-write, pas des copies au niveau bloc. La « copie » survient plus tard quand le dataset vivant change.
  2. ZFS est né chez Sun Microsystems au milieu des années 2000 avec l’idée radicale que les systèmes de fichiers devraient gérer volumes et intégrité ensemble.
  3. Les snapshots dans les implémentations LVM traditionnelles avaient souvent des falaises de performance quand ils se remplissaient ; les snapshots ZFS évitent ce mécanisme spécifique mais peuvent toujours causer fragmentation et croissance de métadonnées.
  4. ZFS a introduit send/receive comme primitif de réplication de première classe — les incrémentaux dépendent de la lignée des snapshots, ce qui signifie que la rétention interagit avec la réplication plus que ce que l’on imagine.
  5. L’« espace utilisé par les snapshots » n’est pas un nombre unique ; ZFS le décompose en referenced, logical vs physical, et « used by snapshots », ce qui embrouille autant les tableaux de bord que les humains.
  6. Les clones sont des snapshots modifiables, et ils peuvent bloquer la suppression d’un snapshot, souvent découverts seulement lors du nettoyage à 2 h du matin.
  7. ZFS supporte les holds utilisateur sur les snapshots justement pour empêcher qu’un nettoyage automatisé supprime des points de récupération critiques — un anti-footgun qui peut devenir une foot-anchor.
  8. Recordsize et compression influencent le coût de rétention. Les modèles de changement sur de grands enregistrements peuvent maintenir plus de blocs historiques en vie que vous ne l’imaginez.
  9. La plupart des pools meurent d’être trop pleins, pas d’une panne de disque unique. Une forte utilisation amplifie la contention d’allocation et la fragmentation ; les snapshots sont un accélérateur fréquent.

Le modèle d’espace des snapshots (ce que ZFS compte réellement)

Pour garder la rétention raisonnable, vous devez comprendre ce que ZFS compte — et ce qu’il ne compte pas. ZFS vous donne plusieurs vues différentes de « utilisé » :

Referenced vs used vs logical

Referenced signifie la quantité de données que le dataset (ou le snapshot) représenterait s’il était la seule chose existante. C’est une mesure de contenu, pas de coût.

Used signifie les blocs uniques attribués à ce dataset ou snapshot dans le contexte de tout le reste. Pour les snapshots, cela peut être trompeur : le « used » d’un snapshot est l’espace unique conservé à cause de celui-ci, mais ces blocs peuvent aussi être partagés entre plusieurs snapshots. La vue la plus actionnable en opération est généralement la répartition au niveau du dataset : usedbydataset, usedbysnapshots, usedbychildren, usedbyrefreservation.

Logical peut dépasser le physique à cause de la compression. C’est bien — jusqu’à ce que quelqu’un budgete la capacité avec des chiffres logiques et se retrouve surpris par la réalité physique.

Pourquoi supprimer des fichiers ne libère pas d’espace (quand il y a des snapshots)

Supprimer un fichier enlève ses références dans le dataset vivant. Si un snapshot référence toujours les anciens blocs, ces blocs restent alloués. Depuis la chaise de l’opérateur, on a l’impression que « rm ne marche pas ». Il marche. Vos snapshots font juste du pillage.

Pourquoi « supprimer juste les anciens snapshots » ne libère parfois pas non plus d’espace

Parce qu’il y a deux ancres supplémentaires :

  • Clones : si un clone dépend d’un snapshot, ce snapshot ne peut pas être détruit tant que le clone n’est pas promu ou détruit.
  • Holds : un snapshot peut être retenu par un admin ou une automatisation et refusera la suppression tant que le hold n’est pas relâché.

De plus, même lorsque vous supprimez des snapshots, l’espace peut ne pas réapparaître immédiatement si vous regardez les mauvais indicateurs, ou si vous êtes dans une charge où les métadonnées et les blocs indirects dominent. ZFS est honnête, mais pas toujours immédiatement lisible.

Deuxième petite blague (et dernière, selon les règles) : la comptabilité d’espace ZFS est le seul endroit où « utilisé » peut signifier « peut-être », « ça dépend », et « oui, mais pas de la façon dont vous l’espérez ».

Construire une politique de rétention qui ne vous trahira pas

Une politique de rétention est un contrat entre vos objectifs de récupération et la réalité de capacité. Si vous ne pouvez pas dire ce que vous protégez — suppressions accidentelles, ransomware, mauvais déploiements, corruption silencieuse, erreur d’opérateur base de données — vous sur-rétentionnerez jusqu’à épuiser le pool.

Partir des objectifs de récupération, pas des sentiments

Il y a trois réglages à définir :

  • RPO (Recovery Point Objective) : combien de perte de données vous tolérez. Cela détermine la fréquence des snapshots (horaire, toutes les 15 minutes, etc.).
  • RTO (Recovery Time Objective) : à quelle vitesse vous devez récupérer. Cela influence combien de snapshots vous gardez localement pour un rollback rapide.
  • Horizon historique : jusqu’où vous devez remonter pour corriger des erreurs lentes (mauvaise config, dérive de données). Cela motive les snapshots quotidiens/hebdomadaires/mensuels et la rétention hors site.

Une politique de départ pratique pour de nombreuses charges mixtes ressemble à :

  • Toutes les 15 minutes : garder 24 heures
  • Horaire : garder 7 jours
  • Quotidien : garder 30 jours
  • Hebdomadaire : garder 12 semaines
  • Mensuel : garder 12 mois (souvent uniquement hors site)

Ce n’est pas un modèle universel ; c’est un point de départ qui force les compromis à la lumière du jour.

Planification de capacité : réserver une marge pour les snapshots

En production, « pool à 80 % » n’est pas une vibe ; c’est une limite. Au-delà d’environ 80–85 % (selon recordsize, ashift, fragmentation, charge), l’allocation devient plus difficile et les performances deviennent étranges. Les snapshots facilitent la dérive vers le haut parce qu’ils sont invisibles jusqu’à ce qu’ils ne le soient plus.

Au lieu de demander « Combien de snapshots pouvons-nous garder ? », demandez :

  • Quel est notre churn quotidien (combien de données changent par jour) ?
  • Combien de temps gardons-nous des snapshots à haute fréquence ?
  • Quelle part de ce churn doit rester locale vs répliquée/hors site ?

Si un dataset a 2 To de données actives mais change pour 300 Go/jour (bases de données, artefacts CI, images VM), alors « garder 30 snapshots quotidiens » n’est pas « garder 2 To plus un peu ». C’est potentiellement « garder jusqu’à ~9 To de blocs historiques écrasés », moins les effets de compression/dedupe. C’est la mathématique que les opérateurs devraient présenter à la direction avant que la direction ne mette une nouvelle initiative sur le même pool.

Rétention en niveaux : rollback local rapide vs historique long distant

Garder un historique profond localement est coûteux et souvent inutile. Utilisez des snapshots locaux pour des fenêtres de rollback rapides (heures à jours), et utilisez des cibles de réplication (un autre pool, un autre site) pour une histoire plus longue où les pressions de capacité et de performance sont différentes.

Deux mises en garde :

  • La réplication incrémentale dépend des chaînes de snapshots. Si vous supprimez un snapshot attendu par le flux incrémental distant, vous pouvez forcer un renvoi complet — pénible en bande passante et en temps.
  • Les cibles de réplication ont leur propre histoire de rétention. « Nous répliquons tout » n’est pas une politique de rétention ; c’est une façon de reproduire vos erreurs ailleurs.

Bornes de dataset : ne snapshottez pas le tiroir à bazar

Si vous prenez des snapshots d’un dataset qui contient à la fois « config critique » et « cache régénérable », vos coûts de rétention seront dominés par le churn du cache. Séparez les datasets selon les lignes de rétention et de churn :

  • Séparez les bases de données des logs et fichiers temporaires.
  • Séparez les images VM des caches d’ISO et des artefacts de build.
  • Séparez les répertoires home des dossiers de téléchargement géants (oui, ça existe).

En tant que SRE, j’ai vu des rétentions « échouer » parce que la politique était correcte mais appliquée au mauvais périmètre de dataset. Le système de fichiers était structuré comme un tiroir à bazar, et les snapshots faisaient ce pour quoi on les avait instruits : préserver l’historique de tout, y compris des déchets.

Nommage, étiquetage et découvrabilité

La rétention des snapshots est en partie psychologique. Si personne ne comprend à quoi sert un snapshot, personne ne le supprimera. Si personne ne sait quels snapshots sont sûrs, le nettoyage devient une négociation politique.

Utilisez un schéma de nommage qui encode l’intention

Un schéma utilisable inclut :

  • Timestamp dans un format triable (UTC est votre ami)
  • Classe de fréquence (15m, hourly, daily, weekly)
  • Créateur ou système (cron, backup, opérateur)
  • Référence de ticket/changement optionnelle pour les snapshots manuels

Exemples de modèles (choisissez-en un et tenez-vous-y) :

  • pool/app@auto-2025-12-25T1200Z-hourly
  • pool/app@manual-INC12345-2025-12-25T1200Z

Les holds ne sont pas une poubelle

Les holds sur snapshots existent pour empêcher la suppression. C’est utile quand un incident est en cours ou qu’une enquête nécessite un état figé. Ce n’est pas un mécanisme de rétention. Les holds devraient avoir :

  • Une chaîne de raison incluant qui/pourquoi
  • Un processus d’expiration (réviser les holds chaque semaine)
  • Un propriétaire documenté

Clones : traitez-les comme des ressources de production

Les clones sont brillants pour des environnements de test rapides et des rafraîchissements de BD. Ils sont aussi la raison n°1 pour laquelle « détruire les anciens snapshots » échoue durant un nettoyage d’urgence. Si vous autorisez le clonage ad hoc, vous devez inventorier les clones et soit :

  • Promouvoir les clones pour qu’ils ne dépendent plus de la chaîne de snapshots d’origine, ou
  • Restreindre le clonage à des pipelines contrôlés avec expiration

Schémas d’automatisation (et ce qu’ils cassent)

L’automatisation est le seul moyen pour que la rétention fonctionne à l’échelle. C’est aussi ainsi que vous détruisez accidentellement votre meilleur point de récupération ou conservez des snapshots pour toujours parce qu’un code de sortie n’a pas été géré.

Deux modes d’automatisation : « basé sur le nombre » vs « basé sur le temps »

Basé sur le nombre signifie « garder les N derniers ». C’est simple mais dangereux : si les snapshots s’interrompent pendant une semaine, vous pouvez conserver une semaine d’écarts et supprimer votre dernier bon point connu parce qu’il est « vieux ».

Basé sur le temps signifie « garder tout ce qui est plus récent que X ». Cela s’aligne sur les attentes humaines et le langage RPO/RTO. C’est un peu plus difficile à implémenter correctement quand vous avez plusieurs fréquences.

Utilisez des politiques hiérarchiques, pas une règle géante

La rétention fonctionne mieux en couches :

  • Snapshots haute fréquence, rétention courte (rollback rapide)
  • Snapshots basse fréquence, rétention moyenne
  • Snapshots d’archive, rétention longue (souvent distante)

Exécutions à blanc et garde-fous

En production, le nettoyage devrait supporter :

  • Liste en dry-run des candidats
  • Suppression par lots bornés (pour éviter de longs blocages txg et la panique opérateur)
  • Journalisation des actions et des raisons
  • Refus d’opérer si le pool est dégradé (vous ne voulez pas ajouter du stress)

Trois mini-histoires du monde corporate

1) Incident causé par une mauvaise hypothèse : « Les snapshots ne comptent pas »

L’entreprise disposait d’un service NFS sur ZFS utilisé par une douzaine d’équipes internes. Le tableau de bord de stockage affichait le dataset principal à une taille raisonnable, et le pool allait bien depuis des mois. Puis, pendant un long week-end, un job batch a réécrit des données — même taille totale, blocs différents. Le mardi matin, le pool était à 98 % et la latence NFS ressemblait à un sismographe.

Le responsable on-call a fait la danse habituelle de nettoyage : vider d’anciens fichiers de log, supprimer des exports temporaires, même effacer quelques gros répertoires « évidents ». L’espace n’a pas bougé. À ce stade, l’histoire tourne généralement au doigt pointé : « ZFS ment », « le moniteur est faux », « quelqu’un a monté le mauvais pool ». Rien de tout cela n’était vrai.

Le véritable coupable était une politique de rétention qui n’existait que sur une page wiki. Des snapshots étaient pris toutes les heures et jamais détruits parce que le job de nettoyage avait échoué silencieusement après qu’une mise à jour OS ait changé le format de sortie d’une commande. La mauvaise hypothèse était que « les snapshots sont des métadonnées et n’ont pas d’importance ». Elles en avaient — parce que le churn du rewrite batch était conservé chaque heure pendant des mois.

La récupération fut salissante mais instructive. Ils ont identifié quels datasets avaient le plus grand usedbysnapshots, mis en pause le job bruyant, et supprimé les snapshots par lots en surveillant l’utilisation du pool et la latence. Ils ont aussi ajouté du monitoring sur le nombre de snapshots et l’espace utilisé par les snapshots, plus une alerte quand le job de rétention échoue. Le changement le plus précieux fut culturel : la rétention des snapshots devint une configuration contrôlée par changement, pas un « ça tourne probablement » laissé au hasard.

2) Optimisation qui a mal tourné : « Snapshoter tout toutes les 5 minutes »

Une équipe plateforme voulait un rollback quasi-instantané pour une flotte d’agents de build et d’environnements de test. Quelqu’un proposa : « Prenez des snapshots toutes les cinq minutes et gardez-les deux semaines. » Dans une présentation, cela semblait génial : restaurations rapides, faible effort d’ingénierie, risque minimal. Le fait que les agents de build génèrent et suppriment d’énormes quantités de données a été poliment ignoré.

Ça a marché — brièvement. Les restaurations étaient rapides, et les développeurs satisfaits. Puis le pool commença à se fragmenter. L’allocation devint plus lourde, les écritures synchrones ralentirent, et l’overhead des métadonnées grignota. Le nombre de snapshots monta à des milliers par dataset, et la liste des snapshots devint assez lente pour que leur automatisation expire parfois. L’« optimisation » devint une auto-sabotage.

Le retour de bâton n’était pas parce que les snapshots sont mauvais. C’était parce que des snapshots haute fréquence sur des données à fort churn et peu de valeur sont un mauvais compromis. L’équipe finit par scinder le dataset : la configuration critique et les petits états eurent des snapshots agressifs, tandis que l’espace de build migra vers un dataset avec une rétention minimale (ou nulle), plus un store d’artefacts séparé avec un vrai cycle de vie. Les performances se rétablirent, les opérations sur les snapshots redevinrent fiables, et la capacité de rollback resta intacte pour les données qui le méritaient vraiment.

La leçon : la fréquence de snapshot n’est pas un badge de sérieux. C’est une fonction de coût. Traitez-la comme telle.

3) Une pratique ennuyeuse mais correcte qui a sauvé la mise : « Drills trimestriels et discipline des holds »

Dans une autre organisation, l’équipe stockage n’était pas tape-à-l’œil. Ils avaient une revue de politique programmée chaque trimestre. Ils testa ient des restaurations depuis les snapshots et depuis les cibles répliquées. Ils gardaient une petite liste de « snapshots dorés » utilisés pour audits et releases, et ils contrôlaient les holds comme des permis de stationnement : il faut une raison, un propriétaire, et ça expire sauf renouvellement.

Puis un mauvais déploiement est passé et a corrompu un dataset de manière subtile — pas une destruction totale, plutôt « tout a l’air correct jusqu’à ce que le job de facturation s’exécute ». L’équipe applicative voulut revenir en arrière, mais l’incident fut découvert des jours plus tard. C’est là que les politiques ad hoc échouent généralement : les snapshots « utiles » sont déjà partis, et les restants sont trop récents.

Mais la pratique ennuyeuse a payé. L’équipe stockage avait des snapshots quotidiens pendant 30 jours localement, et des snapshots mensuels conservés un an sur la cible de réplication. Ils trouvèrent un snapshot quotidien propre datant d’avant la fenêtre de corruption, le validèrent dans un clone, et restaurèrent avec un minimum de drama. Le business n’a jamais connu les détails, ce qui est la preuve d’une opération bien exécutée.

La leçon n’est pas « gardez tout ». C’est « gardez ce dont votre entreprise a réellement besoin, et prouvez que vous pouvez le restaurer ». Les snapshots qui n’ont pas été restaurés sont des actifs théoriques. En incident, la théorie coûte cher.

Tâches pratiques : commandes et interprétation

Ci-dessous des tâches pratiques que vous pouvez exécuter sur un système ZFS. Les commandes sont montrées dans un format d’invite cohérent ; ajustez les noms de pool/dataset pour correspondre à votre environnement.

Tâche 1 : Obtenir une vue haute-niveau de la santé et de la capacité du pool

cr0x@server:~$ zpool status -v
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 02:31:44 with 0 errors on Sun Dec 22 02:31:45 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0

errors: No known data errors

Interprétation : Si le pool est dégradé, différer les suppressions agressives de snapshots ou les réarrangements de réplication ; vous ne voulez pas ajouter de charge. Vérifiez aussi la récence des scrubs — des scrubs anciens plus une forte utilisation forment un cocktail risqué.

Tâche 2 : Voir l’espace du pool et les signaux de fragmentation

cr0x@server:~$ zpool list -o name,size,alloc,free,cap,health
NAME   SIZE   ALLOC   FREE  CAP  HEALTH
tank  36.2T   29.8T  6.4T  82%  ONLINE

Interprétation : Vers ~80 % de capacité, commencez à prêter attention. Si vous êtes au-dessus de 85–90 %, votre fenêtre de nettoyage de snapshots devient une zone à risque en production.

Tâche 3 : Afficher la répartition d’espace du dataset incluant les snapshots

cr0x@server:~$ zfs list -o name,used,available,usedbydataset,usedbysnapshots,usedbychildren,mountpoint tank/app
NAME      USED  AVAIL  USEDBYDATASET  USEDBYSNAPSHOTS  USEDBYCHILDREN  MOUNTPOINT
tank/app  8.2T  5.9T          2.1T              5.7T            420G  /tank/app

Interprétation : C’est la signature classique de « bombe d’espace » : le dataset utilise seulement 2.1T, les snapshots retiennent 5.7T. Supprimer des fichiers n’aidera pas tant que les snapshots ne sont pas élagués.

Tâche 4 : Lister les snapshots avec used et referenced

cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -s creation tank/app | tail -n 6
tank/app@auto-2025-12-24T1800Z-hourly   12.3G  2.1T  Wed Dec 24 18:00 2025
tank/app@auto-2025-12-24T1900Z-hourly   10.9G  2.1T  Wed Dec 24 19:00 2025
tank/app@auto-2025-12-24T2000Z-hourly   11.7G  2.1T  Wed Dec 24 20:00 2025
tank/app@auto-2025-12-24T2100Z-hourly   14.2G  2.1T  Wed Dec 24 21:00 2025
tank/app@auto-2025-12-24T2200Z-hourly   13.8G  2.1T  Wed Dec 24 22:00 2025
tank/app@auto-2025-12-24T2300Z-hourly   15.1G  2.1T  Wed Dec 24 23:00 2025

Interprétation : Le used du snapshot ici est l’espace incrémental unique. Si ces valeurs sont élevées et régulières, votre churn est important. Si elles flambent, cherchez des réécritures batch, des compactages ou des rotations de logs qui réécrivent de gros fichiers.

Tâche 5 : Trouver les pires datasets par overhead de snapshots

cr0x@server:~$ zfs list -r -o name,usedbydataset,usedbysnapshots -s usedbysnapshots tank | head -n 10
NAME                 USEDBYDATASET  USEDBYSNAPSHOTS
tank                 128K           0B
tank/home            640G           120G
tank/vm              3.1T           2.8T
tank/app             2.1T           5.7T
tank/app/db          1.4T           3.9T
tank/app/logs        180G           1.1T
tank/ci              900G           4.4T
tank/ci/workspace    700G           4.2T
tank/backup          1.9T           900G

Interprétation : Les coupables sont généralement évidents : workspaces CI, logs, images VM. La correction est rarement « supprimer des snapshots aveuglément ». C’est « arrêter de snapshotter des données volatiles ou réduire leur rétention ».

Tâche 6 : Vérifier les holds qui bloquent la suppression

cr0x@server:~$ zfs holds tank/app@auto-2025-12-01T0000Z-daily
NAME                              TAG                    TIMESTAMP
tank/app@auto-2025-12-01T0000Z-daily  audit-freeze         Thu Dec  4 09:12 2025

Interprétation : Ce snapshot ne pourra pas être supprimé tant que le hold n’est pas relâché. Le tag vous indique qui/pourquoi — si votre processus est suffisamment mature pour exiger des tags significatifs.

Tâche 7 : Relâcher un hold (avec précaution)

cr0x@server:~$ sudo zfs release audit-freeze tank/app@auto-2025-12-01T0000Z-daily

Interprétation : Le relâchement des holds doit être audité. Si vous le faites de manière ad hoc pendant un incident d’espace, notez ce que vous avez relâché et pourquoi. Le vous du futur voudra ces miettes de pain.

Tâche 8 : Découvrir les clones qui empêchent la destruction d’un snapshot

cr0x@server:~$ zfs get -H -o name,value clones tank/app@auto-2025-11-15T0000Z-daily
tank/app@auto-2025-11-15T0000Z-daily	tank/dev/app-test

Interprétation : Ce snapshot a un clone dépendant. Vous ne pouvez pas détruire la chaîne de snapshots de manière imprudente tant que le clone n’est pas traité.

Tâche 9 : Promouvoir un clone pour supprimer la dépendance au snapshot d’origine

cr0x@server:~$ sudo zfs promote tank/dev/app-test

Interprétation : La promotion change la lignée : le clone devient primaire, et l’origine devient dépendante. C’est une bonne option quand un environnement dev est devenu accidentellement long-vivant et que vous devez libérer l’ancienne chaîne de snapshots. Faites-le intentionnellement ; ce n’est pas un changement cosmétique.

Tâche 10 : Supprimer des snapshots en lots bornés en sécurité

cr0x@server:~$ zfs list -t snapshot -o name -s creation tank/app | head -n 5
NAME
tank/app@auto-2025-10-01T0000Z-daily
tank/app@auto-2025-10-02T0000Z-daily
tank/app@auto-2025-10-03T0000Z-daily
tank/app@auto-2025-10-04T0000Z-daily
cr0x@server:~$ sudo zfs destroy tank/app@auto-2025-10-01T0000Z-daily
cr0x@server:~$ sudo zfs destroy tank/app@auto-2025-10-02T0000Z-daily

Interprétation : Dans un incident de pool plein, supprimer des milliers de snapshots d’un coup peut produire des opérations longues et rendre les gens nerveux. Faites par lots, observez l’impact, et évitez d’aggraver la latence en essayant de résoudre l’espace.

Tâche 11 : Supprimer une plage via le nommage des snapshots (lorsque approprié)

cr0x@server:~$ sudo zfs destroy -n tank/app@auto-2025-10-01T0000Z-daily%auto-2025-10-31T0000Z-daily
would destroy tank/app@auto-2025-10-01T0000Z-daily
would destroy tank/app@auto-2025-10-02T0000Z-daily
...
would destroy tank/app@auto-2025-10-31T0000Z-daily
cr0x@server:~$ sudo zfs destroy tank/app@auto-2025-10-01T0000Z-daily%auto-2025-10-31T0000Z-daily

Interprétation : Utilisez -n d’abord. La suppression de plage est puissante et dangereuse ; c’est ainsi que vous nettoyez correctement en minutes ou que vous détruisez votre fenêtre de récupération en secondes.

Tâche 12 : Mesurer le churn avec les octets écrits (approximation)

cr0x@server:~$ zfs get -o name,property,value -s local,received,default written tank/app
NAME      PROPERTY  VALUE
tank/app  written   14.8T

Interprétation : written est un indice utile sur la quantité de données écrites dans le dataset (pas exactement le « churn », mais corrélé). S’il explose, les coûts de rétention suivront.

Tâche 13 : Vérifier quotas et réservations qui font paraître l’espace « manquant »

cr0x@server:~$ zfs get -o name,property,value quota,refquota,reservation,refreservation tank/app
NAME      PROPERTY        VALUE
tank/app  quota           none
tank/app  refquota        none
tank/app  reservation     none
tank/app  refreservation  500G

Interprétation : Un refreservation peut réserver de l’espace même quand vous essayez de récupérer. Ce n’est pas maléfique ; c’est la façon de garantir de l’espace pour un dataset. Mais pendant un incident, ça peut vous surprendre.

Tâche 14 : Voir quels snapshots sont référencés par des bookmarks ou une logique de réplication (vérifications)

cr0x@server:~$ zfs list -t bookmark -o name,creation -s creation tank/app
NAME                              CREATION
tank/app#replica-2025-12-20T0000Z  Sat Dec 20 00:00 2025
tank/app#replica-2025-12-21T0000Z  Sun Dec 21 00:00 2025

Interprétation : Les bookmarks peuvent être utilisés pour ancrer la réplication incrémentale sans garder un snapshot complet sur l’émetteur. Si vous les utilisez, intégrez-les délibérément à l’histoire de rétention — ne tombez pas dessus par hasard lors d’un nettoyage.

Tâche 15 : Valider que la suppression de snapshots a réellement réduit snapshot-used

cr0x@server:~$ zfs list -o name,usedbydataset,usedbysnapshots tank/app
NAME      USEDBYDATASET  USEDBYSNAPSHOTS
tank/app          2.1T              5.7T
cr0x@server:~$ sudo zfs destroy tank/app@auto-2025-10-01T0000Z-daily%auto-2025-10-15T0000Z-daily
cr0x@server:~$ zfs list -o name,usedbydataset,usedbysnapshots tank/app
NAME      USEDBYDATASET  USEDBYSNAPSHOTS
tank/app          2.1T              4.9T

Interprétation : Bien : snapshot-used a baissé. Si ce n’est pas le cas, vous avez probablement supprimé des snapshots qui ne tenaient pas beaucoup d’espace unique, ou vous êtes bloqué par des clones/holds ailleurs, ou le churn continue.

Mode opératoire de diagnostic rapide

Voici le playbook « approchez un pool stressé et trouvez le goulot d’étranglement rapidement ». Il est ordonné pour le temps jusqu’au signal, pas pour la pureté académique.

Premier point : le pool est-il simplement trop plein ou malade ?

cr0x@server:~$ zpool list -o name,cap,alloc,free,health
NAME  CAP  ALLOC  FREE  HEALTH
tank  92%  33.3T  2.9T  ONLINE
cr0x@server:~$ zpool status -x
all pools are healthy

Interprétation : Si vous êtes >90 % utilisé, traitez tout comme urgent. Les performances et le comportement d’allocation ZFS se dégradent quand l’espace libre diminue. Si le pool est dégradé, évitez les opérations disruptives lourdes et concentrez-vous sur la réduction rapide du risque.

Deuxième point : qui consomme l’espace — dataset, snapshots, enfants, réservations ?

cr0x@server:~$ zfs list -o name,used,available,usedbydataset,usedbysnapshots,usedbychildren,usedbyrefreservation -r tank | head -n 20
NAME           USED  AVAIL  USEDBYDATASET  USEDBYSNAPSHOTS  USEDBYCHILDREN  USEDBYREFRESERVATION
tank           29.8T  6.4T           128K              0B            29.8T                  0B
tank/app       8.2T   5.9T           2.1T             5.7T             420G                 0B
tank/ci        5.5T   5.9T           900G             4.4T             200G                 0B
tank/vm        5.9T   5.9T           3.1T             2.8T               0B                 0B

Interprétation : Décidez où agir. Si usedbysnapshots domine, l’élagage aide. Si usedbydataset domine, vous avez besoin de suppression réelle ou migration. Si usedbyrefreservation est grand, revisitez les réservations.

Troisième point : qu’est-ce qui empêche la suppression des snapshots ?

Vérifiez les holds et les clones pour tout snapshot que vous comptez supprimer.

cr0x@server:~$ zfs holds tank/ci@auto-2025-11-01T0000Z-daily
no datasets available
cr0x@server:~$ zfs get -H -o value clones tank/ci@auto-2025-11-01T0000Z-daily
-

Interprétation : S’il y a des holds ou des clones, votre plan de nettoyage doit inclure la libération des holds ou la promotion/destruction des clones. Sinon vous perdrez du temps à « supprimer » des snapshots impossibles à supprimer.

Quatrième point : le churn est-il toujours en cours ?

Si vous élaguez pendant qu’une charge réécrit des téraoctets, vous colmatez un bateau avec un trou. Mettez en pause le job churn si possible, ou réduisez temporairement la charge d’écriture.

cr0x@server:~$ zfs get -o name,property,value written tank/ci/workspace
NAME               PROPERTY  VALUE
tank/ci/workspace  written   92.4T

Interprétation : Des valeurs written élevées ne prouvent pas un churn actuel, mais elles indiquent que ce dataset est une machine à churn et ne devrait pas avoir une rétention haute fréquence profonde.

Cinquième point : si la latence est le problème, confirmez la pression I/O séparément

Les incidents d’espace ZFS se manifestent souvent comme des incidents de latence. N’assumez pas que c’est « juste le réseau » ou « juste l’app ». Confirmez que le pool subit une pression I/O avant d’effectuer des changements qui l’augmenteraient.

cr0x@server:~$ zpool iostat -v 5 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        29.8T  6.4T     88   2100  8.2M  310M
  raidz2-0                  29.8T  6.4T     88   2100  8.2M  310M
    sda                         -      -     22    520  2.0M   78M
    sdb                         -      -     23    530  2.1M   79M
    sdc                         -      -     21    520  2.0M   76M
    sdd                         -      -     22    530  2.1M   77M
--------------------------  -----  -----  -----  -----  -----  -----

Interprétation : Si le pool est saturé, la suppression de snapshots et d’autres opérations metadata lourdes peuvent aggraver les latences de pointe. Faites les opérations par lots et programmez le nettoyage hors-peak quand possible — sauf si vous êtes déjà dans le rayon d’explosion.

Erreurs courantes, symptômes, corrections

Erreur 1 : « On gardera tout, le stockage est bon marché »

Symptômes : L’utilisation du pool augmente progressivement malgré « pas de croissance » des données visibles ; le nettoyage devient un travail d’urgence ; les restaurations ralentissent parce que le système est toujours proche du plein.

Correction : Définir des objectifs de récupération et plafonner la rétention locale. Déplacer l’historique long vers une cible de réplication séparée avec son propre plan de capacité.

Erreur 2 : Snapshotter des datasets à fort churn (CI, logs, caches) avec la même politique que les bases de données

Symptômes : usedbysnapshots dépasse largement usedbydataset ; des milliers de snapshots ; fragmentation croissante et latence d’écriture en hausse.

Correction : Séparer les datasets par classe de churn. Appliquer des snapshots agressifs seulement à l’état à haute valeur et faible churn. Pour les données churny, garder une rétention courte voire nulle ; s’appuyer sur des politiques de cycle de vie d’artefacts de niveau supérieur.

Erreur 3 : Ignorer les holds jusqu’à ce qu’ils deviennent permanents

Symptômes : Le job de rétention « réussit » mais le nombre de snapshots ne diminue jamais ; zfs destroy échoue ; les opérateurs découvrent des « holds mystères » pendant un incident.

Correction : Discipline opérationnelle : les holds exigent propriétaire/raison/expiration. Exécutez un rapport hebdomadaire des snapshots retenus et révisez-les.

Erreur 4 : Autoriser les clones sans propriété du cycle de vie

Symptômes : La suppression des snapshots échoue à cause de clones dépendants ; de vieux environnements dev/test empêchent le nettoyage ; l’équipe stockage devient le propriétaire réticent de clones abandonnés.

Correction : Traitez les clones comme des ressources de première classe. Imposer une expiration, ou exiger une promotion avec propriété explicite avant qu’un clone puisse vivre plus longtemps qu’une courte fenêtre.

Erreur 5 : Utiliser « garder les N derniers » sans gardes contre les trous

Symptômes : Après une panne dans la création des snapshots, le nettoyage supprime les anciens snapshots et ne laisse que les nouveaux — détruisant votre capacité à revenir au-delà de la fenêtre de panne.

Correction : Préférer la rétention basée sur le temps. Si vous utilisez le compte, implémentez « âge minimum pour suppression » et « fenêtre historique minimale » comme garde-fous.

Erreur 6 : Supprimer des snapshots en une seule opération massive pendant une charge de pointe

Symptômes : Latence accrue ; zfs destroy long ; timeouts applicatifs ; opérateurs paniquent et interrompent au milieu de l’opération.

Correction : Supprimer par lots, mesurer l’impact, et prioriser les snapshots qui détiennent le plus d’espace unique. Programmer la suppression en masse hors-peak quand possible.

Erreur 7 : Ne pas surveiller les échecs de l’automatisation de rétention

Symptômes : Tout semble OK jusqu’à ce que ce ne soit pas le cas ; le nombre de snapshots augmente en silence ; les scripts de nettoyage échouent silencieusement après des changements OS/outils.

Correction : Alerter sur le « dernier succès du job de rétention » et sur les comptes/espaces de snapshots dépassant des seuils. Traiter la rétention comme un service de production.

Checklists / plan étape par étape

Étapes : Concevoir une politique de rétention adaptée à la réalité

  1. Classer les datasets par valeur métier et churn : état critique, état important, régénérable, caches/logs.
  2. Définir RPO/RTO par classe (pas par point de montage filesystem).
  3. Choisir les fréquences de snapshot qui correspondent au RPO : ex. 15m pour l’état critique, hourly/daily pour le moins critique.
  4. Fixer des fenêtres de rétention locales avec marge : garder moins localement que vous ne le souhaitez émotionnellement, plus distant que vous ne le faites actuellement.
  5. Planifier la capacité en utilisant des estimations de churn : budgéter explicitement la marge pour snapshots (et revoir trimestriellement).
  6. Définir des conventions de nommage et les appliquer dans l’automatisation.
  7. Définir la politique de holds : raisons autorisées, tags requis, expiration, reporting.
  8. Définir la politique de clones : qui peut créer, où, pour combien de temps, et ce qui se passe à l’expiration.
  9. Automatiser la création et l’élagage des snapshots avec dry-run et journalisation.
  10. Tester les restaurations trimestriellement : à la fois un simple rollback et un workflow de récupération complet.

Étapes : Nettoyage d’urgence quand le pool est presque plein

  1. Arrêter l’hémorragie : mettre en pause les jobs à fort churn, arrêter les CI en fuite, stopper les tempêtes de logs, désactiver les écritures non essentielles.
  2. Confirmer la pression : zpool list, zfs list avec la répartition des snapshots.
  3. Identifier les principaux coupables : datasets avec le plus grand usedbysnapshots.
  4. Vérifier les blocages : holds et clones sur les anciens snapshots.
  5. Supprimer par lots en commençant par les snapshots les moins susceptibles d’être nécessaires (anciens horaire avant daily/weekly, sauf si la politique indique le contraire).
  6. Re-vérifier après chaque lot : capacité du pool, latence, et métriques snapshot-used.
  7. Documenter ce que vous avez fait et pourquoi ; puis corriger l’automatisation/politique qui a permis que cela arrive.

FAQ

1) Les snapshots ZFS consomment-ils immédiatement de l’espace ?

Typiquement non : créer un snapshot est surtout de la métadonnée. Le coût en espace apparaît quand le dataset vivant change et que d’anciens blocs doivent être retenus.

2) Pourquoi la suppression de fichiers ne libère-t-elle pas d’espace sur mon filesystem ZFS ?

Si des snapshots existent, les blocs supprimés/écrasés peuvent toujours être référencés par ces snapshots. Libérer de l’espace nécessite de supprimer des snapshots (ou de déplacer les données vers un nouveau dataset sans ces snapshots).

3) Quel est le meilleur indicateur pour voir l’impact des snapshots ?

Utilisez zfs list avec usedbydataset et usedbysnapshots. Cela vous dit si les snapshots sont le consommateur dominant. Le used au niveau snapshot aide pour les patterns de churn mais peut induire en erreur quand de nombreux snapshots partagent des blocs.

4) Est-il sûr de supprimer des snapshots ?

Sécuritairement, oui — si vous comprenez quels points de récupération vous perdez et si vous ne cassez pas les attentes de réplication. L’acte technique de suppression est sûr ; la conséquence métier peut être irréversible.

5) Pourquoi ne puis-je pas détruire un snapshot ? Il indique qu’il est occupé.

Raisons courantes : il a un hold, ou il a des clones dépendants. Vérifiez avec zfs holds et zfs get clones. Supprimez les holds ou gérez les clones (destroy/promote) avant de réessayer.

6) Dois-je garder des snapshots sur le même pool que les données de production ?

Pour des fenêtres de rollback courtes, oui. Pour un historique long, il est généralement préférable de répliquer vers un autre pool ou système. Un pool unique est un seul domaine de panne et un seul domaine de capacité — les snapshots ne changent pas cela.

7) Combien de snapshots sont « trop nombreux » ?

Il n’y a pas de nombre universel. C’est « trop » quand la gestion/liste des snapshots devient lente, les jobs de rétention expirent, ou l’espace tenu par les snapshots grignote la marge. Les datasets à fort churn atteignent « trop nombreux » plus vite.

8) Compression et recordsize influencent-ils la rétention des snapshots ?

Oui. La compression change l’empreinte physique ; recordsize et patterns d’écriture influencent combien de données anciennes doivent être conservées. Les réécritures de gros records peuvent rendre la rétention coûteuse même si « les tailles de fichiers n’ont pas changé ».

9) Puis-je compter uniquement sur les snapshots comme seule sauvegarde ?

Pas si vous tenez à la disponibilité face à une défaillance matérielle, une perte de pool ou un incident de site. Les snapshots sont excellents pour le rollback rapide et la récupération locale ; les backups/réplication fournissent séparation et survivabilité.

10) Pourquoi la suppression de snapshots n’a-t-elle pas immédiatement réduit l’utilisation du pool ?

Causes courantes : vous avez supprimé des snapshots qui ne retenaient pas beaucoup d’espace unique ; des clones/holds ancrent encore les parties coûteuses ; la charge continue à churn ; ou vous regardez les mauvais indicateurs au niveau dataset/pool. Revérifiez usedbysnapshots et vérifiez les blocages.

Conclusion

Les snapshots ZFS sont un superpouvoir. Le prix est que le temps devient un consommateur de stockage. Si vous ne mettez pas de limites sur le temps — fréquence, rétention et intention — votre pool finira par payer la facture avec intérêts, généralement pendant une semaine où vous ne pouvez pas vous permettre du drama.

La politique qui prévient les bombes d’espace n’est pas compliquée : alignez les snapshots sur les objectifs de récupération, séparez les données churny, automatisez l’élagage avec des garde-fous, et tenez les holds/clones en laisse. Le reste est de la discipline opérationnelle : surveillez ce qui compte, répétez les restaurations, et traitez la rétention comme une infrastructure de production — pas comme un script cron plein d’espoir.

← Précédent
ZFS zpool clear : quand effacer les erreurs est correct (et quand c’est stupide)
Suivant →
Surveillance DNS : Alertez avant que les utilisateurs ne s’en aperçoivent (Vérifications simples et efficaces)

Laisser un commentaire