Se o Apache estiver escrevendo um arquivo de algum tipo em um local e não tiver concluído a gravação e depois rsync
entrar em ação, rsync
copiará o que estiver lá.
Ou seja, se o Apache estiver lidando com um arquivo de 5 MB, apenas 2 MB são gravados e rsync
entram em ação, o arquivo parcial de 2 MB será copiado. Portanto, esse arquivo parece estar "corrompido" no servidor de destino.
Dependendo do tamanho dos arquivos que você está usando, você pode usar a --inplace
opção rsync
para fazer o seguinte:
Esta opção altera a maneira como o rsync transfere um arquivo quando os dados do arquivo precisam ser atualizados: em vez do método padrão de criar uma nova cópia do arquivo e movê-lo para o lugar quando estiver concluído, o rsync grava os dados atualizados diretamente no destino Arquivo.
A vantagem disso é que, se um arquivo de 5 MB tiver apenas 2 MB copiados na primeira execução, a próxima será recuperada com 2 MB e continuará a copiar o arquivo até que os 5 MB completos estejam no local.
O negativo é que isso pode criar uma situação em que alguém está acessando o servidor da web enquanto um arquivo está sendo copiado e então eles vêem um arquivo parcial. Na minha opinião, rsync
funciona melhor em seu comportamento padrão de armazenar em cache um arquivo "invisível" e depois movê-lo para o lugar imediatamente. Mas --inplace
é bom para cenários em que arquivos grandes e restrições de largura de banda podem impedir que um arquivo grande seja facilmente copiado da estaca zero.
Disse que você afirma isso; ênfase é minha:
A cada cinco minutos , o cron roda o rsync…
Então, suponho que você tenha algum script bash para gerenciar esse trabalho cron? Bem, a coisa é rsync
inteligente o suficiente para copiar apenas os arquivos que precisam ser copiados. E se você tem um script que é executado a cada 5 minutos, parece que você está tentando evitar rsync
entrar um no outro se for mais rápido. Ou seja, se você executá-lo a cada minuto, existe o risco de que um ou mais rsync
processos ainda estejam em execução devido ao tamanho do arquivo ou à velocidade da rede e o próximo processo estará apenas em concorrência com ele; uma condição de corrida.
Uma maneira de evitar isso é agrupar todo o rsync
comando em um script bash que verifique se há um bloqueio de arquivo; abaixo está uma estrutura de script bash padrão que eu uso para casos como este.
Observe que algumas pessoas recomendam o uso, flock
mas como flock
não está instalado em alguns sistemas que eu uso - e eu pulo muito entre o Ubuntu (que possui) e o Mac OS X (que não possui) - eu uso essa estrutura simples sem nenhum problema real:
LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'
if mkdir ${LOCK_DIR} 2>/dev/null; then
# If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
echo $$ > ${PID_FILE}
echo "Hello world!"
rm -rf ${LOCK_DIR}
exit
else
if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
# Confirm that the process file exists & a process
# with that PID is truly running.
echo "Running [PID "$(cat ${PID_FILE})"]" >&2
exit
else
# If the process is not running, yet there is a PID file--like in the case
# of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
rm -rf ${LOCK_DIR}
exit
fi
fi
A idéia é que o núcleo geral - onde eu tenho echo "Hello world!"
- é onde está o coração do seu script. O resto é basicamente um mecanismo / lógica de bloqueio baseado mkdir
. Uma boa explicação do conceito está nesta resposta :
O mkdir cria um diretório se ele ainda não existe e, se existir, define um código de saída. Mais importante, ele faz tudo isso em uma única ação atômica, tornando-o perfeito para esse cenário.
Portanto, no caso do seu rsync
processo, eu recomendaria o uso desse script apenas alterando o echo
comando para seu rsync
comando. Além disso, mude LOCK_NAME
para algo como RSYNC_PROCESS
e então você estará pronto.
Agora, com o seu rsync
envolto neste script, você pode configurar o cron para executar a cada minuto, sem qualquer risco de uma condição de corrida em que dois ou mais rsync
processos estejam lutando para fazer a mesma coisa. Isso permitirá aumentar a velocidade ou as rsync
atualizações, o que não eliminará o problema de transferência parcial de arquivos, mas ajudará a acelerar o processo geral, para que o arquivo completo possa ser copiado adequadamente em algum momento.