Como corrigir erros intermitentes de "Não resta espaço no dispositivo" durante o MV, quando o dispositivo tem bastante espaço?

21
  • Ubuntu 14.04 em um desktop
  • Unidade de origem: / dev / sda1:
    volume de unidade única ext4 de 5 TB
  • Volume de destino: / dev / mapper / archive-lvarchive: raid6 (mdadm) Volume de 18 TB com
    partição lvm e ext4

Existem cerca de 15 milhões de arquivos a serem movidos e alguns podem ser duplicados (não quero sobrescrever duplicados).

O comando usado (do diretório de origem) foi:

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

Isso já dura alguns dias, como esperado, mas estou recebendo o erro ao aumentar a frequência. Quando começou, a unidade de destino estava cerca de 70% cheia, agora são cerca de 90%. Costumava ser cerca de 1/200 dos movimentos declarar e erro, agora é cerca de 1/5. Nenhum dos arquivos tem mais de 100Mb, a maioria tem cerca de 100k

Algumas informações:

$ 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

Aqui está a minha saída:

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

Encontrei MUITAS postagens sobre esse erro, mas o prognóstico não se encaixa. Problemas como "sua unidade está realmente cheia" ou "você ficou sem inodes" ou até "seu volume de inicialização está cheio". Principalmente, porém, eles lidam com software de terceiros, causando um problema devido à maneira como ele lida com os arquivos, e todos são constantes, o que significa que TODAS as movimentações falham.

Obrigado.

EDIT: aqui está um exemplo de arquivo com falha e êxito:

FAILED (ainda na unidade de origem)

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

SUCEDIDO (no volume alvo)

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

Além disso, embora nem todos os arquivos falhem, um arquivo que falhar SEMPRE falhará. Se eu tentar repetidamente, é consistente.

EDIT: Alguns comandos adicionais por solicitação 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
fonte
Os arquivos estão sendo copiados para vários diretórios ou você está tentando gravar arquivos de 1,5 milhão em um único diretório de destino?
Snoopy
não 1,5m, 15m e sim, todos no mesmo diretório. De fato, já existem mais de 40m lá e cerca de 30m a mais para totalizar.
precisa saber é o seguinte
oh olhe, o troll rebaixado aleatório atacou novamente. Eu não acho que você gostaria de mencionar POR QUE você vota?
precisa saber é o seguinte
1
O voto negativo foi provavelmente porque sua pergunta é mais adequada ao Unix.stackexchange ou askubuntu, pois não está relacionada à programação. Se não houver uma linguagem de programação em suas tags, provavelmente haverá um voto negativo.
technosaurus 10/08/15
@ Chris - parece semelhante a esta questão no SF: serverfault.com/questions/384541/…
snoopy

Respostas:

25

Erro na implementação do recurso ext4 dir_indexque você está usando no sistema de arquivos de destino.

