Come correggere gli errori intermittenti "Nessuno spazio lasciato sul dispositivo" durante il mv quando il dispositivo ha molto spazio?


21
  • Ubuntu 14.04 su un desktop
  • Unità di origine: / dev / sda1:
    volume di unità singola ext4 da 5 TB
  • Volume target: / dev / mapper / archive-lvarchive: raid6 (mdadm) Volume 18 TB con
    partizione lvm ed ext4

Ci sono circa 15 milioni di file da spostare e alcuni potrebbero essere duplicati (non voglio sovrascrivere i duplicati).

Il comando utilizzato (dalla directory di origine) era:

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

Questo è andato avanti per alcuni giorni come previsto, ma sto ricevendo l'errore nell'aumentare della frequenza. All'avvio, l'unità di destinazione era piena per circa il 70%, ora è per circa il 90%. Una volta erano circa 1/200 delle mosse che avrebbero dichiarato ed errore, ora sono circa 1/5. Nessuno dei file è superiore a 100 Mb, la maggior parte è di circa 100.000

Alcune informazioni:

$ 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

Ecco il mio output:

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

Ho trovato MOLTE pubblicazioni su questo errore, ma la prognosi non si adatta. Problemi come "il tuo disco è effettivamente pieno" o "hai esaurito gli inode" o anche "il tuo volume / boot è pieno". Principalmente, tuttavia, hanno a che fare con software di terze parti che causa un problema a causa di come gestisce i file e sono tutti costanti, il che significa che OGNI spostamento non riesce.

Grazie.

EDIT: ecco un esempio di file fallito e riuscito:

FAILED (ancora sull'unità sorgente)

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

SUCCEEDED (sul volume target)

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

Inoltre, anche se non tutti i file falliscono, un file che fallisce SEMPRE fallirà. Se riprovo più volte è coerente.

EDIT: alcuni comandi aggiuntivi per richiesta di @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

I file vengono copiati in più directory o stai tentando di scrivere file 1,5 M in una singola directory di destinazione?
snoopy

non 1.5m, 15m e sì, tutti nella stessa directory. In realtà ci sono già oltre 40m lì, e circa 30m in più per arrivare al totale.
Chris.Caldwell,

oh guarda, il troll downvote casuale ha colpito ancora. Non credo che ti interessi menzionare PERCHÉ hai votato?
Chris.Caldwell,

1
Il voto negativo è stato probabilmente dovuto al fatto che la tua domanda è più adatta a Unix.stackexchange o askubuntu poiché non è legata alla programmazione. Se non c'è un linguaggio di programmazione nei tuoi tag, probabilmente otterrà un voto negativo.
technosaurus

@Chris - sembra simile a questo problema su SF: serverfault.com/questions/384541/…
snoopy

Risposte:


25

Bug nell'implementazione della funzione ext4 dir_indexche stai usando sul tuo filesystem di destinazione.

Soluzione: ricreare filesytem senza dir_index. Oppure disabilita la funzione usando tune2fs (sono necessarie alcune precauzioni, vedere il collegamento correlato Novell SuSE 10/11: Disabilitare l'indicizzazione H-Tree su un filesystem ext3 che, sebbene relativo a ext3, potrebbe richiedere una simile attenzione.

(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 ha una funzione chiamata dir_index abilitata di default, che è abbastanza suscettibile alle collisioni di hash.

......

ext4 ha la possibilità di eseguire l'hashing dei nomi dei file dei suoi contenuti. Ciò migliora le prestazioni, ma presenta un "piccolo" problema: ext4 non aumenta la sua tabella hash, quando inizia a riempirsi. Invece restituisce -ENOSPC o "nessuno spazio lasciato sul dispositivo".


3
oh merda, suona esattamente così, e come un dolore completo da risolvere. Sono circa un mese da ricopiare. questo può essere fatto senza perdere il contenuto? Domani dovrò cercare dir_index ecc. Caspita, non ci avrei mai pensato.
Chris.Caldwell,

Aggiunto il comando tune2fs per disabilitare gli indici, nel caso in cui si desideri provarlo.
steve

6
Ben individuato @steve. Sfortunatamente la disattivazione dir_indexprobabilmente ucciderà le prestazioni di accesso con file di 70m in una directory.
mjturner,

3
Si. Non ho bisogno delle massime prestazioni, ma una ricerca fs per ogni file sarebbe orribile. Quindi ora sto guardando xfs o una matrice di circa 10k o più sottocartelle. Le sottocartelle sono una soluzione ragionevole, tuttavia con ext4 corro ancora il rischio di collisione. xfs soffre dello stesso problema? Ho letto che usa un albero B +, ma ciò non significa molto per me per quanto riguarda il fatto che non ci sia mai una collisione. Esiste un mondo di disinformazione là fuori e Ive ha sentito affermazioni che rallenta considerevolmente oltre un milione di file e afferma che non lo fa.
Chris.Caldwell,

2
Penso che questa sia un'ottima risposta, e mi piacerebbe contrassegnarla come tale, ma penso che sarebbe bello se potessimo arrivare a una soluzione, non solo a una diagnosi. Qualcuno sa se xfs soffre di qualcosa del genere? Ho letto recensioni contrastanti che si adattano bene o non oltre 1m.
Chris.Caldwell,

8

Suggerimenti per scelte migliori di ext4 per la memorizzazione di masse di piccoli file:

Se stai usando il filesystem come archivio oggetti, potresti voler guardare usando un filesystem specializzato in questo, probabilmente a scapito di altre caratteristiche. Una rapida ricerca su Google ha trovato Ceph , che sembra essere open source, e può essere montato come un filesystem POSIX, ma è anche possibile accedervi con altre API. Non so se valga la pena utilizzarlo su un singolo host, senza sfruttare la replica.

Un altro sistema di memorizzazione degli oggetti è Swift di OpenStack . I suoi documenti di progettazione dicono che memorizza ogni oggetto come un file separato, con metadati in xattrs . Ecco un articolo a riguardo. La loro guida alla distribuzione afferma che XFS ha fornito le migliori prestazioni per l'archiviazione degli oggetti. Quindi, anche se il carico di lavoro non è la soluzione migliore per XFS, apparentemente era migliore dei concorrenti quando RackSpace stava testando le cose. Forse Swift preferisce XFS perché XFS ha un supporto buono / veloce per attributi estesi. È possibile che ext3 / ext4 funzionino correttamente su singoli dischi come back-end di un archivio oggetti se non fossero necessari metadati aggiuntivi (o se fosse conservato all'interno del file binario).

Swift esegue la replica / bilanciamento del carico per te e suggerisce di fornirgli filesystem creati su dischi grezzi, non su RAID . Sottolinea che il suo carico di lavoro è essenzialmente il caso peggiore per RAID5 (il che ha senso se stiamo parlando di un carico di lavoro con scritture di file di piccole dimensioni. XFS in genere non li comprime direttamente, quindi non ottenere scritture a banda intera e RAID5 deve fare alcune letture per aggiornare la striscia di parità. I ​​documenti di Swift parlano anche dell'uso di 100 partizioni per unità. Disco SATA.

L'esecuzione di un XFS separato per ogni disco è in realtà una differenza enorme . Invece di una gigantesca mappa inode libera, ogni disco avrà un XFS separato con liste libere separate. Inoltre, evita la penalità RAID5 per le piccole scritture.

Se hai già il tuo software creato per utilizzare un filesystem direttamente come archivio oggetti, piuttosto che passare attraverso qualcosa come Swift per gestire la replica / bilanciamento del carico, puoi almeno evitare di avere tutti i tuoi file in una singola directory. (Non ho visto i documenti di Swift dire come disponevano i loro file in più directory, ma sono sicuro che lo fanno.)

Con quasi tutti i normali filesystem, aiuterà ad usare una struttura simile

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

Probabilmente circa 10k voci sono ragionevoli, quindi prendere 4 caratteri ben distribuiti dei nomi dei tuoi oggetti e usarli come directory è una soluzione semplice. Non deve essere molto ben bilanciato. La strana directory 100k probabilmente non sarà un problema evidente, e nemmeno alcune directory vuote.

XFS non è l'ideale per enormi masse di piccoli file. Fa quello che può, ma è più ottimizzato per le scritture in streaming di file più grandi. È molto buono nel complesso per uso generale, però. Non ha ENOSPCcollisioni nell'indicizzazione delle directory (AFAIK) e può gestire una directory con milioni di voci. (Ma è ancora meglio usare almeno un albero di un livello.)

Dave Chinner ha commentato le prestazioni di XFS con un numero enorme di inode allocati , portando a touchprestazioni lente . La ricerca di un inode gratuito da allocare inizia a richiedere più tempo alla CPU, poiché la bitmap dell'inode gratuita viene frammentata. Si noti che questo non è un problema di una directory grande rispetto a più directory, ma piuttosto un problema di molti inode utilizzati nell'intero file system. La suddivisione dei file in più directory aiuta con alcuni problemi, come quello che ext4 ha soffocato nell'OP, ma non il problema dell'intero disco di tenere traccia dello spazio libero. Il file system separato per disco di Swift aiuta in questo, rispetto al gigantesco XFS su un RAID5.

Non so se btrfs sia bravo in questo, ma penso che potrebbe esserlo. Penso che Facebook impieghi il suo sviluppatore principale per un motivo. : P Alcuni benchmark che ho visto, di cose come l'estrazione di un sorgente del kernel Linux, mostrano che btrfs funziona bene.

So che reiserfs è stato ottimizzato per questo caso, ma non viene quasi più mantenuto. Non posso davvero raccomandare di andare con reiser4. Potrebbe essere interessante sperimentare, però. Ma è di gran lunga la scelta meno a prova di futuro. Ho anche visto rapporti di degrado delle prestazioni su reiserFS obsoleti e non esiste un buon strumento di deframmentazione. (google filesystem millions of small files, e guarda alcune delle risposte esistenti di stackexchange.)

Probabilmente mi manca qualcosa, quindi consiglio finale: chiedi di questo su serverfault! Se dovessi scegliere qualcosa in questo momento, direi di provare BTRFS, ma assicurati di avere dei backup. (specialmente se si utilizza la ridondanza su più dischi incorporata di BTRFS, invece di eseguirla su RAID. I vantaggi in termini di prestazioni potrebbero essere grandi, poiché i file di piccole dimensioni sono cattive notizie per RAID5, a meno che non si tratti di un carico di lavoro prevalentemente di lettura.)


1
Grazie mille. Ho visto molte persone usare le sottocartelle, e infatti anni fa avevo quel tipo di soluzione su una configurazione diversa, ma è un altro livello che speravo di evitare. Sembra che il sovraccarico nel farlo in questo modo, tuttavia, sarà molto meno che trovare un fs che funzioni solo per questo scopo. RE: XFS, è sorprendente che sia così male con un alto numero di file poiché la sua risposta istintiva è spesso data. BTRFS, wiki: "le voci della directory appaiono come voci della directory, i cui valori della chiave di destra sono un hash CRC32C del loro nome file". non è lo stesso problema che abbiamo?
Chris.Caldwell,

@ Chris.Caldwell: dovresti verificare, ma suppongo che BTRFS gestisca le collisioni di hash supportando più voci nello stesso bucket hash, piuttosto che ENOSPC. Hai pensato di conservare le tue cose in un database, invece di file separati nel filesystem? Non ho mai dovuto costruire un sistema per gestire questo tipo di dati. Uso XFS, che è ottimo per quello per cui lo uso (memorizzazione di video, codice sorgente Unix e roba per scopi generici).
Peter Cordes,

1
Nel modo in cui sono progettati i filesystem, un livello di directory è meno costoso. Due ricerche rapide in piccole tabelle saranno più veloci di una ricerca lenta in una tabella traboccante che memorizza più dati di quelli per i quali è stata ottimizzata. Come ho detto, non devi distribuire perfettamente i tuoi file tra le directory, quindi puoi semplicemente prendere i primi 4 caratteri dei tuoi nomi di file e inserire un /. Spero che ciò non influisca su troppi punti del codice. (Devi assicurarti che le directory vengano create, se la creazione di un nuovo file fallisce ENOENT). Chiedi a serverfault se ci sono altri filesystem.
Peter Cordes,

@ Chris.Caldwell: dovrei davvero copiare questa risposta a una domanda in cui è rilevante. Ce ne sono alcuni esistenti. Ero curioso di sapere cosa si dovrebbe "usare" per la memorizzazione degli oggetti e ho trovato alcuni documenti su Swift. Apparentemente memorizza oggetti come file separati su XFS (ma con un XFS separato per ogni disco, non RAID. Gestisce la ridondanza stessa).
Peter Cordes,

1

Per questo problema di seguito è quello che ho fatto per risolvere (potrebbe essere necessario l'accesso sudo per i passaggi seguenti):

  1. Lo spazio usato di Inodes era del 100% che può essere recuperato usando il comando seguente

    df -i /

Inodi filesystem IUsed IFree IUse% Montato su

/dev/xvda1            524288   524288  o     100% /
  1. È necessario liberare iNoted, quindi è necessario trovare i file che hanno qui un numero di nodi i usando il comando seguente:

Prova a scoprire se questo è un problema di inode con:

df -ih

Prova a trovare le cartelle principali con un conteggio di inode di grandi dimensioni:

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

Prova a trovare cartelle specifiche:

for i in /src/*; do echo $i; find $i |wc -l; done
  1. ora abbiamo azzerato fino alla cartella con un gran numero di file al suo interno. Esegui i seguenti comandi uno dopo l'altro per evitare errori (nel mio caso la cartella effettiva era / 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 {} +
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.