desenv-web-rp.com

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

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

Existem aproximadamente 15 milhões de arquivos a serem movidos, e alguns podem ser duplicados (não desejo 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
21
Chris.Caldwell

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

Solução: recrie o filesytem sem dir_index. Ou desative o recurso usando o tune2fs (é necessária alguma cautela, consulte o link relacionado Novell SuSE 10/11: Desativar a indexação da árvore H em um sistema de arquivos ext3 que, embora esteja relacionado a 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, ele retorna -ENOSPC ou "não resta espaço no dispositivo".

26
steve

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 objeto, convém usar um sistema de arquivos especializado nisso, possivelmente em detrimento de outras características. Uma pesquisa rápida no Google encontrou 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 é Swift do OpenStack . Seus documentos de design dizem que armazena cada objeto como um arquivo separado, com metadados no xattrs . Aqui está m artigo sobre o assunto. O guia de implantação diz que eles encontraram o XFS com 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 Swift favorece o XFS porque o XFS tem um suporte rápido/bom 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 foi mantido 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 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. Swift também falam sobre o uso de 100 partições por unidade. Suponho que seja um Swift, e não está falando em criar 100 sistemas de arquivos XFS diferentes em cada disco SATA.

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

Se você já possui seu software criado para usar um sistema de arquivos diretamente como um armazenamento de objeto, em vez de passar por algo como Swift para lidar com a replicação/balanceamento de carga), você pode pelo menos evitar ter todos seus arquivos em um único diretório. (Eu não vi os documentos Swift dizem como eles distribuem seus arquivos em vários diretórios, mas tenho certeza de 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 10k 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.

[~ # ~] xfs [~ # ~] não é ideal para grandes massas 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 ENOSPC em colisões em sua indexação de diretório (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 desempenho lento de touch. 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 de todo o disco 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 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, de coisas como desarmar uma fonte de kernel Linux, mostram que o btrfs se sai bem.

Eu sei que 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 files e veja algumas das respostas existentes de stackexchange.)

Provavelmente estou perdendo alguma coisa, então recomendação final: pergunte sobre isso na falha do servidor! Se eu tivesse que escolher alguma coisa agora, eu diria que tente o BTRFS, mas certifique-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.)

8
Peter Cordes

Para esta questão abaixo, foi o que 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 qualquer erro (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 {} +
1
Barani r