Meilleur moyen de libérer de l'espace disque des fichiers supprimés qui sont maintenus ouverts

28

Salut, j'ai de nombreux fichiers qui ont été supprimés, mais pour une raison quelconque, l'espace disque associé aux fichiers supprimés ne peut pas être utilisé jusqu'à ce que je tue explicitement le processus pour le fichier prenant l'espace disque

$ lsof /tmp/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
cron     1623 root    5u   REG   0,21        0 395919638 /tmp/tmpfPagTZ4 (deleted)

L'espace disque occupé par le fichier supprimé ci-dessus provoque des problèmes tels que lorsque j'essaie d'utiliser la touche de tabulation pour compléter automatiquement un chemin de fichier, j'obtiens l'erreur bash: cannot create temp file for here-document: No space left on device

Mais après avoir exécuté kill -9 1623l'espace pour ce PID est libéré et je ne reçois plus l'erreur.

Mes questions sont:

  • pourquoi cet espace n'est-il pas immédiatement libéré lors de la première suppression du fichier?
  • quelle est la meilleure façon de récupérer l'espace fichier associé aux fichiers supprimés?

et veuillez me faire savoir toute terminologie incorrecte que j'ai utilisée ou toute autre information pertinente et pertinente concernant cette situation.

BryanK
la source

Réponses:

26

