Proxmox Backup « No space left on device » : pourquoi ça échoue alors que de l’espace semble disponible

Cet article vous a aidé ?

Vous avez beaucoup d’espace libre. df -h le confirme. Le graphique de stockage dans l’interface semble normal. Puis une tâche de sauvegarde explose avec
No space left on device et vous commencez à marchander avec l’univers.

La chute : « pas d’espace » signifie rarement « pas d’octets restants ». Cela signifie qu’une limite a été atteinte — octets, inodes, métadonnées, marge ZFS, quotas,
espace tmp, croissance des snapshots ou règles du chunk-store PBS. Voici la carte de ce territoire, écrite par quelqu’un qui l’a vu brûler en production.

Ce que « No space left on device » signifie réellement

Sous Linux, ENOSPC est le code d’erreur derrière le message. Il ne veut pas dire « le stockage est physiquement plein ».
Cela signifie : « le noyau a refusé une écriture parce que le système de fichiers, le périphérique de blocs ou un quota/une limite a dit non ».
Le refus peut survenir pour plusieurs raisons :

  • Les octets sont épuisés sur le système de fichiers ou le pool cible.
  • Les inodes sont épuisés (fréquent sur ext4/xfs avec des millions de petits fichiers ; PBS peut créer beaucoup de chunks).
  • L’espace métadonnées est épuisé (périphériques spéciaux ZFS, nœuds btree, limites de journal, ou simplement fragmentation et marge).
  • BLOCS réservés (les systèmes ext réservent des blocs ; ZFS a besoin de marge).
  • Quotas / project quotas / quotas de dataset atteints avant que le « disque entier » ne soit plein.
  • Amplification due au copy-on-write (les snapshots transforment les suppressions en « encore référencées », et les réécritures en nouvelles allocations).
  • Système de fichiers différent de celui que vous pensez (répertoire tmp sur une petite partition ; rootfs de conteneur vs stockage monté).

Proxmox ajoute ses propres nuances. Les sauvegardes impliquent des fichiers temporaires, des snapshots et (si vous utilisez Proxmox Backup Server) un chunk store qui se comporte
davantage comme une archive adressée par contenu que comme un dossier de fichiers tar. Vous pouvez donc avoir 2 To « libres » et ne pas pouvoir allouer les 128 Ko suivants.

Première blague (courte, votre fenêtre de sauvegarde ne va pas s’allonger) : l’espace libre, c’est comme la disponibilité d’une salle de réunion — toujours « disponible » jusqu’à ce que vous essayiez de la réserver.

Mode d’intervention rapide

Quand les sauvegardes échouent avec « no space », vous voulez une séquence courte et impitoyable. Ne parcourez pas les tableaux de bord. Ne devinez pas.
Vérifiez les trois contraintes qui mentent le plus souvent : octets, inodes et marge/quotas.

1) Identifier où l’écriture a échoué (datastore PBS ? NFS ? répertoire local ?)

  • Regardez le journal de la tâche Proxmox : mentionne-t-il un chemin sous /var/lib/vz, un partage monté ou un datastore PBS ?
  • Sur PBS, les erreurs apparaissent souvent dans le visualiseur de tâches et journalctl avec le contexte « chunk » ou « datastore ».

2) Vérifier les octets et les inodes sur le système de fichiers cible

  • df -h (octets)
  • df -i (inodes)

3) Si ZFS est impliqué, vérifiez la santé et la capacité du pool sérieusement

  • zpool list et zpool get autoexpand,ashift
  • zfs list -o space pour le dataset qui héberge réellement le datastore/sauvegardes
  • Si le pool dépasse >80–85% d’utilisation, considérez-le comme « effectivement plein » pour des charges d’écriture lourdes.

4) Si PBS : lancez prune et garbage collection, puis revérifiez

  • Prune supprime les références de snapshots ; GC libère les chunks non référencés. Vous avez généralement besoin des deux.
  • Si prune fonctionne mais que GC ne peut pas allouer des métadonnées, vous êtes toujours « plein » de la manière qui compte.

5) Vérifiez les répertoires temporaires et les points de montage

  • Les sauvegardes peuvent écrire des fichiers temporaires dans /var/tmp, /tmp ou un tmpdir configuré.
  • Si /tmp est un petit tmpfs, les grosses tâches vzdump peuvent échouer alors que le disque de destination a des téraoctets libres.

6) Si la cible est distante (NFS/SMB) : vérifiez les quotas et exports côté serveur

  • « Le client affiche de l’espace libre » n’est pas un contrat légal.
  • Les quotas, snapshots ou politiques de réserve sur le NAS peuvent renvoyer ENOSPC alors que le partage semble spacieux.

Les vrais modes de défaillance (et pourquoi votre espace libre ment)

Mode de défaillance A : épuisement des inodes (oui, en 2025)

Les inodes sont les « emplacements de fichier » du système de fichiers. En manquer signifie que vous ne pouvez pas créer de nouveaux fichiers — même avec des gigaoctets libres.
Les datastores PBS peuvent créer beaucoup de fichiers (chunks, index, métadonnées). Si vous placez un datastore sur ext4 avec un mauvais ratio d’inodes,
ou si vous y fonctionnez depuis des années avec beaucoup de churn, la pression sur les inodes devient réelle.

