du fornece dois resultados diferentes para o mesmo arquivo

19

Sou estudante de química computacional com acesso a um cluster Linux. O cluster consiste em um servidor de arquivos muito grande (25 TB), ao qual várias dúzias de nós de computação estão conectados. Cada nó de computação consiste em 8 a 24 núcleos Intel Xeon. Cada nó de computação também contém um disco local de aproximadamente 365 TB.

Como o servidor de arquivos é rotineiramente acessado por uma dúzia de usuários no grupo de pesquisa, o servidor de arquivos é usado principalmente para armazenamento de arquivos a longo prazo (o backup é feito todas as noites, enquanto os discos locais dos computadores nunca são salvos em backup). Assim, o administrador do sistema nos instruiu a executar simulações nos discos locais - que possuem E / S mais rápidas que o servidor de arquivos - para não desacelerar o servidor de arquivos para os outros usuários.

Então, eu corro simulações nos discos locais e, depois que eles terminam, eu copio os arquivos de trajetória - estou executando simulações de dinâmica molecular (MD) - para o servidor de arquivos para armazenamento. Suponha que eu tenha um arquivo de trajetória chamado traj.trr em um diretório no disco local de um nó, /home/myusername/mysimulation1/traj.trr . Para armazenamento a longo prazo, sempre copio traj.trr para um diretório no servidor de arquivos, ~/mysimulation1/traj.trr , em que ~ representa meu diretório no servidor de arquivos, /export/home/myusername . Depois de copiá-lo, eu costumo usar du -h para verificar se /home/myusername/mysimulation1/traj.trr tem o mesmo tamanho de arquivo que ~/mysimulation1/traj.trr . Dessa forma, posso ter pelo menos uma certeza razoável de que a transferência para o servidor de arquivos foi bem-sucedida. Por exemplo:

cd /home/myusername/mysimulation1/
cp -v traj.trr ~/mysimulation1/
du /home/myusername/mysimulation1/traj.trr -h
du ~/mysimulation1/traj.trr -h

Se as duas chamadas para du -h derem o mesmo tamanho de arquivo legível, então posso ter certeza de que a transferência / cópia foi bem-sucedida. (Meus arquivos traj.trr típicos variam de tamanho de 15 a 20 GB, dependendo da simulação exata que executei.) Se eu executar du (ou seja, sem a opção -h ) nos dois arquivos traj.trr , seus tamanhos em bytes são geralmente muito, muito semelhantes - geralmente dentro de apenas alguns bytes. Eu tenho usado este método global durante o último ano e meio, sem problemas.

No entanto, recentemente encontrei o seguinte problema: às vezes du -h informa que os dois arquivos traj.trr são diferentes em tamanho por vários GB. Aqui está um exemplo:

cd /home/myusername/mysimulation1/            # this is the local disk
cp -v traj.trr ~/mysimulation1/
du traj.trr -h
cd ~/mysimulation1/                           # this is the fileserver
du traj.trr -h

A saída das duas chamadas para du -h é a seguinte, respectivamente:

20G     traj.trr
28G     traj.trr

Acredito que o primeiro (isto é, o traj.trr no disco local, /home/myusername/mysimulation1/ ) é o tamanho correto do arquivo, já que espera-se que as trajetórias de simulação sejam de 15 a 20 GB cada. Mas então como o arquivo no servidor de arquivos poderia ser maior ? Eu podia ver como isso poderia ser menor, se de alguma forma a transferência de cp falhasse. Mas eu não vejo como isso poderia realmente ser maior .

Eu recebo saída semelhante quando executo os mesmos comandos acima, mas sem a opção -h dada a du :

20717480        traj.trr
28666688        traj.trr

Você consegue pensar em algum motivo para a diferença?

Se, por alguma chance improvável, du estiver de alguma forma com defeito, eu posso ficar bem com isso. Mas eu realmente preciso ter certeza de que a cópia de traj.trr no servidor de arquivos esteja completa e idêntica à sua versão de origem no disco local. Eu preciso excluir o arquivo local para que eu tenha espaço em disco local suficiente para executar novas simulações, mas não posso ter a versão de traj.trr no servidor de arquivos corrompida.

O formato de arquivo .trr (do pacote de dinâmica molecular Gromacs) é um formato binário, não texto . Portanto, não tenho certeza se os arquivos podem ser comparados de forma confiável por um programa como diff .

    
por Andrew 22.12.2013 / 23:50

3 respostas

24

Você realmente deve usar algo como md5sum ou sha1sum para verificar a integridade.

Se você realmente quiser usar o tamanho, use ls -l ou du -b .

O utilitário du normalmente mostra apenas o uso de disco do arquivo, ou seja, quanto do sistema de arquivos é usado por ele. Esse valor depende totalmente do sistema de arquivos de apoio e de outros fatores, como arquivos esparsos.

Exemplo:

$ truncate -s 512M foo
$ cat foo >bar
$ ls -l foo bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:06 bar
-rw-r--r-- 1 michas users 536870912 23. Dez 00:03 foo
$ du foo bar
0       foo
524288  bar
$ du -b foo bar
536870912       foo
536870912       bar

Temos dois arquivos contendo 512MB de zeros. O primeiro é armazenado esparso e não usa nenhum espaço em disco, enquanto o segundo armazena cada byte explicitamente no disco. - Mesmo arquivo, mas uso de disco completamente diferente.

