Como posso capturar um instantâneo consistente de um diretório e de todos os seus filhos?

2

Temos um aplicativo que periodicamente faz backup de um diretório no sistema de arquivos local. Dentro deste diretório existem vários arquivos e diretórios.

Eu quero produzir um "instantâneo" de todos esses arquivos que podem ser copiados para o armazenamento de backup.

Mais importante, como posso produzir esse "instantâneo" de maneira atômica? Tenha em mente que o tempo todo, qualquer um desses arquivos pode ser modificado pelo daemon de backup tornando nosso "instantâneo" inconsistente.

Editar:

Talvez eu deva mencionar que o sistema tem um sistema de arquivos ext4 .

    
por AlfaZulu 06.06.2014 / 21:18

2 respostas

1

Até onde sei, a atomicidade de tal transação não pode ser garantida pelo ext4 em si sem a cooperação do aplicativo que está acessando os dados simultaneamente. Usar algum mecanismo de instantâneo em um mapeador de dispositivo subjacente também não funcionará, já que basicamente seria necessário desmontar o sistema de arquivos (ou pelo menos remontar-ro) para obter um estado consistente no nível do dispositivo de bloco.

Eu acho que sem conhecimento adicional sobre o comportamento do aplicativo, isso vai ser bastante complicado. Portanto, a saída mais fácil é provavelmente modificar o aplicativo de alguma forma (como a introdução de um arquivo de bloqueio). Se, no entanto, você precisar tratá-la como uma caixa preta, vou fazer algumas suposições sobre isso:

  1. O backup periódico pelo aplicativo leva apenas um curto período de tempo em comparação com o intervalo em que é realizado
  2. Após concluir o backup, ele fechará todas as alças de arquivo até a próxima execução de backup

Com base nessas suposições, sugiro uma abordagem otimista. Simplificando, tente fazer uma cópia regular, recursiva e não atômica do diretório e verifique depois se o aplicativo tocou em algum dos arquivos. Se isso acontecesse, isso indica que sua cópia infelizmente coincidiu com o backup automático periódico do aplicativo. Nesse caso, descarte a cópia que acabou de criar e tente novamente. Talvez recue por algum tempo; evite um loop infinito que consome recursos.

Você pode implementar isso usando o mecanismo inotify no Linux como um meio de observar os arquivos que deseja copiar durante o processo. Se você está procurando um script de shell simples, dê uma olhada em inotify-tools . Está empacotado na maioria das distros. Não tenho certeza de como o inotify se comporta quando os arquivos já estão abertos, então, referindo-se à suposição número 2, você provavelmente também usará lsof para garantir que seu aplicativo não tenha identificadores de arquivo aberto em nenhum dos conteúdos de sua fonte diretório. Faça isso depois de configurar os relógios inotify.

Então é assim que eu lidaria com sua situação. Espero que você não se importe se eu pular o esboço de uma implementação real disso. Sinta-se à vontade para perguntar se alguma coisa não está clara.

    
por 11.12.2014 / 17:23
0

Se você souber quais processos estão gravando em arquivos nesse diretório, poderá congelá-los usando kill -SIGSTOP <pid> , fazer seu backup e retomar os processos com kill -SIGCONT <pid> .

    
por 11.12.2014 / 17:41