L’indice : df -h semble correct, df -i est à 100%. Les sauvegardes échouent sur des appels de création ou d’écriture.

Conseil opinionné : pour PBS, privilégiez ZFS (avec une marge saine) ou XFS avec planification. ext4 convient jusqu’à ce qu’il n’aille plus — et le jour où il n’ira plus sera
un vendredi soir.

Mode de défaillance B : comportement « plein » du pool ZFS (ça devient moche avant 100%)

ZFS est copy-on-write. C’est excellent pour l’intégrité et les snapshots, et parfois terrible pour « j’ai besoin d’ajouter beaucoup de données maintenant ».
Quand le pool atteint une forte utilisation, les allocations nécessitent plus de mises à jour de métadonnées, plus de recherches, et la fragmentation s’aggrave. Les performances chutent.
Finalement, vous atteignez un point où le pool ne peut plus allouer des blocs de la taille requise de manière fiable. Vous pouvez voir ENOSPC ou des blocages du groupe de transactions.

Le piège spécifique : les gens traitent ZFS comme ext4 — le faire atteindre 95% en s’attendant à ce qu’il se comporte. Ce n’est pas le cas.
Si vous tenez à la fiabilité et à des sauvegardes prévisibles, gardez les pools ZFS confortablement en dessous de la zone dangereuse. Ma règle : commencez à vous inquiéter à 80%, agissez à 85%.

Mode de défaillance C : quotas/réservations de dataset (le pool va bien ; votre dataset non)

Vous pouvez avoir un pool ZFS avec 10 To libres et un dataset avec quota=1T qui est plein. Même histoire sur les project quotas XFS.
Proxmox et PBS sont souvent installés par des humains qui « faisaient propre » et ont défini des quotas « pour empêcher les sauvegardes de tout manger ».
Puis ils oublient. Le quota, lui, se souvient.

Aussi, les réservations fonctionnent inversement : un dataset peut réserver de l’espace et priver les autres datasets. Si votre cible de sauvegarde ne peut plus écrire soudainement, vérifiez à la fois le quota et la réservation.

Mode de défaillance D : snapshots retenant l’espace en otage

Les snapshots ne sont pas une seconde copie. Ils sont une promesse : « les anciens blocs restent disponibles ». Quand vous supprimez ou réécrivez des données après un snapshot,
les anciens blocs restent référencés. Votre « espace libre » ne revient pas. Cela apparaît sur ZFS comme USEDDS/USEDREFRESERV/USEDSNAP.

Sur PBS, le prune supprime les références de snapshot du catalogue ; la garbage collection supprime les chunks qui ne sont plus référencés.
Si vous prunez seulement mais ne lancez jamais GC, l’utilisation disque ne diminuera pas beaucoup. Si GC ne peut pas s’exécuter à cause d’une pression sur l’espace, vous êtes dans une impasse : il faut de l’espace pour libérer de l’espace.

Mode de défaillance E : espace temporaire, tmpfs et « écrire ailleurs que prévu »

Les sauvegardes Proxmox VE (vzdump) écrivent souvent vers une cible, mais elles peuvent aussi mettre en cache des données, créer des logs et utiliser de l’espace tmp.
Si votre /tmp est un petit tmpfs (fréquent), ou si /var est sur un disque root réduit, la sauvegarde peut échouer bien avant que le disque de sauvegarde soit plein.

C’est un de ces problèmes qui fait enrager. La cible de sauvegarde a de la place. Votre disque root non. Le message d’erreur ne dit pas lequel pose problème.
Bienvenue dans l’exploitation.

Mode de défaillance F : provisioning fin et surallocation (LVM-thin, ZVOLs, SANs)

Le thin provisioning rend tout spacieux jusqu’au jour où ce n’est plus le cas. Les pools LVM-thin peuvent atteindre 100% d’utilisation de données ou de métadonnées.
Les backends SAN/NAS peuvent surallouer, et la première écriture nécessitant de vrais blocs échoue. Certains environnements renvoient ENOSPC ; d’autres des erreurs I/O.

Le point dangereux : vous pouvez avoir de l’« espace libre » à l’intérieur d’un disque de VM tandis que le thin pool qui l’héberge est à sec. Les sauvegardes qui snapshotent et lisent
un disque ne vont pas forcément échouer ; les sauvegardes qui écrivent sur le même pool stressé, si.

Mode de défaillance G : stockage distant qui ment (bizarreries NFS/SMB, snapshots serveur, quotas)

Les clients NFS mettent en cache les attributs. SMB ment parfois par omission. Et le serveur peut appliquer des quotas ou des politiques de réserve invisibles au client.
Si votre nœud Proxmox dit « No space left on device » tandis que l’UI du NAS affiche « 2 To libres », croyez l’erreur et investiguez les contraintes côté serveur.

Mode de défaillance H : overhead du chunk store PBS et « espace inutilisable »

