hacer que un cronjob espere a que finalice el trabajo rsync anterior

11

Estoy usando rsync para hacer una copia de seguridad de algunos datos de un servidor a otro. Todo funciona bien, pero puede tardar más en terminar dependiendo de la cantidad de datos que hay que transferir.

¿Hay alguna forma garantizada de garantizar que un comando rsync no se inicie antes de que el anterior termine de usar un cronjob?

Por ejemplo, cada hora ejecuto el comando rsync, pero es posible que la transferencia tarde más de 1 hora en completarse, por lo que la siguiente comenzará antes de que finalice la anterior.

chovy
fuente
Si el trabajo demora potencialmente más de una hora en completarse, y lo está programando más cerca de la duración, entonces está programando mal el trabajo. O bien, descubra cómo reducir el tiempo o aumentar el intervalo entre trabajos. Si continuamente realiza copias de seguridad remotas, es posible que desee considerar un nuevo plan de recuperación ante desastres.
vgoff

Respuestas:

11

Puede implementar algún tipo de bloqueo. Esto imprimirá la cantidad de procesos rsync que aún se ejecutan:

pgrep -cx rsync

Y esto ejecutará rsync solo si no existe otro proceso rsync:

pgrep -cx rsync || rsync ...

El uso -xevitará la coincidencia accidental de nombres no deseados (por ejemplo, "fooba rsync hronizator" o "not_an_ rsync _totally", funciona igual que pgrep -c ^rsync$)

mgabriel
fuente
En caso de que no sea obvio. -c cuenta el número de procesos que tienen el nombre rsync. Si esto no es 0, el shell interpreta el resultado como verdadero (no falso). El || "o líneas" ven que el primer elemento es verdadero y no se molestan en ejecutar el segundo elemento, rsync.
robar el
13

Puede usar el comando flock para ayudarlo a hacer esto, por ejemplo, en este caso flock -nes probablemente lo que desea, ya que provocará una falla inmediata del comando si no puede obtener el bloqueo, por ejemplo

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 
usuario9517
fuente
En general, los nombres de archivo predecibles en / tmp a menudo son peligrosos debido a las condiciones de carrera y al amplio acceso al directorio / tmp. ¿Es seguro en este caso?
mc0e
En este caso, un nombre predecible no solo es seguro, es necesario; eso es lo que hace que el bloqueo (sustantivo) se bloquee (verbo). En otras palabras, el estado del bloqueo se basa específica y únicamente en la existencia de un archivo con un nombre específico y predecible. Si el nombre del archivo era impredecible, o si cambiaba dinámicamente, entonces el lote permitiría que rsync se ejecutara sobre sí mismo, lo que frustraría el propósito. Sin embargo, puede aliviar sus inquietudes e, incluso, ser un poco más "correcto", colocando el archivo de bloqueo en algún lugar como en su /var/runlugar.
Evan de la Cruz
3

Si está dispuesto a considerar otras herramientas, también puede echar un vistazo a rdiff-backup . Utiliza librsync para hacer copias de seguridad y guarda un número configurable de deltas / incrementos. También se bloquea para que solo un proceso de rdiff-backup pueda ejecutarse en un momento dado.

EdwardTeach
fuente
Yo uso rdiff-backup también. Pero debe tener cuidado en esta configuración ya que rdiff-backup tarda más tiempo en completarse que rsync solo.
mgabriel
3

Esto es lo que haría. Cree un script de envoltura alrededor de rsync para crear un archivo de bloqueo.

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
Miguel
fuente
2
Solo asegúrese de eliminar también el archivo de bloqueo después de un reinicio, de lo contrario podría terminar con un proceso que nunca se ejecuta nuevamente.
John Gardeniers
2

Mi respuesta es algo similar a lo que Mike dijo.

En el script, deberías poner algo como esto:

  • crear un archivo de bloqueo
  • Verifique la existencia del archivo de bloqueo la próxima vez que lo ejecute.

Pero hay una cosa muy importante que deberías estar haciendo. y eso para implementar un sistema de trampa.

Entonces, con eso, lo que puedes hacer es que, incluso si de alguna manera tu script es eliminado o alguien lo eliminó, entonces puedes atrapar esa señal y eliminar el archivo de bloqueo, para que no tengas un archivo de bloqueo obsoleto.

Puedes leer cómo implementar eso aquí .

Solo una pequeña cosa, no puedes atrapar la señal 9, quiero decir que si alguien lo hace kill -9, no puedes atrapar eso ya que esa señal interactúa directamente con el núcleo y no hay forma de atrapar eso.

Además, como lo sugiere John, debe eliminar el archivo de bloqueo cada vez que se reinicia el sistema, solo para asegurarse de que no quede ningún archivo obsoleto.

Eso puede hacerlo fácilmente poniendo un pequeño rm -f <FILE>comando en /etc/rc.local

Napster_X
fuente
1

Eche un vistazo a anacron (cron anacrónico) con el modificador -s (serializar). Serialize garantiza que no se volverá a llamar al comando si el anterior todavía se está ejecutando.

tu-Reinstate Monica-dor duh
fuente
Puede haber entendido mal la pregunta.
John Gardeniers
No lo creo. La pregunta es "¿Hay alguna forma garantizada de garantizar que un comando rsync no se inicie antes de que el anterior termine de usar un cronjob?" Anacron ejecuta cronjobs con funcionalidad extra / diferente. Serialize garantiza que cualquier comando que llame no se inicie hasta que finalice el anterior.
tu-Reinstate Monica-dor duh
Mis disculpas. Era yo que leyó mal la pregunta.
John Gardeniers
0

No pude obtener la solución de mgabriel para trabajar en OSX ya que la versión OSX de pgrep no parece tener la opción -c (supongo que esto es para contar). En su lugar, utilicé lo siguiente:

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

Usé ping como un comando de ejemplo.

Espero que esto ayude.

kabadisha
fuente