Comment récupérer de l'espace libre sur les fichiers supprimés sans redémarrer les processus de référencement?

12

Lorsque de gros fichiers sont supprimés sur un serveur, les fichiers peuvent toujours être référencés par des processus, de sorte que le système de fichiers ne dispose pas de plus d'espace libre.

J'ai essayé d'utiliser lsof , mais il semble qu'il ne répertorie pas les fichiers supprimés. fuser -ca mieux fonctionné, mais la liste des processus est tout simplement trop longue pour être vérifiée pour chaque processus, d'autant plus que chaque processus est un processus Oracle.

bash-3.2# fuser -c /var
/var:      105o   29999o   20444c    3528c   27258o    7715o    3864o    3862o    2494o   18205o   17450co   17445co   14912co   14824co   14818co   14816o   14814o    8532c    8530c    7633com    7118o    6958o    6790c    6784co    6734o    6693o    6689o    6684o    6675o    6635o    6594c    6548o    6547o    6546o    6545o    6544o    6543o    6542o    6541o    6540o    6537o    6535o    6456o    6128co    6113o     335o     245co     229o     161o       8o
bash-3.2# du -hs /proc
 139T   /proc

Il arrive parfois qu'un fichier soit supprimé par une application ou un utilisateur, par exemple un fichier journal et que ce fichier soit toujours référencé par un processus qui ne peut pas être redémarré.

Existe-t-il des méthodes propres à récupérer de l'espace disque sur les fichiers supprimés sans redémarrer le processus qui fait référence à ce fichier supprimé?

ujjain
la source
pour référence .. une meilleure façon de supprimer un fichier ouvert est de copier / dev / null dans le fichiercp /dev/null file
Mike
@Mike cp /dev/nullest une commande nulle car cpn'a rien à copier, une simple redirection est strictement équivalente :>fileou même>file
jlliagre

Réponses:

12
find /proc/*/fd -ls 2> /dev/null | grep '(deleted)'

Trouvez tous les descripteurs de fichiers ouverts.

Grep supprimé.

StdError à / dev / null

Production:

160448715    0 lrwx------   1 user      user            64 Nov 29 15:34 /proc/28680/fd/113 -> /tmp/vteT3FWPX\ (deleted)

Ou vous pouvez utiliser awk

trouver / proc / * / fd -ls 2> / dev / null | awk '/ supprimé / {print $ 11}';

sortie awk (testée dans bash Ubuntu 12.04):

/proc/28680/fd/113

Recherchez et tronquez tous les fichiers supprimés (testé dans bash Ubuntu 12.04):

(NE FAITES PAS CELA SI VOUS NE SAVEZ PAS CE QUE VOUS FAITES)

find /proc/*/fd -ls 2> /dev/null | awk '/deleted/ {print $11}' | xargs -p -n 1 truncate -s 0

-p invite avant d'exécuter tronquer

La meilleure façon est de tronquer manuellement

Troncature manuelle:

: > /proc/28680/fd/113

ou:

> /proc/28680/fd/113

ou:

truncate -s 0 /proc/28680/fd/113

Prendre plaisir ;)

user3439968
la source
+1, mais j'ai également demandé à sudo d'exécuter ces commandes
79E09796
6

Voici un exemple simple avec less:

Supposons que nous ayons un fichier my10MBfile:

$ dd if=/dev/zero of=/tmp/my10MBfile bs=1M count=10
10+0 enregistrements lus
10+0 enregistrements écrits
10485760 octets (10 MB) copiés, 0,0454491 s, 231 MB/s

$ ls -l /tmp/my10MBfile
-rw-r--r-- 1 max max 10485760 avril 23 22:49 /tmp/my10MBfile

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Maintenant j'ouvre ce fichier avec less(oui, c'est un fichier binaire ... tant pis)

$ less /tmp/my10MBfile &

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile

Ensuite, je supprime ce fichier

$ rm /tmp/my10MBfile

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile (deleted)

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Il est toujours là, mais supprimé. Regardez la 4ème colonne de la sortie lsof: File Descriptor numéro 4 ouvert pour Reading (4r)

Lançons GDB!

$ gdb -p $(pidof less)

GNU gdb (GDB) 7.4.1-debian
....
Attaching to process 29351
....

(gdb) p close(4)
$1 = 0
(gdb) q

C'est ça!

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9215       4672  67% /

Nos 10 Mo sont les bienvenus :)

$ ls /proc/29351/fd
0  1  2  3

$ ps 29351
29351 pts/0    S+     0:00 less /tmp/my10MBfile

Le processus est toujours en cours.

maxxvw
la source
2
D'accord, mais pour combien de temps? de nombreux processus se terminent simplement s'ils ne peuvent pas écrire dans leur fichier journal.
longneck
Logrotate ne peut pas faire ça pour vous?
maxxvw
logrotate envoie au processus un signal pour fermer le fichier journal et en ouvrir un nouveau.
longneck
2

Cette commande affichera tous les fichiers supprimés encore ouverts sur un système Solaris:

find /proc/*/fd -type f -links 0

Vous pouvez tronquer ceux que vous êtes sûr de vouloir avec cette commande:

:> /proc/p/fd/x

avec p étant l'identifiant du processus et x le descripteur de fichier renvoyé par la première commande.

Ne vous inquiétez pas si avec certains programmes, la taille indiquée par lsest restaurée à la taille avant la troncature après un certain temps, la taille réelle utilisée sur le disque sera beaucoup plus petite car le fichier est maintenant clairsemé.

jlliagre
la source
0

Vous pouvez essayer d'aller dans le /proc/<pid>/fdrépertoire et de tronquer le descripteur de fichier correspondant. Disons que fd = 3 points pour le fichier supprimé de pid == 123:

# echo "" >! /proc/123/fd/3
kofemann
la source
avez-vous un exemple où cette méthode fonctionne? Impossible de trouver un moyen de modifier FD à partir de là
maxxvw
Oui, cela fonctionne, mais comment trouver le pid du processus?
ujjain
-2

Aucune de ces solutions n'a fonctionné pour moi. Ce n'est qu'après avoir utilisé Bleachbit en tant que root que j'ai pu libérer correctement l'espace associé aux fichiers supprimés.

user189721
la source