Wie kann ich die Inode-Nutzung freigeben?


274

Ich habe ein Festplattenlaufwerk, auf dem die Inode-Auslastung 100% beträgt (mit df -iBefehl). Nach dem wesentlichen Löschen von Dateien bleibt die Nutzung jedoch 100%.

Was ist dann der richtige Weg?

Wie ist es möglich, dass ein Festplattenlaufwerk mit weniger Speicherplatznutzung eine höhere Inode-Auslastung aufweist als ein Festplattenlaufwerk mit einer höheren Speicherplatzauslastung?

Ist es möglich, wenn ich viele Dateien komprimiere, würde dies die Anzahl der verwendeten Inodes verringern?


4
Möchten Sie 50 Punkte für diese Frage geben. Wie kann ich! :)
Sophy

@Sophy Tu das nicht. Sie werden automatisch gebannt
Steven Lu

1
@StevenLu Danke für deine Infos! Ich möchte ihm Ehre machen, weil ich ein paar Tage damit verbracht habe, mein Problem zu lösen. Aber dieses Problem kann mir helfen.
Nochmals

1
@Sophy: Warum etwas Off-Topic für SO vergeben? :) Das ist definitiv keine Programmierfrage, egal wie viele Upvotes es bekommt.
Tink

Leere Verzeichnisse verbrauchen auch Inodes. Durch Löschen können einige Inodes freigesetzt werden. Die Anzahl kann in einigen Anwendungsfällen erheblich sein. Sie können leere Verzeichnisse löschen mit: find. -type d -empty -delete
Ruchit Patel

Antworten:


170

Es ist ziemlich einfach für eine Festplatte, eine große Anzahl von Inodes zu verwenden, selbst wenn die Festplatte nicht sehr voll ist.

Ein Inode wird einer Datei zugewiesen. Wenn Sie also Millionen von Dateien mit jeweils 1 Byte haben, gehen Ihnen die Inodes aus, lange bevor Ihnen die Festplatte ausgeht.

Es ist auch möglich, dass das Löschen von Dateien die Inode-Anzahl nicht verringert, wenn die Dateien mehrere feste Links haben. Wie gesagt, Inodes gehören zur Datei, nicht zum Verzeichniseintrag. Wenn mit einer Datei zwei Verzeichniseinträge verknüpft sind, wird durch Löschen eines Eintrags der Inode nicht freigegeben.

Darüber hinaus können Sie einen Verzeichniseintrag löschen. Wenn jedoch bei einem laufenden Prozess die Datei noch geöffnet ist, wird der Inode nicht freigegeben.

Mein erster Rat wäre, alle Dateien zu löschen, die Sie können, und dann die Box neu zu starten, um sicherzustellen, dass keine Prozesse übrig bleiben, die die Dateien offen halten.

Wenn Sie dies tun und immer noch ein Problem haben, lassen Sie es uns wissen.

Übrigens, wenn Sie nach Verzeichnissen suchen, die viele Dateien enthalten, kann dieses Skript helfen:

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$

12
Natürlich >/tmp/count_em_$$funktioniert das nur, wenn Sie Platz dafür haben ... wenn dies der Fall ist, lesen Sie die Antwort von @ simon.
Alxndr

1
@alxndr, deshalb ist es oft eine gute Idee, Ihre Dateisysteme getrennt zu halten. Auf diese Weise wirkt sich das Auffüllen /tmpnicht auf Ihre anderen Dateisysteme aus.
Paxdiablo

Ihre Antwort ist perfekt geeignet für "Das System wird die Datei nach dem Neustart nicht mehr verwenden, wenn diese gelöscht wurde". Es wurde jedoch die Frage gestellt, wie die Inodes nach dem Löschen des Inode-Zeigers zurückgefordert oder wiederverwendet werden können. Grundsätzlich erstellt der Linux-Kernel bei jeder Erstellung einen neuen Inode für eine Datei und fordert den Inode beim Löschen einer Datei automatisch nicht zurück.
Mohanraj

1
@AshishKarpe, ich nehme an, Sie sprechen über Ihre eigene Situation, da das OP keine Produktionsserver erwähnt hat. Wenn Sie nicht sofort neu starten können, gibt es zwei Möglichkeiten. Hoffen Sie zunächst, dass die laufenden Prozesse die aktuellen Dateien schließen, damit Festplattenressourcen freigegeben werden können. Zweitens sollten selbst Produktionsserver irgendwann einen Neustart durchführen können - planen Sie einfach geplante Ausfallzeiten oder warten Sie, bis das nächste Fenster mit Ausfallzeiten angezeigt wird.
Paxdiablo

2
Ich nehme an, Sie wollen ls -Astatt ls -a. Warum willst du zählen? und ..?
Jarno

205

Wenn Sie sehr unglücklich sind, haben Sie ungefähr 100% aller Inodes verwendet und können den Scipt nicht erstellen. Sie können dies mit überprüfen df -ih.

Dann kann Ihnen dieser Bash-Befehl helfen:

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

