it-swarm.com.de

Wie behebt man zeitweise auftretende Fehler "Kein Speicherplatz mehr auf dem Gerät" während mv, wenn das Gerät über ausreichend Speicherplatz verfügt?

  • Ubuntu 14.04 auf einem Desktop
  • Quelllaufwerk:/dev/sda1: 5 TB ext4 single
    Laufwerkslautstärke
  • Ziel-Volume:/dev/mapper/archive-lvarchive: raid6 (mdadm) 18-TB-Volume mit lvm
    Partition und ext4

Es müssen ungefähr 15 Millionen Dateien verschoben werden, und einige können Duplikate sein (ich möchte keine Duplikate überschreiben).

Der verwendete Befehl (aus dem Quellverzeichnis) war:

ls -U |xargs -i -t mv -n {} /mnt/archive/targetDir/{}

Dies ist erwartungsgemäß seit einigen Tagen so, aber ich bekomme den Fehler, die Häufigkeit zu erhöhen. Als es gestartet wurde, war das Ziellaufwerk zu etwa 70% voll, jetzt zu etwa 90%. Früher waren es ungefähr 1/200 der Züge, die Status und Fehler anzeigen, jetzt sind es ungefähr 1/5. Keine der Dateien ist größer als 100 MB, die meisten sind ungefähr 100.000

Einige Infos:

$ df -h
Filesystem                     Size  Used Avail Use% Mounted on
/dev/sdb3                      155G  5.5G  142G   4% /
none                           4.0K     0  4.0K   0% /sys/fs/cgroup
udev                           3.9G  4.0K  3.9G   1% /dev
tmpfs                          797M  2.9M  794M   1% /run
none                           5.0M  4.0K  5.0M   1% /run/lock
none                           3.9G     0  3.9G   0% /run/shm
none                           100M     0  100M   0% /run/user
/dev/sdb1                       19G   78M   18G   1% /boot
/dev/mapper/archive-lvarchive   18T   15T  1.8T  90% /mnt/archive
/dev/sda1                      4.6T  1.1T  3.3T  25% /mnt/tmp

$ df -i
Filesystem                       Inodes    IUsed     IFree IUse% Mounted on
/dev/sdb3                      10297344   222248  10075096    3% /
none                            1019711        4   1019707    1% /sys/fs/cgroup
udev                            1016768      500   1016268    1% /dev
tmpfs                           1019711     1022   1018689    1% /run
none                            1019711        5   1019706    1% /run/lock
none                            1019711        1   1019710    1% /run/shm
none                            1019711        2   1019709    1% /run/user
/dev/sdb1                       4940000      582   4939418    1% /boot
/dev/mapper/archive-lvarchive 289966080 44899541 245066539   16% /mnt/archive
/dev/sda1                     152621056  5391544 147229512    4% /mnt/tmp

Hier ist meine Ausgabe:

mv -n 747265521.pdf /mnt/archive/targetDir/747265521.pdf 
mv -n 61078318.pdf /mnt/archive/targetDir/61078318.pdf 
mv -n 709099107.pdf /mnt/archive/targetDir/709099107.pdf 
mv -n 75286077.pdf /mnt/archive/targetDir/75286077.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/75286077.pdf’: No space left on device
mv -n 796522548.pdf /mnt/archive/targetDir/796522548.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/796522548.pdf’: No space left on device
mv -n 685163563.pdf /mnt/archive/targetDir/685163563.pdf 
mv -n 701433025.pdf /mnt/archive/targetDir/701433025.pd

Ich habe viele Beiträge zu diesem Fehler gefunden, aber die Prognose passt nicht. Probleme wie "Ihr Laufwerk ist tatsächlich voll" oder "Sie haben keine Inodes mehr" oder sogar "Ihr/Boot-Volume ist voll". Meistens handelt es sich jedoch um Software von Drittanbietern, die aufgrund des Umgangs mit den Dateien ein Problem verursacht, und sie sind alle konstant, was bedeutet, dass JEDE Verschiebung fehlschlägt.

Vielen Dank.

