fare in modo che cronjob attenda il completamento del precedente processo rsync


11

Sto usando rsync per eseguire il backup di alcuni dati da un server a un altro. Tutto funziona bene, ma potrebbe richiedere più tempo per terminare a seconda della quantità di dati da trasferire.

Esiste un modo garantito per garantire che un comando rsync non si avvii prima che il precedente abbia finito di usare un cronjob?

Ad esempio, ogni ora che eseguo il comando rsync, ma è possibile che il trasferimento richieda più di 1 ora per essere completato, quindi il prossimo inizierà prima del precedente.


Se il lavoro richiede potenzialmente più di un'ora per completarsi e lo si sta pianificando più vicino della durata, allora si sta pianificando erroneamente il lavoro. O capire come ridurre i tempi o aumentare l'intervallo tra i lavori. Se si eseguono continuamente backup remoti, è possibile prendere in considerazione un nuovo piano di ripristino di emergenza.
vgoff,

Risposte:


11

È possibile implementare un tipo di blocco. Questo stamperà il numero di processi rsync ancora in esecuzione:

pgrep -cx rsync

E questo eseguirà rsync solo se non esiste nessun altro processo rsync:

pgrep -cx rsync || rsync ...

L'uso -ximpedirà la corrispondenza accidentale di nomi indesiderati (ad esempio "fooba rsync hronizator" o "not_an_ rsync _totally" - funziona esattamente come pgrep -c ^rsync$)


Nel caso in cui non sia ovvio. -c conta il numero di processi che hanno il nome rsync. Se questo non è 0, la shell interpreta il risultato come vero (non falso). Il || "o righe" vedono che il primo elemento è vero e non preoccuparti di eseguire il secondo elemento, rsync.
rapina il

13

Puoi usare il comando flock per aiutarti a fare questo ad es. In questo caso flock -nè probabilmente quello che vuoi in quanto causerà un immediato fallimento del comando se non può ottenere il blocco ad es.

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 

In generale, i nomi di file prevedibili in / tmp sono spesso pericolosi a causa delle condizioni di competizione e dell'ampio accesso alla directory / tmp. È sicuro in questo caso?
mc0e

In questo caso un nome prevedibile non è solo sicuro, è necessario; questo è ciò che rende il lock (sostantivo) lock (verbo). In altre parole, lo stato del blocco si basa specificamente e unicamente sull'esistenza di un file con un nome specifico e prevedibile. Se il nome del file fosse imprevedibile, o se fosse cambiato dinamicamente, allora flock avrebbe permesso a rsync di funzionare su se stesso, vanificando lo scopo. Tuttavia, puoi alleviare le tue preoccupazioni e imo essere un po 'più "corretto", mettendo il file di blocco da qualche parte come /var/runinvece.
Evan de la Cruz,

3

Se sei disposto a prendere in considerazione altri strumenti, puoi anche dare un'occhiata a rdiff-backup . Utilizza librsync per eseguire i backup e salva un numero configurabile di delta / incrementi. Si blocca anche in modo che un solo processo di backup rdiff possa essere eseguito in un dato momento.


Uso anche rdiff-backup. Ma devi fare attenzione in questa configurazione poiché rdiff-backup richiede più tempo per il completamento rispetto a rsync da solo.
mgabriel,

3

Ecco cosa farei. Crea uno script wrapper attorno a rsync per creare un file di blocco.

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

2
Assicurati di rimuovere anche il file di blocco dopo un riavvio, altrimenti potresti finire con un processo che non verrà più eseguito.
John Gardeniers,

2

La mia risposta è in qualche modo la stessa cosa ha detto Mike.

Nella sceneggiatura, dovresti inserire qualcosa del genere:

  • creare un file di blocco
  • Verificare l'esistenza del file di blocco alla successiva esecuzione.

Ma c'è una cosa molto importante che dovresti fare. e quello per implementare un sistema di trap.

Quindi, ciò che puoi fare è che anche se in qualche modo il tuo script viene ucciso o qualcuno lo ha ucciso, allora puoi intercettare quel segnale e rimuovere il file di blocco, in modo da non avere un file di blocco obsoleto.

Puoi leggere come implementarlo qui .

Solo una piccola cosa, non puoi intrappolare il segnale 9, voglio dire se qualcuno lo fa kill -9, non puoi intrappolarlo poiché quel segnale interagisce direttamente con il kernel e non c'è modo di intrappolarlo.

Inoltre, come suggerito da John, è necessario rimuovere il file di blocco ogni volta che il sistema si riavvia, solo per assicurarsi che non sia rimasto alcun file obsoleto.

Che puoi fare facilmente inserendo un piccolo rm -f <FILE>comando in /etc/rc.local


1

Dai un'occhiata ad anacron (anachronistic cron) con l'opzione -s (serialize). Serialize assicura che il comando non verrà più richiamato se il precedente è ancora in esecuzione.


Potresti aver frainteso la domanda.
John Gardeniers,

Io non la penso così. La domanda è "Esiste un modo garantito per garantire che un comando rsync non si avvii prima che il precedente abbia finito di usare un cronjob?" Anacron esegue cronjobs con funzionalità extra / diverse. Serialize assicura che qualsiasi comando chiamato non inizi fino al termine di quello precedente.
tu-Reinstate Monica-dor duh

Mie scuse. Sono stato io a fraintendere la domanda.
John Gardeniers,


0

Non sono riuscito a far funzionare la soluzione di mgabriel su OSX poiché la versione OSX di pgrep non sembra avere l'opzione -c (suppongo che sia per il conteggio). Invece ho usato il seguente:

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

Ho usato il ping come comando di esempio.

Spero che questo ti aiuti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.