¿Cómo reparar los errores intermitentes de "No queda espacio en el dispositivo" durante mv cuando el dispositivo tiene mucho espacio?

21
  • Ubuntu 14.04 en un escritorio
  • Unidad de origen: / dev / sda1:
    volumen de unidad individual ext4 de 5 TB
  • Volumen de destino: / dev / mapper / archive-lvarchive: raid6 (mdadm) Volumen de 18 TB con
    partición lvm y ext4

Hay aproximadamente 15 millones de archivos para mover, y algunos pueden ser duplicados (no quiero sobrescribir duplicados).

El comando utilizado (del directorio de origen) fue:

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

Esto ha estado sucediendo durante unos días como se esperaba, pero recibo el error al aumentar la frecuencia. Cuando comenzó, la unidad de destino estaba llena en un 70%, ahora tiene aproximadamente el 90%. Solía ​​ser aproximadamente 1/200 de los movimientos indicados y error, ahora es aproximadamente 1/5. Ninguno de los archivos tiene más de 100Mb, la mayoría tiene alrededor de 100k

Alguna información:

$ 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

Aquí está mi salida:

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

He encontrado MUCHAS publicaciones sobre este error, pero el pronóstico no encaja. Cuestiones tales como "su unidad está realmente llena" o "se ha quedado sin inodos" o incluso "su volumen / boot está lleno". Sin embargo, en su mayoría, tratan con software de terceros que causa un problema debido a cómo maneja los archivos, y todos son constantes, lo que significa que CADA movimiento falla.

Gracias.

EDITAR: aquí hay un archivo de muestra fallido y correcto:

FALLIDO (todavía en la unidad fuente)

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

ÉXITO (en el volumen objetivo)

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

Además, aunque no todos los archivos fallan, un archivo que falla SIEMPRE fallará. Si lo vuelvo a intentar una y otra vez, es consistente.

EDITAR: Algunos comandos adicionales por solicitud de @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
Chris Caldwell
fuente
¿Los archivos se están copiando en varios directorios o está intentando escribir archivos de 1,5 M en un único directorio de destino?
snoopy
no 1.5m, 15m, y sí, todos en el mismo directorio. De hecho, ya hay más de 40 m allí, y unos 30 m más para llegar en total.
Chris.Caldwell
Oh, mira, el troll al azar con votos negativos volvió a golpear. No creo que quieras mencionar ¿POR QUÉ votas mal?
Chris.Caldwell
1
El voto negativo probablemente se debió a que su pregunta se adapta mejor a Unix.stackexchange o askubuntu ya que no está relacionada con la programación. Si no hay un lenguaje de programación en sus etiquetas, probablemente obtendrá un voto negativo.
technosaurus
@Chris - parece similar a este problema en SF: serverfault.com/questions/384541/…
snoopy

Respuestas:

25

Error en la implementación de la función ext4 dir_indexque está utilizando en su sistema de archivos de destino.