BEARBEITEN: Hier ist ein Beispiel fehlgeschlagene und erfolgreiche Datei:

FEHLGESCHLAGEN (immer noch auf dem Quelllaufwerk)

ls -lhs 702637545.pdf
16K -rw-rw-r-- 1 myUser myUser 16K Jul 24 20:52 702637545.pdf

SUCCEEDED (auf Zielvolumen)

ls -lhs /mnt/archive/targetDir/704886680.pdf
104K -rw-rw-r-- 1 myUser myUser 103K Jul 25 01:22 /mnt/archive/targetDir/704886680.pdf

Auch wenn nicht alle Dateien fehlschlagen, schlägt eine fehlgeschlagene Datei IMMER fehl. Wenn ich es immer wieder versuche, ist es konsistent.

BEARBEITEN: Einige zusätzliche Befehle pro Anfrage von @mjturner

$ ls -ld /mnt/archive/targetDir
drwxrwxr-x 2 myUser myUser 1064583168 Aug 10 05:07 /mnt/archive/targetDir

$ tune2fs -l /dev/mapper/archive-lvarchive
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/archive
Filesystem UUID:          af7e7b38-f12a-498b-b127-0ccd29459376
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr dir_index filetype needs_recovery extent 64bit flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              289966080
Block count:              4639456256
Reserved block count:     231972812
Free blocks:              1274786115
Free inodes:              256343444
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         2048
Inode blocks per group:   128
RAID stride:              128
RAID stripe width:        512
Flex block group size:    16
Filesystem created:       Thu Jun 25 12:05:12 2015
Last mount time:          Mon Aug  3 18:49:29 2015
Last write time:          Mon Aug  3 18:49:29 2015
Mount count:              8
Maximum mount count:      -1
Last checked:             Thu Jun 25 12:05:12 2015
Check interval:           0 (<none>)
Lifetime writes:          24 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      3ea3edc4-7638-45cd-8db8-36ab3669e868
Journal backup:           inode blocks

$ tune2fs -l /dev/sda1
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/tmp
Filesystem UUID:          10df1bea-64fc-468e-8ea0-10f3a4cb9a79
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              152621056
Block count:              1220942336
Reserved block count:     61047116
Free blocks:              367343926
Free inodes:              135953194
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      732
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         4096
Inode blocks per group:   256
Flex block group size:    16
Filesystem created:       Thu Jul 23 13:54:13 2015
Last mount time:          Tue Aug  4 04:35:06 2015
Last write time:          Tue Aug  4 04:35:06 2015
Mount count:              3
Maximum mount count:      -1
Last checked:             Thu Jul 23 13:54:13 2015
Check interval:           0 (<none>)
Lifetime writes:          150 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      a266fec5-bc86-402b-9fa0-61e2ad9b5b50
Journal backup:           inode blocks
21
Chris.Caldwell

Fehler bei der Implementierung der ext4-Funktion dir_index, die Sie in Ihrem Zieldateisystem verwenden.