PBS stocke les données en chunks et indexes avec vérification. Cela apporte des surcoûts :
métadonnées, checksums, index, logs, plus de l’espace « de travail » pour le GC.
Si vous dimensionnez PBS « sur la taille brute des sauvegardes », vous finirez par découvrir le concept d’« espace opérationnel de secours », typiquement lors d’une sauvegarde échouée.

Deuxième blague, parce qu’on en a droit à deux : un système de sauvegarde sans marge de secours, c’est comme un parachute plié exactement au volume du sac — techniquement impressionnant, opérationnellement fatal.

Mode de défaillance I : le système de fichiers root est plein (et fait tomber votre tâche de sauvegarde)

Même si les sauvegardes écrivent sur un montage séparé, le système a besoin d’espace pour les logs, le journal, les fichiers temporaires, les fichiers de verrouillage et parfois
les métadonnées de snapshot. Si /var/log ou le journal système remplissent le filesystem root, vous verrez une cascade d’échecs sans rapport.
Les sauvegardes sont souvent la première chose que vous remarquez.

Mode de défaillance J : « fichiers supprimés mais encore ouverts »

Piège Unix classique : un processus a un fichier ouvert ; vous le supprimez ; l’espace n’est pas libéré tant que le processus ne ferme pas le fichier.
Vous nettoyez, voyez « espace libre inchangé », puis la sauvegarde suivante échoue encore.
PBS et composants Proxmox se comportent généralement bien, mais des loggers, debuggers ou agents tiers peuvent garder de gros fichiers ouverts.

Une citation opérationnelle à garder en tête, paraphrase d’une idée de James Hamilton (AWS) : « Mesurez tout ce que vous pouvez, et automatisez le reste. »
Si vous n’avez pas d’alerte pour l’utilisation des inodes, la capacité ZFS et le metadata des thin-pools, vous choisissez des pannes surprises.

Faits intéressants et courte histoire (ce qui explique les bizarreries d’aujourd’hui)

  1. ENOSPC est plus ancien que la plupart de vos serveurs. Le code d’erreur remonte aux premiers Unix ; « device » signifiait le stockage support du système de fichiers, pas seulement les disques.
  2. Les inodes ont été conçus quand les disques étaient petits. Les premiers systèmes Unix pré-allouaient des tables d’inodes ; manquer d’inodes avant les octets est une caractéristique héritée qui refuse de disparaître.
  3. Les systèmes ext réservent des blocs par défaut. Traditionnellement ~5% réservé pour root afin de garder le système vivant et réduire la fragmentation ; cela surprend sur des volumes de données.
  4. ZFS a besoin de marge pour le copy-on-write. Une forte utilisation augmente la fragmentation et la pression sur les métadonnées ; « 100% plein » n’est pas un objectif pratique.
  5. Le thin provisioning a popularisé le « ça semblait libre ». Les plateformes VM ont normalisé la surallocation ; les administrateurs de stockage ont appris que « alloué » et « utilisé » ne sont pas identiques.
  6. PBS privilégie la déduplication plutôt que la lisibilité. Son chunk store échange des fichiers lisibles par l’humain contre intégrité et efficience ; le nettoyage demande prune + GC, pas juste supprimer des fichiers.
  7. La garbage collection a souvent besoin d’un peu d’air. Beaucoup de systèmes demandent un peu d’espace libre pour réarranger les métadonnées et libérer des blocs de façon sûre ; fonctionner « à zéro » peut bloquer le nettoyage.
  8. Le cache d’attributs NFS peut tromper la surveillance. La vue client de l’espace libre et l’application côté serveur peuvent diverger, surtout avec les quotas et snapshots.
  9. Le « libre » d’un système de fichiers n’est pas entièrement utilisable. Entre blocs réservés, tailles d’unité d’allocation et métadonnées, vous pouvez être « libre » mais incapable d’allouer les extents nécessaires.

Tâches pratiques : commandes, sorties, ce qu’elles signifient et la décision à prendre

Voici les vérifications que j’exécute quand quelqu’un signale « sauvegardes échouent, mais il y a de l’espace ». Chaque tâche inclut : une commande, un extrait réaliste de sortie,
ce que cela signifie, et l’action à entreprendre.

Task 1: Find the failing path in Proxmox task logs

cr0x@server:~$ journalctl -u pvedaemon -u pvescheduler --since "2 hours ago" | tail -n 30
Dec 26 01:12:19 pve01 pvescheduler[1883]: starting new backup job: vzdump 101 102 --storage pbs01 --mode snapshot
Dec 26 01:13:44 pve01 vzdump[22109]: ERROR: Backup of VM 101 failed - write error: No space left on device
Dec 26 01:13:44 pve01 vzdump[22109]: INFO: Failed at: /var/tmp/vzdumptmp12345
Dec 26 01:13:44 pve01 pvedaemon[1765]: VM 101 qmp command failed - backup aborted

Signification : L’échec s’est produit en écrivant dans /var/tmp, pas sur la cible de sauvegarde. C’est votre premier embranchement.

Décision : Vérifier le filesystem root et l’espace temporaire, pas la capacité PBS.

Task 2: Check byte usage on all mounted filesystems

