o arquivo unix está corrompido [fechado]

2

Descobri que um dos meus logs consome muito espaço proveniente de um processo em execução. Eu queria limpar esse arquivo, então eu posso rodar o logadm para rodá-lo depois. mas eu não sei como

# >MyLog_nohup.out
# ls -lLh MyLog_nohup.out
-rw-r-lr--   1 user     group       72G Jul 30 07:26 MyLog_nohup.out
# du -sh MyLog_nohup.out
480K   MyLog_nohup.out

Mesmo depois de liberá-lo, ainda consome 72G, e executando mais, apenas mostrando linhas em branco .. Como posso corrigir isso?

Eu não posso permitir o reinício do processo. Mas eu queria usar logadm para rodar esse arquivo de log, isso é possível? Eu tentei, mas ele continua lidando com linhas em branco um loop infinito. mesmo quando eu faço mais neste arquivo. Existe alguma outra maneira de corrigir isso?

Para o logrotate, há a opção copytruncate que lida com o arquivo aberto, mas não posso usá-lo enquanto o arquivo tiver essas linhas em branco à medida que ele for executado em um loop. Eu ainda não entendi porque eu não consigo ver / more / head este arquivo!

    
por asa 30.07.2015 / 07:51

2 respostas

5

Seu arquivo não está corrompido; Nos sistemas Linux e POSIX, desde que um processo em execução tenha um descritor de arquivos aberto em algum arquivo que esteja sendo escrito, poderá continuar a escrevê-lo, mesmo se você remover ou renomear esse arquivo (porque um descritor de arquivo está relacionado a um i-node , não para um nome de arquivo). em particular logrotate ou logadm - ou qualquer sequência de comandos externos - não fará nada útil sobre o espaço em disco.

Estou assumindo que você está no Linux.

Se o seu processo tiver pid 1234, você poderá procurar em /proc/1234/ , em particular, listar o diretório /proc/1234/fd/ . Leia proc (5) .

Provavelmente, você deve interromper o processo ofensivo (usando kill -TERM , em seguida, kill -QUIT , e, por fim, kill -KILL ; consulte sinal (7) e matar (1) ), em seguida, remova o arquivo e, finalmente, corrija e / ou configure seu programa para fazer alguns logs mais úteis e inicie-o novamente.

Você provavelmente perdeu todo o cálculo feito pelo seu programa. Então, melhor pará-lo o quanto antes, melhorá-lo (talvez você queira algum ponto de verificação do aplicativo , ou persistence , ou adicione uma maneira de fechar, renomeie e reabra o arquivo de log), e reinicie uma versão melhorada do seu programa.

Você deve ler Programação avançada em Linux . Você provavelmente tem vários bugs no seu programa (talvez relacionados ao registro). Você pode usar strace (1) para entender o syscalls feito pelo seu processo, e você pode usar syslog (3) dentro do seu programa (melhorado).

Muito provavelmente, você tem um bug no seu programa. Então, pare melhor agora, pense, melhore e comece de novo. Esperar que o disco seja totalmente preenchido não o ajudará (e isso tornaria o problema ainda pior).

Para testes futuros, você pode considerar a definição de algumas cotas de disco e / ou alguns limites de recursos (por exemplo, setrlimit(2) e o bash ulimit builtin).

No futuro, sempre projete seu programa para poder reciclar o processo. Não ser capaz de suportar isso é sempre um grande erro (em particular, você precisa de alguma estratégia de backup, e você precisa de algum controle de revisão no seu código-fonte, eu recomendo git para isso.

    
por 30.07.2015 / 08:00
4
# ls -lLh MyLog_nohup.out
-rw-r-lr--   1 user     group       72G Jul 30 07:26 MyLog_nohup.out
# du -sh MyLog_nohup.out
480K   MyLog_nohup.out

Isso parece um arquivo esparso para mim. Um arquivo esparso aloca um tamanho virtual no disco (72G no seu caso) para eficiência, mas na realidade o espaço usado é o mesmo número de dados que são gravados no arquivo (480K no seu caso). O tamanho virtual não é calculado no espaço usado (você não vai liberar 72G no caso de você excluir o arquivo, mas apenas 480k).

Você vê linhas em branco ao ler o arquivo porque ... bem, há apenas linhas em branco (nulos) nele. Tente o hexdump (1) para ver os dados reais (se houver), mas para qualquer saída significativa você precisará de uma ferramenta que entenda o formato do arquivo (o programa que cria o arquivo deve vir com uma ferramenta para isso).

Além disso - como outros apontaram - você não pode recuperar os recursos do arquivo enquanto o arquivo permanece mapeado na memória. Você precisa liberar o mapeamento, que é ether terminar o programa ou você pode tentar isso com gdb (1)

pidof <procname>       # find the pid of the process which creates the log file
ls -l /proc/<pid>/fd/  # find the fd pointing to MyLog_nohup.out
gdb -p <pid>           # attach to pid
(gdb) p close(<fd>)    # close fd pointing to log file

No entanto, por favor, note que o programa pode recriar o arquivo de log ou ter um comportamento não especificado quando o fd for fechado e desde que você não pode ter que reiniciar o processo 'acima pode ser muito arriscado, apenas deixe o arquivo de log.

    
por 30.07.2015 / 12:23

Tags