każ cronjobowi czekać na zakończenie poprzedniej pracy rsync

11

Używam rsync do tworzenia kopii zapasowych niektórych danych z jednego serwera na drugi. Wszystko działa dobrze, ale może potrwać dłużej, w zależności od ilości danych do przesłania.

Czy istnieje jakiś sposób, aby upewnić się, że polecenie rsync nie uruchomi się, zanim poprzednie nie zakończy korzystania z cronjob?

Na przykład co godzinę uruchamiam polecenie rsync, ale możliwe jest, że transfer trwa dłużej niż godzinę, więc następna rozpocznie się przed zakończeniem poprzedniej.

chovy
źródło
Jeśli wykonanie zadania może potrwać dłużej niż godzinę, a planujesz je bliżej niż czas trwania, oznacza to, że zadanie jest źle zaplanowane. Zastanów się, jak skrócić czas lub zwiększyć odstępy między zadaniami. Jeśli ciągle tworzysz zdalne kopie zapasowe, możesz rozważyć nowy plan odzyskiwania po awarii.
vgoff

Odpowiedzi:

11

Możesz wdrożyć pewien rodzaj blokady. Spowoduje to wydrukowanie liczby uruchomionych procesów rsync:

pgrep -cx rsync

Spowoduje to uruchomienie rsync tylko wtedy, gdy nie istnieje żaden inny proces rsync:

pgrep -cx rsync || rsync ...

Użycie -xzapobiegnie przypadkowemu dopasowaniu niechcianych nazw (na przykład „fooba rsync hronizator” lub „not_an_ rsync _totally ” - działa tak jak pgrep -c ^rsync$)

mgabriel
źródło
W przypadku, gdy nie jest to oczywiste. -c zlicza liczbę procesów o nazwie rsync. Jeśli nie jest to 0, powłoka interpretuje wynik jako prawdziwy (nie fałszywy). || „lub wiersze”, czy pierwszy element jest prawdziwy i nie zawracaj sobie głowy uruchomieniem drugiego elementu, rsync.
rab
13

Możesz użyć polecenia flock, aby to zrobić, np. W tym przypadku flock -nprawdopodobnie jest to, co chcesz, ponieważ spowoduje natychmiastową awarię polecenia, jeśli nie może uzyskać blokady, np.

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 
użytkownik9517
źródło
Zasadniczo przewidywalne nazwy plików w / tmp są często niebezpieczne ze względu na warunki wyścigu i szeroki dostęp do katalogu / tmp. Czy w tym przypadku jest bezpiecznie?
mc0e
W takim przypadku przewidywalna nazwa jest nie tylko bezpieczna, jest konieczna; to właśnie sprawia, że ​​blokada (rzeczownik) blokuje (czasownik). Innymi słowy, stan blokady opiera się konkretnie i wyłącznie na istnieniu pliku o określonej, przewidywalnej nazwie. Jeśli nazwa pliku była nieprzewidywalna lub zmieniła się dynamicznie, flock pozwoliłby, aby rsync przejechał sam siebie, pokonując cel. Możesz jednak złagodzić swoje obawy i imo być bardziej „poprawnym”, umieszczając plik blokady w miejscu takim jak /var/runzamiast.
Evan de la Cruz,
3

Jeśli chcesz rozważyć inne narzędzia, możesz także zapoznać się z rdiff-backup . Używa librsync do wykonywania kopii zapasowych i zapisuje konfigurowalną liczbę delt / przyrostów. Blokuje się również, aby w danym momencie mógł działać tylko jeden proces tworzenia kopii zapasowych rdiff.

EdwardTeach
źródło
Używam także rdiff-backup. Ale musisz być ostrożny w tej konfiguracji, ponieważ rdiff-backup zajmuje więcej czasu niż samo rsync.
mgabriel
3

Oto co bym zrobił. Utwórz skrypt otoki wokół rsync, aby utworzyć plik blokady.

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
Mikrofon
źródło
2
Pamiętaj tylko o usunięciu pliku blokady po ponownym uruchomieniu, w przeciwnym razie możesz zakończyć się procesem, który nigdy się nie uruchomi.
John Gardeniers,
2

Moja odpowiedź jest nieco taka sama, jak powiedział Mike.

W skrypcie powinieneś umieścić coś takiego:

  • utwórz plik blokady
  • Sprawdź, czy plik blokady istnieje podczas następnego uruchomienia.

Ale jest jedna bardzo ważna rzecz, którą powinieneś zrobić. i żeby wprowadzić system pułapek.

Tak więc dzięki temu, nawet jeśli w jakiś sposób twój skrypt zostanie zabity lub ktoś go zabije, możesz złapać ten sygnał i usunąć plik blokady, aby nie mieć nieaktualnego pliku blokady.

Można przeczytać, jak wdrożyć, że ponad tutaj .

Tylko jedna mała rzecz, nie możesz złapać pułapki na sygnał 9, to znaczy, jeśli ktoś tak zrobi kill -9, nie możesz złapać tego w pułapkę, ponieważ ten sygnał bezpośrednio oddziałuje z jądrem i nie ma sposobu, aby to zrobić.

Ponadto, zgodnie z sugestią Johna, musisz usunąć plik blokady przy każdym ponownym uruchomieniu systemu, aby upewnić się, że nie ma już przestarzałego pliku.

Można to łatwo zrobić, umieszczając małe rm -f <FILE>polecenie w /etc/rc.local

Napster_X
źródło
1

Spójrz na anakron (anachroniczny cron) z przełącznikiem -s (serializuj). Serializacja zapewnia, że ​​polecenie nie zostanie ponownie wywołane, jeśli poprzednie nadal działa.

tu-Reinstate Monica-dor duh
źródło
Być może źle zrozumiałeś pytanie.
John Gardeniers,
Nie wydaje mi się Pytanie brzmi: „Czy istnieje jakiś sposób, aby upewnić się, że komenda rsync nie uruchomi się, zanim poprzednia zakończy pracę z cronjob?” Anacron uruchamia cronjobs z dodatkowymi / różnymi funkcjami. Serializacja zapewnia, że ​​każde wywołane polecenie nie uruchomi się, dopóki poprzednie nie zakończy się.
Tu-Reinstate Monica-dor duh
Przepraszam. To ja źle odczytałem pytanie.
John Gardeniers,
0

Nie mogłem dostać rozwiązania mgabriel do pracy na OSX, ponieważ wersja pgrep w OSX nie wydaje się mieć opcji -c (zakładam, że jest to do zliczenia). Zamiast tego użyłem następującego:

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

Użyłem polecenia ping jako polecenia przykładowego.

Mam nadzieję że to pomoże.

kabadisha
źródło