cr0x@server:~$ df -hT
Filesystem                        Type   Size  Used Avail Use% Mounted on
/dev/mapper/pve-root              ext4    96G   95G   0G 100% /
tmpfs                             tmpfs  32G  1.2G   31G   4% /run
rpool/ROOT/pve-1                  zfs     96G   95G   0G 100% /
rpool/data                        zfs    1.8T  1.1T  700G  62% /rpool/data
192.0.2.10:/exports/pbsstore      nfs4    20T   15T  5.0T  75% /mnt/pbsstore

Signification : Le root est plein. Notez aussi l’exemple mixte qui montre comment on confond les montages ; concentrez-vous sur le montage pertinent pour le chemin en échec.

Décision : Libérer de l’espace sur / (logs, caches) ou déplacer le tmpdir vers un filesystem plus grand.

Task 3: Check inode exhaustion (the silent killer)

cr0x@server:~$ df -i
Filesystem                        Inodes   IUsed   IFree IUse% Mounted on
/dev/mapper/pve-root             6553600 6553201     399  100% /
192.0.2.10:/exports/pbsstore    134217728 210345 134007383    1% /mnt/pbsstore

Signification : Le filesystem root n’a pratiquement plus d’inodes. Cela peut casser les installations de paquets, la rotation des logs et la création de fichiers temporaires pour les sauvegardes.

Décision : Identifier les répertoires gourmands en inodes (souvent /var/log, /var/lib ou stockage de conteneurs) et nettoyer ou étendre.

Task 4: Find inode-heavy paths quickly

cr0x@server:~$ sudo du --inodes -x -d 2 /var | sort -n | tail -n 10
1200    /var/cache
8421    /var/tmp
15300   /var/log
1204500 /var/lib
1209800 /var

Signification : /var/lib consomme des inodes comme passe-temps. Sur Proxmox cela peut être des images de conteneurs, des caches ou des répertoires égarés.

Décision : Approfondir /var/lib pour trouver les coupables ; envisager de déplacer les chemins à écriture intense vers un filesystem plus grand.

Task 5: Confirm where vzdump is staging temporary data