Solução: recrie o filesytem sem dir_index. Ou desabilite o recurso usando o tune2fs (é necessária alguma cautela, consulte o link relacionado Novell SuSE 10/11: Desabilitar a indexação da árvore H em um sistema de arquivos ext3 que, embora esteja relacionado ao ext3, pode precisar de cuidado semelhante.

(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)

O ext4 possui um recurso chamado dir_index ativado por padrão, que é bastante suscetível a colisões de hash.

......

ext4 tem a possibilidade de misturar os nomes dos arquivos de seu conteúdo. Isso melhora o desempenho, mas tem um problema "pequeno": o ext4 não aumenta sua hashtable quando começa a encher. Em vez disso, retorna -ENOSPC ou "não há espaço no dispositivo".

Steve
fonte
3
oh merda, isso soa exatamente como isso, e como uma dor completa para corrigir. É cerca de um mês para recopiar. isso pode ser feito sem perder o conteúdo? Vou ter que pesquisar dir_index etc mais amanhã. Uau, nunca teria pensado nisso.
precisa saber é o seguinte
Adicionado o comando tune2fs para desativar os índices, caso você queira tentar isso.
steve
6
Bem visto @steve. Infelizmente, a desativação dir_indexprovavelmente matará o desempenho do acesso com arquivos de 70 milhões em um diretório.
precisa saber é o seguinte
3
Sim. Não estou precisando de desempenho máximo, mas uma pesquisa fs para cada arquivo seria horrível. Então agora estou olhando para xfs ou uma matriz de 10k ou mais subpastas. As subpastas são uma solução razoável, porém com o ext4 eu ainda corro o risco de colisão. xfs sofre do mesmo problema? Eu li que usa uma árvore B +, mas isso não significa muito para mim, pois garante que nunca haja uma colisão. Existe um mundo de informações erradas por aí, e ouvi alegações de que diminui consideravelmente mais de um milhão de arquivos e afirma que não.
precisa saber é o seguinte
2
Eu acho que essa é uma ótima resposta, e eu gostaria de marcá-la como tal, mas acho que seria bom se pudéssemos resolver o problema, não apenas um diagnóstico. Alguém sabe se o xfs sofre com algo assim? Li críticas mistas de que a escala é boa ou não ultrapassa 1 milhão.
precisa saber é o seguinte
8

Sugestões para opções melhores que o ext4 para armazenar massas de arquivos pequenos:

Se você estiver usando o sistema de arquivos como um armazenamento de objetos, poderá querer usar um sistema de arquivos especializado nisso, possivelmente em detrimento de outras características. Uma rápida pesquisa no Google encontrou o Ceph , que parece ser de código aberto e pode ser montado como um sistema de arquivos POSIX, mas também acessado com outras APIs. Não sei se vale a pena usar em um único host, sem tirar proveito da replicação.

Outro sistema de armazenamento de objetos é o Swift do OpenStack . Seus documentos de design dizem que ele armazena cada objeto como um arquivo separado, com metadados no xattrs . Aqui está um artigo sobre isso. O guia de implantação diz que eles descobriram que o XFS ofereceu o melhor desempenho para armazenamento de objetos. Portanto, mesmo que a carga de trabalho não seja a melhor para o XFS, aparentemente era melhor do que os concorrentes quando o RackSpace estava testando as coisas. Possivelmente o Swift favorece o XFS porque o XFS possui um suporte bom / rápido para atributos estendidos. Pode ser que o ext3 / ext4 funcione bem em discos únicos como um back-end de armazenamento de objetos se metadados extras não forem necessários (ou se forem mantidos dentro do arquivo binário).

O Swift faz o replicação / balanceamento de carga para você e sugere que você forneça sistemas de arquivos feitos em discos brutos, não em RAID . Ele ressalta que sua carga de trabalho é essencialmente a pior das hipóteses para o RAID5 (o que faz sentido se estamos falando de uma carga de trabalho com gravações de arquivos pequenos. O XFS normalmente não os compacta da cabeça aos pés, então você não obter gravações de faixa completa e o RAID5 precisa fazer algumas leituras para atualizar a faixa de paridade. Os documentos Swift também falam sobre o uso de 100 partições por unidade. Disco SATA.

A execução de um XFS separado para cada disco é realmente uma grande diferença . Em vez de um mapa gigantesco de inode livre, cada disco terá um XFS separado com listas livres separadas. Além disso, evita a penalidade de RAID5 para gravações pequenas.

Se você já possui seu software desenvolvido para usar um sistema de arquivos diretamente como armazenamento de objeto, em vez de passar por algo como o Swift para lidar com o replicação / balanceamento de carga, você pode pelo menos evitar ter todos os seus arquivos em um único diretório. (Eu não vi os documentos do Swift dizerem como eles distribuem seus arquivos em vários diretórios, mas tenho certeza que sim.)

Com quase qualquer sistema de arquivos normal, ajudará a usar uma estrutura como

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

Provavelmente cerca de 10 mil entradas são razoáveis, portanto, pegar 4 caracteres bem distribuídos dos nomes dos objetos e usá-los como diretórios é uma solução fácil. Não precisa ser muito bem equilibrado. O diretório estranho de 100k provavelmente não será um problema perceptível, nem alguns diretórios vazios.

O XFS não é ideal para grandes quantidades de arquivos pequenos. Ele faz o que pode, mas é mais otimizado para gravar gravações de arquivos maiores. No entanto, é muito bom para uso geral. Ele não possui ENOSPCcolisões na indexação de diretórios (AFAIK) e pode lidar com um diretório com milhões de entradas. (Mas ainda é melhor usar pelo menos uma árvore de um nível.)

Dave Chinner fez alguns comentários sobre o desempenho do XFS com um grande número de inodes alocados , levando a um touchdesempenho lento . Encontrar um inode livre para alocar começa a demorar mais tempo da CPU, pois o bitmap do inode livre é fragmentado. Observe que este não é um problema de um diretório grande versus vários diretórios, mas de muitos inodes usados ​​em todo o sistema de arquivos. Dividir seus arquivos em vários diretórios ajuda com alguns problemas, como o que o ext4 engasgou no OP, mas não o problema do disco inteiro de controlar o espaço livre. O sistema de arquivos separado por disco da Swift ajuda nisso, comparado com o XFS gigante em um RAID5.

Não sei se o btrfs é bom nisso, mas acho que pode ser. Eu acho que o Facebook emprega seu desenvolvedor líder por um motivo. : P Alguns benchmarks que eu já vi, como desvendar uma fonte de kernel Linux, mostram que o btrfs se sai bem.

Eu sei que o reiserfs foi otimizado para este caso, mas quase não é mais mantido. Eu realmente não posso recomendar ir com reiser4. Pode ser interessante experimentar, no entanto. Mas é de longe a opção menos preparada para o futuro. Também vi relatórios de degradação do desempenho no reiserFS antigo, e não há uma boa ferramenta de desfragmentação. (google filesystem millions of small filese veja algumas das respostas existentes de stackexchange.)

Provavelmente estou perdendo alguma coisa, então recomendação final: pergunte sobre isso no serverfault! Se eu tivesse que escolher alguma coisa agora, diria que experimenta o BTRFS, mas verifique se você tem backups. (especialmente se você usar a redundância de múltiplos discos incorporada do BTRFS, em vez de executá-lo sobre o RAID. As vantagens de desempenho podem ser grandes, pois arquivos pequenos são uma má notícia para o RAID5, a menos que seja uma carga de trabalho de leitura principalmente.)

Peter Cordes
fonte
1
Muito obrigado. Eu já vi muitas pessoas usarem subpastas e, na verdade, anos atrás, eu tinha esse tipo de solução em uma configuração diferente, mas era outra camada que esperava evitar. Parece que a sobrecarga de fazer dessa maneira, no entanto, será muito menor do que encontrar um fs que funcione apenas para esse fim. RE: XFS, é surpreendente que seja tão ruim em altas contagens de arquivos, já que é a resposta certa. BTRFS, wiki: "as entradas de diretório aparecem como itens de diretório, cujos valores de chave à direita são um hash CRC32C de seu nome de arquivo". não é esse o mesmo problema que temos?
Chris.Caldwell
@ Chris.Caldwell: Você precisaria verificar, mas eu assumo que o BTRFS lida com colisões de hash suportando várias entradas no mesmo depósito de hash, em vez do ENOSPC. Você já pensou em apenas manter suas coisas em um banco de dados, em vez de arquivos separados no sistema de arquivos? Eu nunca tive que construir um sistema para lidar com esse tipo de dados. Eu uso XFS, que é ótimo para o que eu usá-lo para (armazenamento de vídeos, e de propósito geral código fonte do Unix e outras coisas.)
Peter Cordes
1
Da maneira como os sistemas de arquivos são projetados, um nível de diretórios é menor. Duas pesquisas rápidas em tabelas pequenas serão mais rápidas do que uma pesquisa lenta em uma tabela excedente que está armazenando mais dados do que foi otimizado. Como eu disse, você não precisa distribuir perfeitamente seus arquivos entre os diretórios; assim, você pode apenas pegar os 4 primeiros caracteres dos seus nomes de arquivos e inserir a /. Espero que isso não afete muitos lugares no seu código. (Você precisa garantir que os diretórios sejam criados, se a criação de um novo arquivo falhar ENOENT). Pergunte no serverfault se existem outros sistemas de arquivos.
Peter Cordes
@ Chris.Caldwell: Eu realmente deveria copiar esta resposta para uma pergunta em que é relevante. Existem alguns existentes. Fiquei curioso sobre o que se "deveria" usar para armazenamento de objetos e encontrei alguns documentos sobre o Swift. Aparentemente, ele armazena objetos como arquivos separados no XFS (mas com um XFS separado para cada disco, não RAID. Ele lida com redundância).
Peter Cordes
1

Para este problema abaixo, é o que eu fiz para corrigir (você pode precisar de acesso ao sudo para as etapas abaixo):

  1. O espaço usado dos Inodes foi de 100%, que pode ser recuperado usando o comando abaixo

    df -i /

Inodes do sistema de arquivos IUsed IFree IUse% Mounted on

/dev/xvda1            524288   524288  o     100% /
  1. Precisa liberar o iNoted, portanto, precisa encontrar os arquivos que possuem aqui o número de nós usando o comando abaixo:

Tente descobrir se este é um problema de inodes com:

df -ih

Tente encontrar pastas raiz com grande número de inodes:

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

Tente encontrar pastas específicas:

for i in /src/*; do echo $i; find $i |wc -l; done
  1. agora zeramos a pasta com um grande número de arquivos. Execute os comandos abaixo um após o outro para evitar erros (no meu caso, a pasta 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
fonte