Sur les unités, les noms de fichiers ne sont que des pointeurs (inodes) qui pointent vers la mémoire où réside le fichier (qui peut être un disque dur ou même un système de fichiers sauvegardé en RAM). Chaque fichier enregistre le nombre de liens vers celui-ci: les liens peuvent être soit le nom du fichier (pluriel, s'il existe plusieurs liens durs vers le même fichier), et également chaque fois qu'un fichier est ouvert, le processus contient en fait le "lien" vers le même espace.

L'espace n'est physiquement libéré que s'il n'y a plus de liens (il est donc impossible de s'y rendre). C'est le seul choix judicieux: pendant que le fichier est utilisé, ce n'est pas important si quelqu'un d'autre ne peut plus y accéder: vous l'utilisez et jusqu'à ce que vous le fermiez, vous avez toujours le contrôle - vous ne remarquerez même pas le nom du fichier est parti ou déplacé ou autre chose. C'est même utilisé pour les fichiers temporaires: certaines implémentations créent un fichier et le dissocient immédiatement, il n'est donc pas visible dans le système de fichiers, mais le processus qui l'a créé l'utilise normalement. Le plugin Flash aime particulièrement cette méthode: tous les fichiers vidéo téléchargés sont maintenus ouverts, mais le système de fichiers ne les affiche pas.

Donc, la réponse est, alors que les processus ont toujours les fichiers ouverts, vous ne devriez pas vous attendre à récupérer de l'espace. Il n'est pas libéré, il est activement utilisé. C'est également l'une des raisons pour lesquelles les applications doivent vraiment fermer les fichiers lorsqu'elles ont fini de les utiliser. En utilisation normale, vous ne devriez pas penser à cet espace comme étant gratuit, et cela ne devrait pas non plus être très courant - à l'exception des fichiers temporaires qui sont dissociés exprès, il ne devrait pas y avoir vraiment de fichiers que vous voudriez envisager d'être inutilisé, mais toujours ouvert. Essayez de vérifier s'il existe un processus qui le fait beaucoup et examinez comment vous l'utilisez, ou tout simplement trouver plus d'espace.

orion
la source
24

Les fichiers sont supprimés du système de fichiers où est supprimée toute référence à cet inode. La référence peut être sur le disque (lien dans n'importe quel répertoire) et .. à partir d'applications ouvertes. Si vous supprimez un fichier - vous supprimez uniquement la référence du disque, mais - il y a toujours une référence de l'application.

Vous pouvez "libérer" de l'espace de deux manières:

  1. comme mentionné ci-dessus - vous pouvez tuer l'application, qui ouvre le fichier.
  2. vous pouvez ... tronquer le fichier. Même s'il est supprimé:

Si vous connaissez pid - regardez quels fichiers sont ouverts par ce pid: ls -l / proc / PID / fd vous voyez ici des liens comme:

undefine @ uml: ~ $ ls -l / proc / 18596 / fd
razem 0
lrwx ------ 1 indéfinir indéfinir 64 lut 1 00:06 0 -> / dev / pts / 30
lrwx ------ 1 indéfinir indéfinir 64 lut 1 00:06 1 -> / dev / pts / 30
lrwx ------ 1 indéfinir indéfinir 64 lut 1 00:05 2 -> / dev / pts / 30
lr-x ------ 1 indéfinir indéfinir 64 lut 1 00:06 3 -> / home / indéfinir / x (supprimé)
lr-x ------ 1 indéfinir indéfinir 64 lut 1 00:06 4 -> anon_inode: inotify

Comme vous le voyez, 3 fd est supprimé. vous pouvez le tronquer par commande (par exemple):

undefine @ uml: ~ $:> / proc / 18596 / fd / 3
undefine @ uml: ~ $ 

N'oubliez pas que si l'application lit ce fichier, cela peut être dangereux pour eux. Mais - s'il ne s'agit que d'un fichier journal - vous pouvez le tronquer en toute sécurité.

indéfinir
la source
notez qu'après avoir tronqué le fichier, le processus d'origine qui le contient peut toujours s'ajouter à la fin (où il attend la fin). le résultat est des fichiers apparemment énormes mais clairsemés qui prennent moins d'espace sur le disque (si le système de fichiers prend en charge des fichiers clairsemés) et ils continuent de croître!
törzsmókus
Oui. Si quelque chose écrit dans un fichier, il aura lieu sur le disque. Il est difficile de l'éviter sans arrêter l'application qui écrit sur le disque;)
annuler la définition
8

Comme d'autres l'ont dit, il lsofpeut être utilisé pour répertorier tous les fichiers supprimés qui sont toujours sur le disque en raison des descripteurs de fichiers ouverts. Cependant, cela peut être une très longue liste. Voici une commande qui répertorie ces fichiers triés par taille croissante en octets:

sudo lsof -F sn0 | tr -d '\000' | grep deleted | sed 's/^[a-z]*\([0-9]*\)n/\1 /' | sort -n

Il peut y avoir une façon plus succincte de le faire, mais la commande ci-dessus a fonctionné pour moi.

jcoffland
la source
5

L'espace n'est pas immédiatement libéré car le processus en cours a toujours un descripteur de fichier ouvert sur le fichier qui vient d'être supprimé. Après tout, si un processus essaie toujours d'utiliser un fichier, vous ne voulez probablement pas vraiment que le noyau s'en débarrasse (le fichier). Cela pourrait rendre le processus un peu bouleversé. La meilleure façon (et pour autant que je sache) de libérer de l'espace est de faire exactement ce que vous avez fait - tuer le processus.

John
la source
Une meilleure phrase que «comment ça marche» est probablement «si un processus utilise toujours un fichier, Unix ne devrait pas essayer de s'en débarrasser».
Bratchley
Bon point. J'ai ajouté cela à la réponse.
John
-1

(Mint 17.1)

TL; DR:

  • Inspectez avec sudo baobab(Disk Usage Analyzer).
  • Vider rootla corbeille de l'utilisateur.

Le contexte

J'étais coincé avec un espace sans cesse décroissant alors que je supprimais constamment des fichiers. J'ai installé le trash-clipaquet pour vider la corbeille, mais cela n'a pas aidé. Enfin, j'ai remarqué que lorsque j'ai exécuté baobab(Disk Usage Analyzer dans l'interface graphique, au moins sur Mint 17.1) pour inspecter la structure de l'espace disque, il a donné un avertissement que certains dossiers n'étaient pas accessibles. Je l'ai donc exécuté en rootutilisant sudo baobab. Cela a révélé le problème. Beaucoup de fichiers qui avaient été supprimés étaient dans la poubelle de l' rootutilisateur, pas le mien. Ainsi, je n'ai pas pu libérer de l'espace. Ensuite, j'ai simplement vidé la corbeille en utilisant comme root ( sudo trash-cli) et tout mon espace est revenu.

Deleet
la source
-1

Essayez d'utiliser la commande ci-dessous

lsof | grep deleted

puis tuez le pid du fichier supprimé.

Sumit Tyagi
la source
L'OP est allé aussi loin; cela ne répond pas à leurs questions.
Jeff Schaller