Wie findet man große Dateien, die gelöscht wurden, aber noch in einer Anwendung geöffnet sind? Wie kann man eine solche Datei entfernen, obwohl ein Prozess sie geöffnet hat?
Die Situation ist, dass wir einen Prozess ausführen, der eine Protokolldatei mit einer hervorragenden Geschwindigkeit füllt. Ich kenne den Grund und kann ihn beheben. Bis dahin möchte ich die Protokolldatei speichern oder leeren, ohne den Prozess zu beenden.
Durch einfaches Ausführen werden rm output.log
nur Verweise auf die Datei entfernt, der Speicherplatz auf der Festplatte wird jedoch weiterhin belegt, bis der Vorgang beendet wird. Schlimmer noch: rm
Ich habe jetzt keine Möglichkeit herauszufinden, wo sich die Datei befindet oder wie groß sie ist! Gibt es eine Möglichkeit, die Datei zu finden und möglicherweise zu leeren, obwohl sie in einem anderen Prozess noch geöffnet ist?
Ich beziehe mich speziell auf Linux-basierte Betriebssysteme wie Debian oder RHEL.
quelle
lsof -p <pid>
geöffneten Dateien und deren Größe auflisten.(deleted)
Neben der gelöschten Datei befindet sich ein . Die gelöschte Datei wird/proc/<pid>/fd/1
wahrscheinlich um verlinkt . Ich weiß nicht, wie ich einen Prozess stoppen kann, ohne ihn zu beenden. Ich würde denken, dass das vom Prozess abhängen würde.rm
noch geöffneten ed-Dateien erhalten?lsof | grep "(deleted)"
. Wenn keine Prozesse mehr vorhanden sind, bei denen eine gelöschte Datei geöffnet ist, gibt der Kernel die Inode- und Festplattenblöcke frei. Prozesse haben keine "Handler", mit denen sie benachrichtigt werden können, dass eine offene, im Wesentlichen gesperrte Datei von der Festplatte entfernt wurde.lsof | grep '(deleted)'
funktioniert auch unter Linux. Unter Linux können Sie Löschen von Dateien benachrichtigt werden (auch Dateien , die bereits keinen Eintrag andere in einem beliebigen Verzeichnis haben als / proc / some-pid / fd mehr) mit dem inotify Mechanismus (IN_DELETE_SELF Ereignis)somefile
es in VIM erstellt und geöffnet und es dannrm
in einem anderen Bash-Prozess bearbeitet. Ich laufe dannlsof | grep somefile
und es ist nicht drin, obwohl die Datei in VIM geöffnet ist.Antworten:
Wenn Sie Ihre Anwendung nicht beenden können, können Sie die Protokolldatei abschneiden, anstatt sie zu löschen, um den Speicherplatz freizugeben. Wenn die Datei nicht im Anfügemodus (mit
O_APPEND
) geöffnet war , wird die Datei beim nächsten Schreiben so groß wie zuvor angezeigt (obwohl der führende Teil spärlich ist und so aussieht, als ob er NUL-Bytes enthält), aber der Speicherplatz wird zurückgefordert (dies gilt jedoch nicht für HFS + -Dateisysteme unter Apple OS / X, die keine Sparse-Dateien unterstützen).So kürzen Sie es:
Wenn es unter Linux bereits gelöscht wurde, können Sie es dennoch abschneiden, indem Sie folgende Schritte ausführen:
Wo
$pid
ist die Prozess - ID des Prozesses, der die Datei geöffnet hat, und$fd
ein Dateideskriptor hat es unter geöffnet (die Sie überprüfen mit kannlsof -p "$pid"
.Wenn Sie die PID nicht kennen und nach gelöschten Dateien suchen, können Sie Folgendes tun:
lsof -nP +L1
, wie von @ user75021 erwähnt, ist eine noch bessere (zuverlässigere und portablere) Option (Dateien mit weniger als 1 Link auflisten ).Oder (unter Linux):
Oder um die Großen zu finden mit
zsh
:Eine Alternative, wenn die Anwendung dynamisch verknüpft ist, besteht darin, einen Debugger an sie anzuhängen und ihn aufzurufen,
close(fd)
gefolgt von einem neuenopen("the-file", ....)
.quelle
truncate
Befehl, der dasselbe expliziter ausführt.lsof
ist wahrscheinlich die Lösung, die einer portablen Lösung am nächsten kommt, mit der Sie offene Dateien auflisten können. Der Debugger-Ansatz zum Schließen des fd unter den Anwendungsfüßen sollte ebenfalls portabel sein.df -k | awk 'NR>1 { print $NF }' | xargs fuser -Vud
(und dann einfach Signale an die Täter zu senden, um sie zur Freigabe des fd zu zwingen)lsof +L1
. Auf der lsof-Manpage: "Eine Spezifikation des Formulars+L1
wählt offene Dateien aus, die nicht verknüpft wurden. Eine Spezifikation des Formulars+aL1 <file_system>
wählt nicht verknüpfte offene Dateien im angegebenen Dateisystem aus." Das sollte ein bisschen zuverlässiger sein als Greifen.Überprüfen Sie die Schnellstart - out hier:
lsof
QuickstartIch bin überrascht, dass niemand die lsof-Schnellstartdatei erwähnt hat (in lsof enthalten). Abschnitt "3.a" zeigt, wie offene, nicht verknüpfte Dateien gefunden werden:
Z.B:
Auf Red Hat-Systemen gehe ich normalerweise folgendermaßen vor, um die lokale Kopie der Schnellstartdatei zu finden:
... oder dieses:
quelle
Es liegt Fahrer auf das Dateisystem tatsächlich befreien den zugewiesenen Speicherplatz, und das wird in der Regel nur einmal passiert alle Dateideskriptoren auf diese Datei beziehen freigegeben werden. Sie können den Speicherplatz also nicht wirklich zurückfordern, es sei denn, Sie veranlassen die Anwendung, die Datei zu schließen. Was bedeutet, dass Sie es entweder beenden oder "ein bisschen" in einem Debugger damit spielen (z. B. die Datei schließen und sicherstellen, dass sie nicht erneut geöffnet / beschrieben wird, oder
/dev/null
stattdessen öffnen ). Oder Sie könnten den Kernel hacken, aber ich würde davon abraten.Das Kürzen der Datei, wie von Stephane vorgeschlagen, kann hilfreich sein, das tatsächliche Ergebnis hängt jedoch auch von Ihrem Dateisystem ab (z. B. werden vorab zugewiesene Blöcke wahrscheinlich erst freigegeben, nachdem Sie die Datei in jedem Fall geschlossen haben).
Der Grund für dieses Verhalten ist, dass der Kernel nicht weiß, was mit Datenanforderungen (Lesen und Schreiben, aber Lesen ist tatsächlich kritischer) zu tun ist, die auf eine solche Datei abzielen.
quelle
fallocate
Linux 4.9 zugewiesen wurden . Können Sie bitte klären, unter welchen Dateisystemen und Bedingungen das Abschneiden einer Datei keinen Speicherplatz beansprucht?