Solución: vuelva a crear el sistema de archivos sin dir_index. O deshabilite la función usando tune2fs (se requiere precaución, consulte el enlace relacionado Novell SuSE 10/11: deshabilite la indexación de H-Tree en un sistema de archivos ext3 que, aunque está relacionado con ext3, puede necesitar una precaución similar.

(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 tiene una característica llamada dir_index habilitada por defecto, que es bastante susceptible a colisiones hash.

......

ext4 tiene la posibilidad de trocear los nombres de archivo de sus contenidos. Esto mejora el rendimiento, pero tiene un problema "pequeño": ext4 no aumenta su tabla hash cuando comienza a llenarse. En su lugar, devuelve -ENOSPC o "no queda espacio en el dispositivo".

Steve
fuente
3
oh mierda, eso suena exactamente como eso, y como un dolor completo de arreglar. Es alrededor de un mes para volver a copiar. ¿Se puede hacer esto sin perder el contenido? Mañana tendré que investigar dir_index, etc. más. Wow, nunca hubiera pensado en eso.
Chris.Caldwell
Se agregó el comando tune2fs para deshabilitar los índices, en caso de que quiera probar eso.
Steve
66
Bien visto @steve. Desafortunadamente, apagarlo dir_indexprobablemente matará el rendimiento de acceso con 70 millones de archivos en un directorio.
mjturner
3
Sí. No necesito un rendimiento máximo, pero una búsqueda fs para cada archivo sería horrible. Así que ahora estoy mirando xfs o una matriz de más de 10k subcarpetas. Subcarpetas es una solución razonable, sin embargo, con ext4 todavía corro el riesgo de colisión. ¿xfs sufre el mismo problema? Leí que usa un árbol B +, pero eso no significa mucho para mí en cuanto a garantizar que nunca haya una colisión. Hay un mundo de información errónea por ahí, y he escuchado afirmaciones de que ralentiza considerablemente más de un millón de archivos, y afirma que no.
Chris.Caldwell
2
Creo que esta es una gran respuesta, y me gustaría marcarla como tal, pero creo que sería bueno si pudiéramos llegar a una solución, no solo un diagnóstico. ¿Alguien sabe si xfs sufre de algo como esto? He leído críticas mixtas que escalan bien, o no más de 1 m.
Chris.Caldwell
8

Sugerencias para opciones mejores que ext4 para almacenar grandes cantidades de archivos pequeños:

Si está utilizando el sistema de archivos como un almacén de objetos, puede considerar usar un sistema de archivos que se especialice en eso, posiblemente en detrimento de otras características. Una búsqueda rápida en Google encontró a Ceph , que parece ser de código abierto, y se puede montar como un sistema de archivos POSIX, pero también se puede acceder con otras API. No sé si vale la pena usarlo en un solo host, sin aprovechar la replicación.

Otro sistema de almacenamiento de objetos es Swift de OpenStack . Sus documentos de diseño dicen que almacena cada objeto como un archivo separado, con metadatos en xattrs . Aquí hay un artículo al respecto. Su guía de implementación dice que descubrieron que XFS dio el mejor rendimiento para el almacenamiento de objetos. Entonces, aunque la carga de trabajo no es lo mejor para XFS, aparentemente fue mejor que la competencia cuando RackSpace estaba probando cosas. Posiblemente Swift favorece XFS porque XFS tiene soporte bueno / rápido para atributos extendidos. Es posible que ext3 / ext4 funcione bien en discos individuales como un back-end de almacenamiento de objetos si no se necesitaran metadatos adicionales (o si se mantuvieran dentro del archivo binario).

Swift realiza la replicación / equilibrio de carga por usted y sugiere que le proporcione sistemas de archivos hechos en discos sin formato, no RAID . Señala que su carga de trabajo es esencialmente el peor de los casos para RAID5 (lo que tiene sentido si hablamos de una carga de trabajo con escrituras de archivos pequeños. XFS generalmente no los empaqueta de la cabeza a la cola, por lo que no obtener escrituras de banda completa, y RAID5 tiene que hacer algunas lecturas para actualizar la banda de paridad. Los documentos de Swift también hablan sobre el uso de 100 particiones por unidad. Supongo que es un término de Swift, y no habla de hacer 100 sistemas de archivos XFS diferentes en cada Disco SATA.

Ejecutar un XFS separado para cada disco es en realidad una gran diferencia . En lugar de un mapa gigantesco de inodo libre, cada disco tendrá un XFS separado con listas libres separadas. Además, evita la penalización RAID5 para pequeñas escrituras.

Si ya tiene su software creado para usar un sistema de archivos directamente como un almacén de objetos, en lugar de pasar por algo como Swift para manejar la replicación / equilibrio de carga, entonces al menos puede evitar tener todos sus archivos en un solo directorio. (No vi documentos de Swift que digan cómo distribuyen sus archivos en varios directorios, pero estoy seguro de que lo hacen).

Con casi cualquier sistema de archivos normal, ayudará usar una estructura como

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

Probablemente alrededor de 10k entradas es razonable, por lo que tomar 4 caracteres bien distribuidos de los nombres de sus objetos y usarlos como directorios es una solución fácil. No tiene que estar muy bien equilibrado. El directorio impar de 100k probablemente no será un problema notable, y tampoco lo serán algunos directorios vacíos.

XFS no es ideal para grandes masas de archivos pequeños. Hace lo que puede, pero está más optimizado para transmitir escrituras de archivos más grandes. Sin embargo, es muy bueno en general para uso general. No tiene ENOSPCcolisiones en su indexación de directorio (AFAIK), y puede manejar tener un directorio con millones de entradas. (Pero aún es mejor usar al menos un árbol de un nivel).

Dave Chinner hizo algunos comentarios sobre el rendimiento de XFS con un gran número de inodos asignados , lo que condujo a un touchrendimiento lento . Encontrar un inodo libre para asignar comienza a tomar más tiempo de CPU, ya que el mapa de bits de inodo libre se fragmenta. Tenga en cuenta que este no es un problema de un directorio grande frente a varios directorios, sino más bien un problema de muchos inodos usados ​​en todo el sistema de archivos. Dividir sus archivos en múltiples directorios ayuda con algunos problemas, como el que ext4 se atragantó en el OP, pero no el problema del disco completo de realizar un seguimiento del espacio libre. El sistema de archivos separado por disco de Swift ayuda con esto, en comparación con el XFS gigante en un RAID5.

No sé si btrfs es bueno en esto, pero creo que puede serlo. Creo que Facebook emplea a su desarrollador principal por una razón. : P Algunos puntos de referencia que he visto, de cosas como descomprimir una fuente de kernel de Linux, muestran que btrfs funciona bien.

Sé que reiserfs se optimizó para este caso, pero apenas se mantiene, si es que se mantiene. Realmente no puedo recomendar ir con reiser4. Sin embargo, puede ser interesante experimentar. Pero es, con mucho, la opción menos preparada para el futuro. También he visto informes de degradación del rendimiento en reiserFS antiguos, y no hay una buena herramienta de desfragmentación. (google filesystem millions of small files, y mira algunas de las respuestas existentes de stackexchange).

Probablemente me falta algo, así que la recomendación final: ¡pregunta sobre esto en serverfault! Si tuviera que elegir algo en este momento, diría que pruebe BTRFS, pero asegúrese de tener copias de seguridad. (especialmente si utiliza la redundancia de múltiples discos incorporada de BTRFS, en lugar de ejecutarlo sobre RAID. Las ventajas de rendimiento podrían ser grandes, ya que los archivos pequeños son malas noticias para RAID5, a menos que sea una carga de trabajo principalmente de lectura).

Peter Cordes
fuente
1
Muchas gracias. He visto a muchas personas usar subcarpetas y, de hecho, hace años tuve ese tipo de solución en una configuración diferente, pero esperaba evitar esa otra capa. Parece que la sobrecarga de hacerlo de esa manera, sin embargo, será mucho menor que encontrar una fs que simplemente funcione para este propósito. RE: XFS, es sorprendente que sea tan malo en el alto recuento de archivos ya que es la respuesta instintiva que se da con frecuencia. BTRFS, wiki: "las entradas de directorio aparecen como elementos de directorio, cuyos valores de clave de la derecha son un hash CRC32C de su nombre de archivo". ¿No es ese el mismo problema que tenemos?
Chris.Caldwell
@ Chris.Caldwell: Tendría que verificar, pero supongo que BTRFS maneja las colisiones hash al admitir múltiples entradas en el mismo depósito de hash, en lugar de ENOSPC. ¿Has pensado en mantener tus cosas en una base de datos, en lugar de archivos separados en el sistema de archivos? Nunca he tenido que construir un sistema para manejar este tipo de datos. Uso XFS, que es excelente para lo que lo uso (almacenamiento de videos y código fuente Unix de uso general y esas cosas)
Peter Cordes
1
La forma en que se diseñan los sistemas de archivos, un nivel de directorios es menos sobrecarga. Dos búsquedas rápidas en tablas pequeñas serán más rápidas que una búsqueda lenta en una tabla desbordada que almacena más datos de los que se optimizó. Como dije, no tiene que distribuir perfectamente sus archivos entre directorios, por lo que puede tomar los primeros 4 caracteres de sus nombres de archivo e insertar un /. Esperemos que eso no afecte muchos lugares en su código. (Debe asegurarse de que se creen directorios, si falla la creación de un nuevo archivo ENOENT). Pregunte en serverfault si hay otros sistemas de archivos.
Peter Cordes
@ Chris.Caldwell: Realmente debería copiar esta respuesta a una pregunta donde sea relevante. Hay algunos existentes. Tenía curiosidad por saber qué se "supone" usar para el almacenamiento de objetos, y encontré algunos documentos sobre Swift. Aparentemente almacena objetos como archivos separados en XFS (pero con un XFS separado para cada disco, no RAID. Maneja la redundancia).
Peter Cordes
1

Para este problema a continuación es lo que hice para solucionar (es posible que necesite acceso sudo para los pasos a continuación):

  1. El espacio utilizado de Inodes era del 100%, que se puede recuperar con el siguiente comando

    df -i /

Sistema de archivos Inodes IUsed IFree IUse% Montado en

/dev/xvda1            524288   524288  o     100% /
  1. Necesita liberar el iNoted, por lo tanto, necesita encontrar los archivos que tienen aquí un número de nodos i usando el siguiente comando:

Trate de encontrar si este es un problema de inodes con:

df -ih

Trate de encontrar carpetas raíz con gran cantidad de inodos:

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

Intenta encontrar carpetas específicas:

for i in /src/*; do echo $i; find $i |wc -l; done
  1. ahora nos hemos centrado en la carpeta con gran cantidad de archivos. Ejecute los siguientes comandos uno tras otro para evitar cualquier error (en mi caso, la carpeta real 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 {} +
Barani r
fuente