cr0x@server:~$ grep -R "tmpdir" -n /etc/vzdump.conf /etc/pve/* 2>/dev/null
/etc/vzdump.conf:2:tmpdir: /var/tmp

Signification : Votre répertoire temporaire de sauvegarde est sur root. C’est acceptable jusqu’à ce que root soit petit ou occupé.

Décision : Déplacer tmpdir vers un filesystem dédié et spacieux (et le surveiller).

Task 6: Check whether /tmp is tmpfs and its size

cr0x@server:~$ findmnt -no SOURCE,FSTYPE,SIZE,USED,AVAIL /tmp
tmpfs tmpfs 2.0G 1.9G 100M

Signification : /tmp est un tmpfs de 2 Go et est quasiment plein. Tout outil utilisant /tmp pour préparer des données échouera rapidement.

Décision : Vider l’utilisation du tmpfs, augmenter sa taille ou configurer Proxmox pour utiliser un autre emplacement temporaire.

Task 7: If PBS is involved, check datastore usage from PBS

cr0x@server:~$ proxmox-backup-manager datastore list
┌───────────┬───────────────┬───────────────┬─────────────┐
│ Name      │ Path          │ Comment       │ Maintenance │
╞═══════════╪═══════════════╪═══════════════╪═════════════╡
│ store1    │ /mnt/store1   │ main datastore│ false       │
└───────────┴───────────────┴───────────────┴─────────────┘

Signification : Le datastore est à /mnt/store1. Vous savez maintenant quelles contraintes de filesystem importent.

Décision : Vérifier df et les inodes sur ce montage ; puis l’état de prune/GC PBS.

Task 8: Check datastore filesystem bytes and inodes on PBS host

cr0x@server:~$ df -hT /mnt/store1
Filesystem     Type  Size  Used Avail Use% Mounted on
rpool/store1   zfs   8.0T  7.4T  600G  93% /mnt/store1

Signification : 93% sur ZFS, c’est « vous aimez vivre dangereusement ». GC et nouvelles écritures peuvent échouer.

Décision : Libérer de l’espace immédiatement (prune+GC, supprimer des groupes anciens, ajouter de la capacité). Ensuite appliquer une politique de marge.

Task 9: ZFS pool and dataset space breakdown (what’s really consuming space)

cr0x@server:~$ zfs list -o name,used,avail,refer,usedsnap,usedds,usedrefreserv,logicalused -r rpool/store1
NAME           USED  AVAIL  REFER  USEDSNAP  USEDDS  USEDREFRESERV  LOGICALUSED
rpool/store1  7.40T   600G  7.10T     900G   6.50T            0B       12.8T

Signification : Les snapshots retiennent 900 Go. Cela peut être normal, ou une rétention devenue incontrôlée. Le logical used montre les effets de dédup/compression.

Décision : Revoir la rétention et vérifier si les snapshots sont bien effacés (prune PBS) et si les chunks sont libérés (GC). Envisager d’ajouter de la capacité avant d’ajuster.

Task 10: Check ZFS pool capacity and fragmentation signals

cr0x@server:~$ zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH
rpool  8.00T  7.45T   550G         -    61%    93%  1.00x  ONLINE

Signification : 93% de capacité et 61% de fragmentation. Les écritures seront pénibles ; l’allocation de métadonnées peut échouer avant 100%.

Décision : Réduire l’utilisation. N’essayez pas d’« optimiser » à tout prix ; ajoutez de l’espace ou des vdevs.

Task 11: Check dataset quotas and reservations (the invisible wall)

cr0x@server:~$ zfs get -o name,property,value -H quota,refquota,reservation,refreservation rpool/store1
rpool/store1	quota	7.5T
rpool/store1	refquota	none
rpool/store1	reservation	none
rpool/store1	refreservation	none

Signification : Le dataset a un quota de 7.5T. Vous êtes à 7.4T utilisé, donc vous êtes pratiquement à court d’espace même si le pool a autre chose ailleurs.

Décision : Augmenter le quota (si c’est intentionnel), ou libérer de l’espace à l’intérieur du quota. Si le quota était une « mesure de sécurité » oubliée, supprimez-le et remplacez-le par de la surveillance.

Task 12: PBS prune simulation (see what would be deleted)

cr0x@server:~$ proxmox-backup-manager prune-job run nightly --dry-run
Starting prune on datastore 'store1'
Group 'vm/101' - would keep 14 backups, remove 6 backups
Group 'vm/102' - would keep 14 backups, remove 4 backups
Prune dry-run completed successfully

Signification : La politique de prune supprimerait certains snapshots. Bien. Mais prune seul ne libère pas nécessairement l’espace tant que GC n’a pas tourné.

Décision : Lancer prune pour de vrai pendant une fenêtre sûre, puis exécuter GC et confirmer la diminution d’espace.

Task 13: Run PBS garbage collection and read the result

cr0x@server:~$ proxmox-backup-manager datastore gc store1
Starting garbage collection on datastore 'store1'
Removed 18432 unreferenced chunks (68.4 GiB)
GC finished in 00:12:09

Signification : Vous avez récupéré ~68 GiB. Si vous récupérez presque rien, soit la rétention est trop agressive, soit la plupart des chunks sont encore référencés par d’autres sauvegardes.

Décision : Si l’espace reste serré, réduisez la rétention, déplacez certains groupes vers un autre datastore, ou ajoutez de la capacité. N’attendez pas de miracles du GC.

Task 14: Detect deleted-but-open files eating space

cr0x@server:~$ sudo lsof +L1 | head -n 10
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NLINK    NODE NAME
rsyslogd  912 syslog  7w   REG  252,0 2147483648     0  53123 /var/log/syslog.1 (deleted)

Signification : Un fichier de log de 2 Go a été supprimé mais est encore tenu ouvert par rsyslogd. L’espace ne sera pas libéré tant que le processus ne le ferme pas.

Décision : Redémarrer le processus propriétaire (prudemment), ou configurer une rotation correcte des logs. Puis revérifier df.

Task 15: For LVM-thin setups, check thin pool data and metadata

cr0x@server:~$ sudo lvs -a -o +seg_monitor,metadata_percent,data_percent vg0
  LV              VG  Attr       LSize   Pool       Origin Data%  Meta%  Monitor
  thinpool        vg0 twi-aotz--  3.00t                      92.31  99.87 monitored
  thinpool_tmeta  vg0 ewi-aotz--  8.00g
  thinpool_tdata  vg0 lwi-aotz--  3.00t

Signification : Les métadonnées du thin pool sont à 99.87%. Condition « sur le point d’exploser ». Les écritures peuvent échouer même si Data% n’est pas à 100%.

Décision : Étendre immédiatement les métadonnées du thin pool et arrêter la surallocation sans surveillance.

Task 16: Validate that your backup target mount is actually mounted

cr0x@server:~$ findmnt /mnt/pbsstore
TARGET        SOURCE                      FSTYPE OPTIONS
/mnt/pbsstore 192.0.2.10:/exports/pbsstore nfs4   rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2

Signification : C’est monté. S’il ne l’était pas, Proxmox aurait pu écrire dans le répertoire vide sur root — le remplir silencieusement.

Décision : Si non monté, corriger l’automount/les dépendances systemd et nettoyer les écritures locales accidentelles.

Trois mini-récits du monde de l’entreprise (anonymisés, plausibles et douloureusement familiers)

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne utilisait Proxmox VE avec sauvegardes sur un partage NFS d’un NAS respectable. L’équipe ops surveillait le tableau de bord du NAS :
téraoctets libres, voyants verts, tout le monde détendu. Puis lundi matin : plusieurs sauvegardes de VM ont échoué avec « No space left on device ».
Les gens ont immédiatement blâmé Proxmox, parce que c’est ce qu’on fait quand on est fatigué.

La mauvaise hypothèse était subtile : ils supposaient que la vue client de l’espace libre correspondait à l’application côté serveur.
Le NAS avait des quotas par partage activés — définis des mois plus tôt lors d’une réorganisation du stockage. Le partage avait une capacité physique suffisante,
mais le plafond de quota avait été atteint. NFS a correctement renvoyé ENOSPC.

Pire, l’équipe a essayé de « régler » le problème en supprimant d’anciennes sauvegardes sur le partage. La comptabilité des quotas n’a pas beaucoup bougé car le NAS avait aussi des snapshots,
et la politique de rétention des snapshots conservait les blocs supprimés pendant des semaines. Le listing de fichiers paraissait plus vide, mais le quota restait bloqué.

Le correctif final fut ennuyeux : augmenter le quota du partage, réduire la rétention des snapshots et aligner la politique de rétention Proxmox avec ce que faisaient les snapshots du NAS.
Le post-mortem a inclus une nouvelle règle : toute cible de stockage doit avoir les quotas et snapshots documentés au même endroit que la définition du job de sauvegarde.

Enseignement opérationnel : quand le backend dit non, croyez-le. Puis vérifiez les quotas et snapshots côté serveur, pas seulement df côté client.

Mini-récit 2 : L’optimisation qui a mal tourné

Une autre organisation a décidé « d’optimiser » l’espace PBS en approchant le datastore du bord. Ils avaient des économies de déduplication, et cela paraissait superbe sur le papier.
Ils visaient 95% d’utilisation parce que « chaque téraoctet coûte ». La finance adorait. L’ingénieur stockage non, mais il fut surclassé.

La panne n’a pas été un événement net de type « disque plein ». Ce fut une dégradation lente : la garbage collection a pris plus de temps, puis a commencé à échouer par intermittence.
Les fenêtres de sauvegarde se sont allongées jusqu’à se chevaucher. Les jobs nocturnes ont commencé à se gêner. Finalement un ensemble de sauvegardes a échoué pendant une fenêtre de patch critique,
excellent moment pour découvrir qu’on n’a pas de point de restauration récent.

La cause racine n’était pas juste « disque plein ». C’était le comportement du pool ZFS sous forte fragmentation et faible marge.
GC avait besoin de créer et mettre à jour des métadonnées, et ces allocations sont devenues peu fiables. Le système était techniquement en ligne, fonctionnellement fragile.

Le remède a été d’ajouter de la capacité et d’imposer un seuil interne strict : alertes à 75%, action à 80–85% et interdiction de « pousser à 95% pendant une semaine ».
La « semaine » devient toujours un trimestre.

Enseignement opérationnel : les objectifs d’utilisation sont des objectifs de fiabilité. Si vous budgétez pour 95% de remplissage, vous budgétez pour des modes de panne que vous ne pouvez pas tester en sécurité.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la situation

Une troisième équipe exploitait Proxmox avec PBS sur ZFS. Leur pratique était offensivement ennuyeuse : revue de capacité hebdomadaire, alertes sur la capacité du pool ZFS et l’utilisation des inodes,
et un playbook permanent : prune, GC, vérifier l’espace, puis n’augmenter la rétention que si la marge restait suffisante. Ils gardaient aussi un petit quota « d’urgence » sur un dataset
qui pouvait être temporairement augmenté en cas d’incident.

Une nuit, un développeur a accidentellement écrit des logs dans un répertoire monté de sauvegarde depuis un conteneur mal configuré avec un bind mount.
PBS a commencé à accumuler des fichiers indésirables à côté de son chemin de datastore (pas à l’intérieur). Le job de sauvegarde a commencé à échouer, et la première page a réveillé l’astreignant.

L’astreignant n’a pas deviné. Il a suivi le runbook : vérifier les points de montage, df -i, l’utilisation du dataset ZFS. Ils ont trouvé le répertoire fautif,
arrêté le conteneur, nettoyé et lancé PBS GC. Les sauvegardes ont repris avant la relève du matin.

Pas d’héroïsme, pas de « war room », pas de terreur existentielle. Juste des outils, des seuils et un runbook qui suppose que les humains oublieront où vont vraiment les fichiers.

Enseignement opérationnel : « ennuyeux » est une caractéristique. Si votre système de sauvegarde exige de la créativité à 2 h du matin, il est conçu, non pas ingéné.

Erreurs fréquentes : symptôme → cause racine → correction

1) Symptom: df shows 30% free; backups fail immediately

Cause racine : épuisement des inodes sur le système de fichiers cible (ou sur le filesystem root/temp).

Correction : Exécutez df -i. Si les inodes sont pleins, supprimez les fichiers gourmands en inodes, faites tourner la rotation des logs, ou déplacez le datastore PBS vers un FS conçu pour de nombreux fichiers.

2) Symptom: PBS prune ran, but space didn’t come back

Cause racine : prune a supprimé les références de snapshots, mais les chunks restent jusqu’à l’exécution de la garbage collection ; ou la plupart des chunks sont encore référencés par d’autres sauvegardes.

Correction : Lancez PBS GC. Si GC échoue à cause d’une faible marge, libérez de l’espace en supprimant des groupes complets ou en ajoutant de la capacité, puis relancez GC.

3) Symptom: ZFS pool at 92% and everything becomes slow, then ENOSPC

Cause racine : pression d’allocation et des métadonnées ZFS à forte utilisation ; fragmentation et overhead CoW.

Correction : Réduisez l’utilisation du pool (supprimer des données, prune+GC, ajouter des vdevs). Fixez des seuils d’alerte bien en dessous du « plein ».

4) Symptom: Proxmox job log mentions /var/tmp or /tmp

Cause racine : tmpdir sur un petit filesystem ou tmpfs rempli.

Correction : Déplacez tmpdir dans /etc/vzdump.conf vers un montage plus grand ; nettoyez tmp ; augmentez le tmpfs si approprié.

5) Symptom: Pool has space, dataset says no

Cause racine : quota/refquota ZFS atteint ; ou quota projet XFS.

Correction : Vérifiez quotas et réservations. Augmentez/supprimez le quota ou allouez un dataset dédié dimensionné pour les objectifs de rétention.

6) Symptom: “Deleted old backups” but disk usage unchanged

Cause racine : snapshots (ZFS ou NAS) retiennent les blocs ; ou fichiers supprimés mais encore ouverts ; ou chunks PBS toujours référencés.

Correction : Vérifiez l’utilisation des snapshots, exécutez prune+GC, et lancez lsof +L1 pour détecter les fichiers supprimés encore ouverts.

7) Symptom: Backups to NFS fail, but NAS UI shows free space

Cause racine : quota côté serveur sur le partage, politique de réserve ou rétention de snapshots ; parfois mauvaise configuration d’export.

Correction : Vérifiez quotas/snapshots sur le NAS, pas seulement le df client. Confirmez le montage avec findmnt.

8) Symptom: LVM-thin backing VM disks shows “free,” but backups fail writing to local storage

Cause racine : métadonnées du thin pool pleines (souvent avant que les données ne soient pleines).

Correction : Surveillez data_percent et metadata_percent ; étendez les métadonnées ; réduisez les snapshots ; cessez la surallocation sans alertes.

9) Symptom: Root filesystem fills repeatedly after you “cleaned it”

Cause racine : sauvegardes écrivant dans un répertoire non monté (montage échoué), ou logs qui croissent, ou fichiers temporaires en boucle.

Correction : Assurez-vous que les montages sont actifs au démarrage ; ajoutez des dépendances systemd ; mettez un garde-fou comme un check de montage dans les scripts de sauvegarde.

Listes de contrôle / plan étape par étape

Étape par étape : récupérer d’un « No space left on device » aujourd’hui

  1. Arrêtez l’hémorragie. Mettez en pause les plannings de sauvegarde pour éviter de transformer un problème d’espace en problème d’espace + charge.
  2. Localisez le chemin en échec. Depuis le log de job, identifiez s’il a échoué sur root/temp, la cible de sauvegarde ou le montage du datastore.
  3. Vérifiez octets et inodes. Lancez df -hT et df -i sur le montage fautif et sur /.
  4. Si root est plein : videz les gros logs, anciens noyaux, caches ; corrigez la rotation des logs ; envisagez de déplacer les répertoires temporaires.
  5. Si les inodes sont pleins : supprimez les fichiers gourmands en inodes ; trouvez les coupables avec du --inodes ; envisagez une refonte du filesystem pour PBS.
  6. Si le pool ZFS est >85% : libérez de l’espace immédiatement. Traitez-le comme urgent. Exécutez prune+GC (PBS) et/ou supprimez des datasets anciens.
  7. Si PBS : exécutez prune, puis garbage collection, puis revérifiez l’utilisation du dataset/pool.
  8. Si stockage distant : vérifiez quotas et snapshots côté serveur ; confirmez que l’export n’est pas plafonné.
  9. Relancez une sauvegarde manuelle. Validez le correctif sur une seule VM avant de réactiver les plannings.

Prévenir : garde-fous opérationnels qui fonctionnent

  • SLOs de capacité : Définissez une utilisation maximale cible (ZFS : 80–85% pour PBS orienté écriture). Faites-en une politique, pas un conseil.
  • Alerte sur les inodes : l’utilisation des inodes n’est pas une surveillance optionnelle pour les stores de sauvegarde avec beaucoup de fichiers.
  • Alerte sur metadata thin pool : surveillez metadata_percent. Traitez 80% comme une page, pas un e-mail.
  • Planifier prune+GC et rendre visible : si GC n’a pas tourné avec succès depuis des jours, vous accumulez du risque.
  • Vérification de montage : assurez-vous que les cibles de sauvegarde sont montées avant l’exécution des jobs ; échouez rapidement si ce n’est pas le cas.
  • Séparez les chemins d’écriture système et sauvegarde : ne laissez pas les sauvegardes dépendre d’un petit filesystem root pour le stockage temporaire.

À éviter (parce que ça paraît malin jusqu’à ce que ça ne le soit plus)

  • Laisser des pools ZFS près du plein parce que « la dédup va nous sauver ». Peut-être, jusqu’à ce que non, et alors la panne n’est pas linéaire.
  • Utiliser les quotas à la place de la surveillance. Les quotas sont utiles, mais ce ne sont pas de l’observabilité.
  • Supprimer des fichiers au hasard dans les chemins du datastore PBS. Utilisez les outils PBS ; le datastore n’est pas un tiroir à bazar.
  • Supposer que le df client reflète la vérité serveur pour NFS.

FAQ

1) Pourquoi Proxmox dit « No space left on device » alors que df montre de l’espace libre ?

Parce que l’écriture qui a échoué peut viser un autre système de fichiers (comme /var/tmp), ou vous avez manqué d’inodes, ou un quota a été atteint,
ou ZFS ne peut pas allouer de manière fiable à cause d’une forte utilisation.

2) Est-ce un bug Proxmox ?

Généralement non. Proxmox affiche l’erreur noyau. La confusion vient des humains (et des IHM) qui supposent que « espace libre » est un seul nombre,
alors qu’il s’agit en fait de plusieurs contraintes empilées.

3) Pour PBS, pourquoi la suppression d’anciennes sauvegardes ne libère-t-elle pas d’espace immédiatement ?

PBS est basé sur des chunks. La suppression de sauvegardes (prune) supprime des références ; l’espace est libéré quand la garbage collection supprime les chunks non référencés.
Si la plupart des chunks sont encore référencés par d’autres sauvegardes, l’espace ne diminuera pas beaucoup.

4) Quelle marge d’espace libre garder sur un pool ZFS utilisé pour PBS ?

Gardez une marge significative. Pour la fiabilité : essayez de rester en dessous d’environ ~80–85% d’utilisation. Au-delà, attendez-vous à ce que GC et les écritures deviennent peu fiables sous pression.
Le chiffre exact dépend de la charge de travail et de la topologie des vdevs, mais « 95% plein c’est acceptable » est une fantaisie.

5) L’épuisement des inodes peut-il arriver sur ZFS ?

ZFS n’a pas de table d’inodes fixe comme ext4 ; il peut toujours atteindre des limites métadonnées d’une autre manière, mais « df -i à 100% » est principalement un problème des familles ext.
Sur ZFS, concentrez-vous plutôt sur la capacité du pool/dataset et le comportement des métadonnées.

6) Quelle est la différence entre prune et garbage collection dans PBS ?

Prune supprime les sauvegardes du catalogue selon la rétention. La garbage collection supprime les chunks sur disque qui ne sont plus référencés par aucune sauvegarde restante.
Vous avez souvent besoin des deux pour récupérer l’espace.

7) Pourquoi les sauvegardes échouent quand le NAS indique de l’espace libre ?

Quotas et snapshots. Le NAS peut appliquer un quota de partage ou réserver de la capacité. Les snapshots peuvent garder les données supprimées « en usage ».
Les clients NFS/SMB mettent aussi en cache ; le serveur est la source de vérité.

8) Comment savoir si Proxmox écrit dans un répertoire non monté ?

Utilisez findmnt pour confirmer que le montage est actif. S’il ne l’est pas, le chemin n’est qu’un répertoire sur root, et les sauvegardes peuvent remplir root silencieusement.
Vérifiez aussi les timestamps et fichiers inattendus sous le point de montage.

9) Le thin provisioning peut-il provoquer ENOSPC pendant les sauvegardes même si la cible est séparée ?

Oui, si l’écriture se fait sur le stockage local (fichiers temporaires, logs) situé sur le pool thin-provisioned, ou si le thin pool héberge aussi le datastore.
De plus, l’épuisement des métadonnées du thin pool peut casser les écritures de manière surprenante.

10) Dois-je simplement ajouter un disque plus grand et passer à autre chose ?

Souvent oui — la capacité coûte moins cher que le temps d’arrêt. Mais n’en restez pas là : ajoutez la surveillance pour la contrainte qui vous a planté (inodes, marge ZFS,
quotas, metadata thin) sinon vous reviendrez ici avec un disque plus grand et la même surprise.

Conclusion : prochaines étapes à effectuer réellement

« No space left on device » est une catégorie de diagnostic, pas une mesure. La correction n’est presque jamais « supprimer un fichier au hasard et espérer ».
Trouvez où l’écriture a échoué, puis vérifiez la contrainte qui s’applique là : octets, inodes, quotas, marge ZFS, metadata thin, ou politique côté serveur.

Faites ceci ensuite, dans l’ordre :

  1. À partir des logs, identifiez le chemin exact en échec et l’hôte (nœud PVE vs serveur PBS).
  2. Exécutez df -hT et df -i sur ce filesystem et sur /.
  3. Si ZFS est impliqué, considérez >85% utilisé comme incident et réduisez l’utilisation.
  4. Si PBS est impliqué, exécutez prune puis GC ; confirmez l’espace récupéré avec zfs list -o space ou df.
  5. Ajoutez de la surveillance pour la contrainte qui a failli, avec des seuils qui forcent une action avant la falaise.

Le meilleur système de sauvegarde est celui qui échoue bruyamment en staging et réussit silencieusement en production. Concevez-le pour que « l’espace » soit une variable contrôlée, pas une surprise.

← Précédent
Paramètres Cloudflare pour WordPress qui n’interrompent pas wp-admin
Suivant →
Microcode : le « firmware » à l’intérieur de votre CPU que vous ne pouvez plus ignorer

Laisser un commentaire