Und ja, das wird einige Zeit dauern, aber Sie können das Verzeichnis mit den meisten Dateien finden.


8
das macht den Trick. Mein Problem war, unglaublich viele Sitzungen im Verzeichnis / lib / php / session zu haben. Vielleicht hat jemand das gleiche Problem
SteMa

2
Jemand sollte diese Find, Cut, Uniq-Sortierung in einen einzigen awk-Befehl umschreiben!
Mogsie

5
@alxndr awkkönnte einen Hash des Verzeichnisses und der Anzahl der Dateien behalten, ohne eine Unmenge von Zeilen zu vereinheitlichen und zu sortieren. Das heißt, vielleicht ist hier eine Verbesserung: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- Dies sortiert nur die letzte Liste.
Mogsie

12
Wenn Sie keine Dateien erstellen können, kann auch dies fehlschlagen, da sortmöglicherweise nicht alles im Speicher bleibt und versucht wird, automatisch auf das Schreiben einer temporären Datei zurückzugreifen. Ein Prozess, der offensichtlich scheitern würde ...
Mikko Rantalainen

10
sortscheiterte für mich, aber ich konnte geben, --buffer-size=10Gwas funktionierte.
Frederick Nord

69

Meine Situation war, dass ich keine Inodes mehr hatte und bereits alles gelöscht hatte, was ich konnte.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

Ich bin auf einem Ubuntu 12.04LTS und konnte die alten Linux-Kernel nicht entfernen, die ungefähr 400.000 Inodes beanspruchten, weil apt wegen eines fehlenden Pakets kaputt war. Und ich konnte das neue Paket nicht installieren, weil ich keine Inodes mehr hatte und feststeckte.

Am Ende habe ich ein paar alte Linux-Kernel von Hand gelöscht, um ungefähr 10.000 Inodes freizugeben

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

Dies war genug, um mich dann das fehlende Paket installieren und meine Wohnung reparieren zu lassen

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

und entfernen Sie dann den Rest der alten Linux-Kernel mit apt

$ sudo apt-get autoremove

Die Dinge sind jetzt viel besser

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /

3
Dies kam meinem eigenen Ansatz in einer ähnlichen Situation am nächsten. Es ist erwähnenswert, dass ein vorsichtigerer Ansatz unter help.ubuntu.com/community/Lubuntu/Documentation/…
beldaz

Mein Fall genau! Aber musste "sudo apt-get autoremove -f" verwenden, um voranzukommen
Tony Sepia

Ist es sicher, dies zu tun: sudo rm -rf /usr/src/linux-headers-3.2.0-2*Wenn ich sicher bin, dass ich diesen Kernel nicht benutze?
Mars Lee

@ MarsLee Sie können überprüfen, welcher Kernel derzeit mit "uname -a" ausgeführt wird
Dominique Eav

$ sudo apt-get autoremoveAllein anrufen , hat den Trick für mich getan.
Morten Grum

49

Meine Lösung:

Versuchen Sie herauszufinden, ob dies ein Inodes-Problem ist mit:

df -ih

Versuchen Sie, Stammordner mit einer großen Anzahl von Inodes zu finden:

for i in /*; do echo $i; find $i |wc -l; done

Versuchen Sie, bestimmte Ordner zu finden:

for i in /src/*; do echo $i; find $i |wc -l; done

Wenn dies Linux-Header sind, versuchen Sie, die ältesten zu entfernen mit:

sudo apt-get autoremove linux-headers-3.13.0-24

Persönlich habe ich sie in einen bereitgestellten Ordner verschoben (weil für mich der letzte Befehl fehlgeschlagen ist) und die neueste Version installiert mit:

sudo apt-get autoremove -f

Dies löste mein Problem.


1
In meinem Fall war das Problem SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -fhat den Job gemacht :) Danke!
Joystick

4
Für mich dauerte das Stunden. Es gibt jedoch eine einfache Lösung: Wenn der zweite Befehl in einem bestimmten Verzeichnis hängt, beenden Sie den aktuellen Befehl und starten Sie die Änderung von / * in das Verzeichnis, in dem er sich befand. Ich konnte bis zur <Minute des Täters einen Drilldown durchführen.
Michael Terry

Ich habe diese Variante Ihres Befehls verwendet, um die Zahlen in derselben Zeile zu drucken: for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker

for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -10Zeigen Sie die 10 größten Verzeichnisse
Mark Simon

12

Ich hatte das gleiche Problem, behoben es durch Entfernen der Verzeichnissitzungen von PHP

rm -rf /var/lib/php/sessions/

Es kann unter sein, /var/lib/php5wenn Sie eine ältere PHP-Version verwenden.

Erstellen Sie es mit der folgenden Berechtigung neu

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

Standardmäßige Berechtigung für Verzeichnis auf Debian angezeigt drwx-wx-wt(1733)


1
Irgendeine Idee, warum das passiert?
Sibidharan

1
@Sibidharan in meinem Fall war es, weil der PHP-Cron-Job zum Löschen der alten PHP-Sitzungen nicht funktionierte.
grimmig

3
rm -rf /var/lib/php/sessions/*wäre wahrscheinlich ein besserer Befehl - es wird nicht das Sitzungsverzeichnis entfernen, nur seinen Inhalt ... Dann müssen Sie sich keine Sorgen mehr machen, es neu zu erstellen
Shadow

Ich hatte keine PHP-Sitzung, sondern ein Magento-Sitzungsproblem, ähnlich wie dieses. Danke für die Richtung.
Mohit

PHP-Sitzungen sollten nicht über Cron-Jobs gelöscht werden. Setzen Sie

2

Wir haben dies auf einem HostGator-Konto (das allen Hosting-Inode-Beschränkungen auferlegt) nach einem Spam-Angriff erlebt. Es hat eine große Anzahl von Warteschlangendatensätzen in /root/.cpanel/comet hinterlassen. Wenn dies passiert und Sie feststellen, dass Sie keine freien Inodes haben, können Sie dieses cpanel-Dienstprogramm über die Shell ausführen:

/usr/local/cpanel/bin/purge_dead_comet_files

2

Sie können RSYNC verwenden, um die große Anzahl von Dateien zu löschen

rsync -a --delete blanktest/ test/

Erstellen Sie einen blanktest-Ordner mit 0 Dateien, und der Befehl synchronisiert Ihre Testordner mit einer großen Anzahl von Dateien (ich habe fast 5 Millionen Dateien mit dieser Methode gelöscht).

Vielen Dank an http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux


Nach dem, was ich aus dem Artikel / den Kommentaren ersehen kann, ist dies schneller als rm *bei vielen Dateien, da der Platzhalter erweitert und jedes Argument übergeben / verarbeitet wird. Es ist jedoch rm test/in Ordnung, einen test/Ordner mit vielen Dateien zu löschen .
mwfearnley

Heads up, das funktioniert gut, aber stellen Sie sicher, dass Sie die Berechtigungen für das leere Verzeichnis richtig eingestellt haben! Ich habe dies nicht getan und versehentlich die Berechtigungen für mein PHP-Sitzungsverzeichnis geändert. Es dauerte zwei Stunden, um herauszufinden, was ich vermasselt habe.
aecend

1

eaccelerator könnte das Problem verursachen, da es PHP in Blöcke kompiliert ... Ich hatte dieses Problem mit einem Amazon AWS-Server auf einer Site mit hoher Last. Geben Sie Inodes frei, indem Sie den eaccelerator-Cache in / var / cache / eaccelerator löschen, wenn Sie weiterhin Probleme haben.

rm -rf /var/cache/eaccelerator/*

(oder was auch immer dein Cache-Verzeichnis ist)


1

In letzter Zeit hatten wir ein ähnliches Problem: Wenn sich ein Prozess auf eine gelöschte Datei bezieht, wird der Inode nicht freigegeben. Sie müssen also lsof / überprüfen und kill / restart. Der Prozess gibt die Inodes frei.

Korrigieren Sie mich, wenn ich hier falsch liege.


1

Wie bereits erwähnt, gehen dem Dateisystem möglicherweise die Inodes aus, wenn viele kleine Dateien vorhanden sind. Ich habe einige Mittel bereitgestellt, um Verzeichnisse zu finden, die die meisten Dateien hier enthalten .


0

Späte Antwort: In meinem Fall waren es meine Sitzungsdateien unter

/var/lib/php/sessions

das waren Inodes.
Ich konnte sogar nicht meine Crontab öffnen oder ein neues Verzeichnis erstellen, geschweige denn den Löschvorgang auslösen. Da ich PHP verwende, haben wir dieses Handbuch, in dem ich den Code aus Beispiel 1 kopiert und einen Cronjob eingerichtet habe, um diesen Teil des Codes auszuführen.

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

Wenn Sie sich fragen, wie ich es geschafft habe, meine Crontab zu öffnen, habe ich einige Sitzungen manuell über die CLI gelöscht.

Hoffe das hilft!


0

Sie konnten diese Informationen sehen

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t

-2

Bisher gibt es viele Antworten auf diese Frage, und alle oben genannten Fragen scheinen konkret zu sein. Ich denke, Sie werden sicher sein, statwenn Sie im Laufe der Zeit verwenden, aber je nach Betriebssystem können sich einige Inode-Fehler auf Sie einschleichen. Die Implementierung Ihrer eigenen statAnruffunktionalität 64bitzur Vermeidung von Überlaufproblemen scheint daher ziemlich kompatibel zu sein.


wir lieben Beispiele hier bei so;)
Bohne

-3

Wenn Sie Docker verwenden, entfernen Sie alle Bilder. Sie nutzten viel Platz ....

Stoppen Sie alle Container

docker stop $(docker ps -a -q)

Löschen Sie alle Container

docker rm $(docker ps -a -q)

Löschen Sie alle Bilder

docker rmi $(docker images -q)

Funktioniert für mich


Dies hilft nicht zu erkennen, ob "zu viele Inodes" das Problem sind.
Mark Stosberg

Dies hat nichts mit Docker zu tun.
Urda
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.