Lösung: Erstellen Sie das Dateisystem ohne dir_index neu. Oder deaktivieren Sie die Funktion mit tune2fs (Vorsicht geboten, siehe verwandten Link Novell SuSE 10/11: Deaktivieren der H-Tree-Indizierung in einem ext3-Dateisystem , die sich zwar auf ext3 bezieht erfordert möglicherweise ähnliche Vorsicht.

(get a really good backup made of the filesystem)
(unmount the filesystem)
tune2fs -O ^dir_index /dev/foo
e2fsck -fDvy /dev/foo
(mount the filesystem)

ext4 verfügt standardmäßig über eine Funktion namens dir_index, die sehr anfällig für Hash-Kollisionen ist.

......

ext4 hat die Möglichkeit, die Dateinamen seines Inhalts zu hashen. Dies verbessert die Leistung, hat jedoch ein „kleines“ Problem: ext4 vergrößert seine Hashtabelle nicht, wenn es zu füllen beginnt. Stattdessen wird -ENOSPC oder "kein Speicherplatz mehr auf dem Gerät" zurückgegeben.

26
steve

Vorschläge für eine bessere Auswahl als ext4 zum Speichern von Massen kleiner Dateien:

Wenn Sie das Dateisystem als Objektspeicher verwenden, sollten Sie ein Dateisystem verwenden, das darauf spezialisiert ist, möglicherweise zum Nachteil anderer Merkmale. Eine schnelle Google-Suche fand Ceph , das Open Source zu sein scheint und als POSIX-Dateisystem bereitgestellt werden kann, aber auch mit anderen APIs aufgerufen werden kann. Ich weiß nicht, ob es sich lohnt, auf einem einzelnen Host zu arbeiten, ohne die Replikation zu nutzen.

Ein weiteres Objektspeichersystem ist OpenStacks Swift . In den Designdokumenten heißt es speichert jedes Objekt als separate Datei mit Metadaten in xattrs . Hier ist ein Artikel darüber. Ihr Bereitstellungshandbuch besagt, dass XFS die beste Leistung für die Objektspeicherung erbracht hat. Obwohl die Arbeitslast nicht die beste ist, in der XFS am besten ist, war sie anscheinend besser als die Konkurrenz, als RackSpace Dinge testete. Möglicherweise bevorzugt Swift XFS, da XFS erweiterte Attribute gut/schnell unterstützt. Es kann sein, dass ext3/ext4 auf einzelnen Datenträgern als Objektspeicher-Backend in Ordnung ist, wenn keine zusätzlichen Metadaten benötigt werden (oder wenn sie in der Binärdatei gespeichert werden).

Swift übernimmt die Replikation/den Lastenausgleich für Sie und schlägt vor, dass Sie ihm Dateisysteme geben, die auf Raw-Festplatten erstellt wurden, nicht RAID. Es wird darauf hingewiesen, dass die Arbeitslast für RAID5 im Wesentlichen der schlechteste Fall ist (was sinnvoll ist, wenn es sich um eine Arbeitslast mit Schreibvorgängen für kleine Dateien handelt. XFS packt sie normalerweise nicht ganz direkt, also nicht Holen Sie sich Vollstreifen-Schreibvorgänge, und RAID5 muss einige Lesevorgänge ausführen, um den Paritätsstreifen zu aktualisieren. In Swift - Dokumenten wird auch über die Verwendung von 100 Partitionen pro Laufwerk gesprochen. Ich gehe davon aus, dass dies ein Swift Begriff ist und nicht etwa 100 verschiedene XFS-Dateisysteme auf jeder SATA-Festplatte zu erstellen.

Das Ausführen eines separaten XFS für jede Festplatte ist tatsächlich ein großer Unterschied . Anstelle einer gigantischen Free-Inode-Map verfügt jede Festplatte über ein separates XFS mit separaten Free-Listen. Außerdem wird die RAID5-Strafe für kleine Schreibvorgänge vermieden.

Wenn Sie Ihre Software bereits so erstellt haben, dass sie ein Dateisystem direkt als Objektspeicher verwendet, anstatt Swift für die Replikation/den Lastenausgleich zu verwenden, können Sie zumindest vermeiden, dass alle Ihre Dateien in einem einzigen enthalten sind Verzeichnis. (Ich habe nicht gesehen, dass Swift - Dokumente sagen, wie sie ihre Dateien in mehreren Verzeichnissen anordnen, aber ich bin mir sicher, dass sie dies tun.)

Bei fast jedem normalen Dateisystem ist es hilfreich, eine Struktur wie diese zu verwenden

1234/5678   # nested medium-size directories instead of
./12345678   # one giant directory

Wahrscheinlich sind etwa 10.000 Einträge sinnvoll, daher ist es eine einfache Lösung, 4 Zeichen Ihrer Objektnamen gut verteilt und als Verzeichnisse zu verwenden. Es muss nicht sehr gut ausbalanciert sein. Das ungerade 100k-Verzeichnis wird wahrscheinlich kein auffälliges Problem sein, und einige leere Verzeichnisse auch nicht.

[~ # ~] xfs [~ # ~] ist nicht ideal für große Mengen kleiner Dateien. Es tut, was es kann, ist jedoch besser für das Streaming von Schreibvorgängen größerer Dateien optimiert. Insgesamt ist es jedoch sehr gut für den allgemeinen Gebrauch. Es hat kein ENOSPC für Kollisionen in seiner Verzeichnisindizierung (AFAIK) und kann mit einem Verzeichnis mit Millionen von Einträgen umgehen. (Aber es ist immer noch besser, mindestens einen einstufigen Baum zu verwenden.)

Dave Chinner hatte einige Kommentare zur XFS-Leistung mit einer großen Anzahl von zugewiesenen Inodes , was zu einer langsamen touch Leistung führte. Das Finden eines freien Inodes zum Zuweisen nimmt mehr CPU-Zeit in Anspruch, da die Bitmap des freien Inodes fragmentiert wird. Beachten Sie, dass dies kein Problem von einem Verzeichnis mit einem großen Verzeichnis im Vergleich zu mehreren Verzeichnissen ist, sondern ein Problem vieler verwendeter Inodes im gesamten Dateisystem. Das Aufteilen Ihrer Dateien in mehrere Verzeichnisse hilft bei einigen Problemen, wie dem, das ext4 im OP verschluckt hat, aber nicht bei dem Problem der gesamten Festplatte, den freien Speicherplatz zu verfolgen. Das separate Dateisystem von Swift pro Festplatte hilft dabei im Vergleich zu einem riesigen XFS auf einem RAID5.

Ich weiß nicht, ob btrfs darin gut ist, aber ich denke, es kann sein. Ich denke, Facebook beschäftigt seinen Hauptentwickler aus einem bestimmten Grund. : P Einige Benchmarks, die ich gesehen habe, wie das Entpacken einer Linux-Kernelquelle, zeigen, dass btrfs gut funktioniert.

Ich weiß, dass reiserfs für diesen Fall optimiert wurde, aber es wird kaum noch, wenn überhaupt, gewartet. Ich kann reiser4 wirklich nicht empfehlen. Es könnte jedoch interessant sein, zu experimentieren. Aber es ist bei weitem die am wenigsten zukunftssichere Wahl. Ich habe auch Berichte über Leistungseinbußen bei gealterten reiserFS gesehen, und es gibt kein gutes Defragmentierungswerkzeug. (googeln Sie filesystem millions of small files und sehen Sie sich einige der vorhandenen Antworten zum Stapelaustausch an.)

Ich vermisse wahrscheinlich etwas, also letzte Empfehlung: Fragen Sie bei Serverfehlern danach! Wenn ich jetzt etwas auswählen müsste, würde ich sagen, versuchen Sie es mit BTRFS, aber stellen Sie sicher Sie haben Backups. (Insbesondere, wenn Sie die integrierte BTRFS-Redundanz für mehrere Festplatten verwenden, anstatt sie auf RAID auszuführen. Die Leistungsvorteile können groß sein, da kleine Dateien für RAID5 eine schlechte Nachricht sind, es sei denn, es handelt sich um eine hauptsächlich lesbare Workload.)

8
Peter Cordes

Für dieses Problem habe ich Folgendes behoben (für die folgenden Schritte benötigen Sie möglicherweise Sudo-Zugriff):

  1. Der genutzte Speicherplatz von Inodes betrug 100% und kann mit dem folgenden Befehl abgerufen werden

    df -i /

Dateisystem-Inodes IUsed IFree IUse% Mounted on

/dev/xvda1            524288   524288  o     100% /
  1. Müssen Sie den iNoted freigeben, müssen Sie daher die Dateien finden, die hier die Anzahl der i-Knoten haben, indem Sie den folgenden Befehl verwenden:

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
  1. jetzt haben wir uns auf den Ordner mit einer großen Anzahl von Dateien konzentriert. Führen Sie die folgenden Befehle nacheinander aus, um Fehler zu vermeiden (in meinem Fall war der eigentliche Ordner/var/spool/clientmqueue):
find /var/spool/clientmqueue/ -type f -mtime +1050 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +350 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +150 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +50 -exec rm -f {} +
1
Barani r