A opção -b pode ser boa para você:

   -b, --bytes
          equivalent to '--apparent-size --block-size=1'

   --apparent-size
          print apparent sizes, rather than disk usage; although the apparent
          size is  usually  smaller,  it  may  be  larger  due  to  holes  in
          ('sparse')  files, internal fragmentation, indirect blocks, and the
          like
    
por 23.12.2013 / 00:11
7

Este é um problema comum quando você coloca os mesmos dados em 2 HDDs diferentes. Você desejará executar o comando du com e o switch adicional, supondo que ele o tenha - o que deve ser dado a esses nós do Linux.

O interruptor?

   --apparent-size
          print  apparent  sizes,  rather  than  disk  usage;  although the 
          apparent size is usually smaller, it may be larger due to holes in
          ('sparse') files, internal fragmentation, indirect blocks, and the 
          like

Exemplo

$ du -sh --apparent-size /home/sam/scsconfig.log ~/scsconfig.log 
93K /home/sam/scsconfig.log
93K /root/scsconfig.log

Os sistemas de arquivos acima são um disco local ( /root ) enquanto o outro /home/sam é um compartilhamento NFS do meu NAS.

$ df -h . /home/sam
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      222G  118G   92G  57% /
mulder:/export/raid1/home/sam
                      917G  566G  305G  65% /home/sam

Então, o que está acontecendo?

Isso confunde muitas pessoas, mas lembre-se de que, quando arquivos são armazenados em um disco, eles consomem blocos de espaço, mesmo que estejam usando apenas uma parte desses blocos. Quando você executa du sem o --apparent-size , está obtendo o tamanho com base na quantidade de espaço em bloco do disco usado, não no espaço real consumido pelo (s) arquivo (s).

usando uma soma de verificação?

Esta é provavelmente uma opção melhor se você estiver preocupado em comparar duas árvores de arquivos. Você pode usar este comando para calcular uma soma de verificação para todos os arquivos e, em seguida, calcular uma soma de verificação final das somas de verificação. Este exemplo usa sha1sum , mas você pode facilmente usar md5sum .

$ cd /some/dir
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum

Exemplo

$ cd ~/dir1
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

$ cd ~/dir2
$ find . -type f \( -exec sha1sum "{}" \; \) | sort -k2,2 | sha1sum
55e2672f8d6fccff6d83f0bffba1b67aeab87911  -

Assim, podemos ver que as duas árvores são idênticas.

(Nota: o comando find irá listar os arquivos conforme aparecem no sistema de arquivos. Portanto, se você estiver comparando dois diretórios do sistema de arquivos diferente (por exemplo, Ext3 vs. APFS), será necessário classificar primeiro antes do sha1sum final. (adicionado por Xianjun Dong)

    
por 23.12.2013 / 00:04
4

A resposta curta: não teste o tamanho do arquivo, teste o status de retorno do comando. O status de retorno é apenas uma indicação confiável de que a cópia foi bem-sucedida (menos de comparar os dois arquivos byte por byte, direta ou indiretamente - o que é redundante se a cópia for bem-sucedida).

Verificar o tamanho do arquivo não é uma maneira muito útil de verificar se uma cópia foi bem-sucedida. Em alguns casos, pode ser uma verificação de sanidade útil, por exemplo, quando você faz o download de um arquivo da web. Mas aqui há uma maneira melhor.

Todos os comandos Unix retornam um status para indicar se tiveram sucesso: 0 para sucesso, 1 ou mais para erros. Portanto, verifique o status de saída de cp . cp normalmente terá impresso uma mensagem de erro se falhar, indicando qual é o erro. Em um script, o status de saída do último comando está na variável mágica $? .

cp -v traj.trr ~/mysimulation1/
if [ $? -ne 0 ]; then
  echo 1>&2 "cp failed due to the error above"
  exit 2
 fi

Em vez de verificar se $? é zero, você pode usar operadores booleanos.

cp -v traj.trr ~/mysimulation1/ || exit 2

Se você estiver executando um script e quiser que o script pare se algum comando falhar, execute set -e . Se algum comando falhar (isto é, retornar um status diferente de zero), o script sairá imediatamente com o mesmo status do comando.

set -e
…
cp -v traj.trr ~/mysimulation1/

Quanto ao motivo pelo qual seu arquivo copiado era maior, deve ser porque era um arquivo esparso . Arquivos esparsos são uma forma bruta de compactação, em que blocos contendo apenas bytes nulos não são armazenados. Quando você copia um arquivo, o comando cp lê e grava bytes nulos, portanto, onde o original tinha blocos ausentes, a cópia possui blocos cheios de bytes nulos. No Linux, o comando cp tenta detectar arquivos esparsos, mas nem sempre é bem-sucedido; cp --sparse=always faz com que seja mais difícil, em detrimento de um aumento muito pequeno no tempo de CPU.

Mais geralmente, du poderia retornar resultados diferentes devido a outras formas de compactação. Sistemas de arquivos compactados são raros, no entanto. Se você quiser saber o tamanho de um arquivo como no número de bytes no arquivo, ao contrário do número de blocos de disco usados, use ls -l em vez de du .

    
por 23.12.2013 / 01:51

Tags