Wie kann ich freien Speicherplatz für gelöschte Dateien wiederherstellen, ohne die Referenzierungsprozesse neu zu starten?

11

Wenn große Dateien auf einem Server gelöscht werden, werden die Dateien möglicherweise weiterhin von Prozessen referenziert, sodass das Dateisystem nicht über mehr freien Speicherplatz verfügt.

Ich habe versucht, lsof zu verwenden , aber es scheint, dass die gelöschten Dateien nicht aufgelistet wurden. fuser -chat besser funktioniert, aber die Liste der Prozesse ist einfach zu lang, um sie für jeden Prozess zu überprüfen, zumal jeder Prozess ein Oracle-Prozess ist.

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

Es kommt manchmal vor, dass eine Datei von einer Anwendung oder einem Benutzer gelöscht wird, z. B. eine Protokolldatei, und dass auf diese Datei immer noch von einem Prozess verwiesen wird, der nicht neu gestartet werden kann.

Gibt es Warenmethoden, um Speicherplatz für gelöschte Dateien zurückzugewinnen, ohne den Prozess neu zu starten, der einen Verweis auf diese gelöschte Datei enthält?

ujjain
quelle
als Referenz .. eine bessere Möglichkeit, eine geöffnete Datei zu löschen, besteht darin, / dev / null in die Datei zu kopierencp /dev/null file
Mike
@ Mike cp /dev/nullist ein Null-Befehl, da cpnichts zu kopieren ist, eine einfache Umleitung ist streng gleichwertig :>fileoder sogar>file
jlliagre

Antworten:

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

Finden Sie alle geöffneten Dateideskriptoren.

Grep gelöscht.

StdError nach / dev / null

Ausgabe:

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

Oder Sie können awk verwenden

find / proc / * / fd -ls 2> / dev / null | awk '/ gelöscht / {print $ 11}';

awk Ausgabe (getestet in Bash Ubuntu 12.04):

/proc/28680/fd/113

Suchen und kürzen Sie alle gelöschten Dateien (getestet in Bash Ubuntu 12.04):

(TUN SIE DAS NICHT, WENN SIE NICHT WISSEN, WAS SIE TUN)

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

-p Eingabeaufforderung vor dem Ausführen abschneiden

Besser ist manuelles Abschneiden

Manuelles Abschneiden:

: > /proc/28680/fd/113

oder:

> /proc/28680/fd/113

oder:

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

Genießen ;)

user3439968
quelle
+1, aber ich brauchte auch sudo, um diese Befehle auszuführen
79E09796
6

Hier ist ein einfaches Beispiel mit less:

Nehmen wir an, wir haben eine Datei 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% /

Jetzt öffne ich diese Datei mit less(ja, es ist eine Binärdatei ... egal)

$ less /tmp/my10MBfile &

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

Dann entferne ich diese Datei

$ 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% /

Es ist noch da, aber gelöscht. Schauen Sie sich die 4. Spalte der lsof-Ausgabe an: Dateideskriptor Nummer 4 zum Lesen geöffnet (4r)

Lassen Sie uns GDB ausführen!

$ gdb -p $(pidof less)

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

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

Das ist es!

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

Unsere 10 MB sind willkommen zurück :)

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

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

Der Prozess läuft noch.

maxxvw
quelle
2
Ok, aber wie lange noch? Viele Prozesse werden einfach beendet, wenn sie nicht in ihre Protokolldatei schreiben können.
Longneck
Logrotate kann das nicht für Sie tun?
Maxxvw
logrotate sendet dem Prozess ein Signal zum Schließen der Protokolldatei und zum Öffnen einer neuen.
Longneck
2

Dieser Befehl zeigt alle gelöschten Dateien an, die auf einem Solaris-System noch geöffnet sind:

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

Mit diesem Befehl können Sie diejenigen abschneiden, von denen Sie sicher sind, dass Sie sie möchten:

:> /proc/p/fd/x

Dabei ist p die Prozess-ID und x der vom ersten Befehl zurückgegebene Dateideskriptor.

Machen Sie sich keine Sorgen, wenn bei einigen Programmen die gemeldete lsGröße vor dem Abschneiden nach einer Weile auf die Größe zurückgesetzt wird. Die tatsächlich auf der Festplatte verwendete Größe ist viel kleiner, da die Datei jetzt spärlich ist.

jlliagre
quelle
0

Sie können versuchen, in das /proc/<pid>/fdVerzeichnis zu wechseln und den entsprechenden Dateideskriptor abzuschneiden. Angenommen, fd = 3 zeigt auf die gelöschte Datei von pid == 123:

# echo "" >! /proc/123/fd/3
kofemann
quelle
Haben Sie ein Beispiel, wo diese Methode funktioniert? Kann keinen Weg finden, FD von dort zu ändern
maxxvw
Ja, das funktioniert, aber wie findet man die PID des Prozesses?
Ujjain
-2

Keine dieser Lösungen hat bei mir funktioniert. Erst nachdem ich Bleachbit als Root verwendet hatte, konnte ich den mit gelöschten Dateien verbundenen Speicherplatz ordnungsgemäß freigeben.

user189721
quelle