fazer um cronjob aguardar a conclusão do trabalho rsync anterior

11

Estou usando o rsync para fazer backup de alguns dados de um servidor para outro. Tudo funciona bem, mas pode demorar mais para terminar, dependendo da quantidade de dados a serem transferidos.

Existe alguma maneira garantida de garantir que um comando rsync não seja iniciado antes que o anterior termine o uso de um cronjob?

Por exemplo, a cada hora eu executo o comando rsync, mas é possível que a transferência demore mais de 1 hora para ser concluída, portanto a próxima iniciará antes que a anterior termine.

chovy
fonte
Se o trabalho levar potencialmente mais de uma hora para ser concluído e você o agendar mais próximo do que a duração, estará agendando incorretamente o trabalho. Descubra como reduzir o tempo ou aumentar o intervalo entre os trabalhos. Se você estiver executando continuamente backups remotos, considere um novo plano de recuperação de desastre.
vgoff

Respostas:

10

Você pode implementar algum tipo de bloqueio. Isso imprimirá o número de processos rsync ainda em execução:

pgrep -cx rsync

E isso executará o rsync apenas se não houver outro processo rsync:

pgrep -cx rsync || rsync ...

O uso -ximpedirá a correspondência acidental de nomes indesejados (por exemplo, "fooba rsync hronizator" ou "not_an_ rsync _totally" - funciona da mesma maneira pgrep -c ^rsync$)

mgabriel
fonte
Caso isso não seja óbvio. -c conta o número de processos que têm o nome rsync. Se este não for 0, o shell interpretará o resultado como verdadeiro (não falso). O || "ou linhas", veja se o primeiro item é verdadeiro e não se preocupe em executar o segundo item, rsync.
22617 Rob
12

Você pode usar o comando flock para ajudá-lo a fazer isso, por exemplo. Nesse caso, flock -nprovavelmente é o que você deseja, pois causará uma falha imediata do comando se ele não puder obter o bloqueio, por exemplo.

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 
user9517
fonte
Em geral, os nomes de arquivos previsíveis em / tmp geralmente são perigosos devido às condições de corrida e amplo acesso ao diretório / tmp. É seguro neste caso?
Mc0e
Nesse caso, um nome previsível não é apenas seguro, é necessário; é isso que faz o bloqueio (substantivo) bloquear (verbo). Em outras palavras, o estado do bloqueio é baseado específica e exclusivamente na existência de um arquivo com um nome específico e previsível. Se o nome do arquivo fosse imprevisível ou se fosse alterado dinamicamente, o flock permitiria que o rsync funcionasse sozinho, derrotando o objetivo. No entanto, você pode aliviar suas preocupações e ser um pouco mais "correto", colocando o arquivo de bloqueio em algum lugar, como em /var/runvez disso.
Evan de la Cruz
3

Se você estiver disposto a considerar outras ferramentas, também poderá dar uma olhada no rdiff-backup . Ele usa o librsync para fazer backups e salva um número configurável de deltas / incrementos. Ele também é bloqueado para que apenas um processo de backup de rdiff possa ser executado a qualquer momento.

EdwardTeach
fonte
Eu uso rdiff-backup também. Mas você precisa ter cuidado nessa configuração, pois o rdiff-backup leva mais tempo para ser concluído do que o rsync sozinho.
mgabriel
3

Aqui está o que eu faria. Crie um script de wrapper em torno do rsync para criar um arquivo de bloqueio.

script 1
- create lock file
- rsync
- remove lock file

script 2 (running later then script 1)
- check if lock file is there
    - if not run
    - if it is there wait 10 minutes in a loop. break out of lopp when the lock file is gone
- continue to run script
Mike
fonte
2
Apenas certifique-se de remover também o arquivo de bloqueio após uma reinicialização, caso contrário, você poderá acabar com um processo que nunca será executado novamente.
John Gardeniers
2

Minha resposta é o mesmo que Mike disse.

No script, você deve colocar algo como isto:

  • crie um arquivo de bloqueio
  • Verifique a existência do arquivo de bloqueio ao executá-lo na próxima vez.

Mas há uma coisa muito importante que você deveria estar fazendo. e isso para implementar um sistema de interceptação.

Então, com isso, o que você pode fazer é que, mesmo que de alguma forma seu script seja morto ou alguém o tenha matado, você poderá capturar esse sinal e remover o arquivo de bloqueio, para não ter um arquivo de bloqueio obsoleto.

Você pode ler como implementar isso aqui .

Apenas uma pequena coisa, você não pode capturar o sinal 9, quero dizer, se alguém o fizer kill -9, você não poderá capturá-lo, pois esse sinal interage diretamente com o kernel e não há como capturá-lo.

Além disso, conforme sugerido por John, você precisa remover o arquivo de bloqueio sempre que o sistema for reiniciado, apenas para garantir que não exista nenhum arquivo obsoleto.

Isso você pode fazer facilmente colocando um pequeno rm -f <FILE>comando em /etc/rc.local

Napster_X
fonte
1

Dê uma olhada no anacron (cron anacrônico) com a opção -s (serialize). Serializar garante que o comando não será chamado novamente se o anterior ainda estiver em execução.

restabelecer Monica-dor duh
fonte
Você pode ter entendido mal a pergunta.
John Gardeniers
Acho que não. A pergunta é "Existe alguma maneira garantida de garantir que um comando rsync não seja iniciado antes do comando anterior terminar de usar um cronjob?" O Anacron executa cronjobs com funcionalidade extra / diferente. Serializar garante que qualquer comando que você chame não seja iniciado até a conclusão do comando anterior.
tu restabelece Monica-dor duh
Me desculpe. Foi -me que descaracterizou a pergunta.
John Gardeniers 31/12/12
0

Não consegui que a solução do mgabriel funcionasse no OSX, pois a versão OSX do pgrep não parece ter a opção -c (presumo que isso seja importante). Em vez disso, usei o seguinte:

[ $(pgrep ping | wc -l) -eq 0 ] && ping multiplay.co.uk || echo "Sorry, ping already in progress"

Eu usei ping como um comando de exemplo.

Espero que isto ajude.

kabadisha
fonte