заставить cronjob дождаться завершения предыдущего задания rsync

11

Я использую rsync для резервного копирования некоторых данных с одного сервера на другой. Все работает нормально, но это может занять больше времени, в зависимости от того, сколько данных нужно передать.

Есть ли какой-нибудь гарантированный способ гарантировать, что команда rsync не запустится до того, как предыдущая закончила использовать cronjob?

Например, каждый час я запускаю команду rsync, но, возможно, передача занимает более 1 часа, поэтому следующий начинается до того, как завершится предыдущий.

chovy
источник
Если на выполнение задания может уйти больше часа, и вы планируете его ближе, чем продолжительность, значит, вы неправильно запланировали задание. Либо выясните, как сократить время, либо увеличьте интервал между заданиями. Если вы постоянно делаете удаленные резервные копии, вы можете рассмотреть новый план аварийного восстановления.
vgoff

Ответы:

10

Вы можете реализовать какую-то блокировку. Это напечатает количество процессов rsync, все еще работающих:

pgrep -cx rsync

И это запустит rsync, только если не существует другого процесса rsync:

pgrep -cx rsync || rsync ...

Использование -xпредотвратит случайное сопоставление нежелательных имен (например, «fooba rsync hronizator» или «not_an_ rsync _totally» - это работает так же, как pgrep -c ^rsync$)

mgabriel
источник
В случае, если это не очевидно. -c подсчитывает количество процессов с именем rsync. Если это не 0, то оболочка интерпретирует результат как true (не false). || "or lines" видит, что первый элемент верен, и не беспокойтесь о запуске второго элемента, rsync.
ограбить
12

Вы можете использовать команду flock, чтобы помочь вам сделать это, например. В этом случае flock -n, вероятно, то, что вы хотите, так как это вызовет немедленный сбой команды, если она не может получить блокировку, например

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 
user9517
источник
В общем, предсказуемые имена файлов в / tmp часто опасны из-за состязаний и широкого доступа к каталогу / tmp. Это безопасно в этом случае?
mc0e
В этом случае предсказуемое имя не только безопасно, оно необходимо; это то, что делает блокировку (существительное) блокировкой (глагол). Другими словами, состояние блокировки основано конкретно и исключительно на существовании файла с определенным, предсказуемым именем. Если имя файла было непредсказуемым или динамически изменялось, то flock позволил бы rsync перехватить само себя, нанося поражение цели. Тем не менее, вы можете облегчить свои проблемы, и, возможно, я буду более «правильным», поместив файл блокировки где-нибудь, например, /var/runвместо этого.
Эван де ла Круз
3

Если вы готовы рассмотреть другие инструменты, вы также можете взглянуть на rdiff-backup . Он использует librsync для создания резервных копий и сохраняет настраиваемое количество дельт / приращений. Он также блокируется, так что в любой момент времени может быть запущен только один процесс rdiff-backup.

EdwardTeach
источник
Я также использую rdiff-backup. Но вы должны быть осторожны в этой настройке, так как rdiff-backup занимает больше времени, чем rsync.
mgabriel
3

Вот что я сделаю. Создайте сценарий оболочки вокруг rsync для создания файла блокировки.

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
Просто обязательно удалите файл блокировки после перезагрузки, иначе вы можете получить процесс, который больше никогда не запустится.
Джон Гарденье
2

Мой ответ несколько отличается от того, что сказал Майк.

В сценарии вы должны поместить что-то вроде этого:

  • создать файл блокировки
  • Проверьте наличие файла блокировки при следующем запуске.

Но есть одна очень важная вещь, которую вы должны делать. и чтобы реализовать систему ловушек.

Итак, что вы можете сделать, так это то, что даже если каким-то образом ваш скрипт был убит или кто-то его убил, вы можете перехватить этот сигнал и удалить файл блокировки, чтобы у вас не было устаревшего файла блокировки.

Вы можете прочитать, как реализовать это здесь .

Еще одна маленькая вещь: вы не можете перехватить сигнал 9, я имею в виду, что если кто-то это сделает kill -9, вы не можете перехватить его, так как этот сигнал напрямую взаимодействует с ядром, и нет способа отловить это.

Кроме того, по предложению Джона, вам нужно удалять файл блокировки при каждой перезагрузке системы, просто чтобы убедиться, что не осталось устаревших файлов.

Это легко сделать, поместив небольшую rm -f <FILE>команду в /etc/rc.local

Napster_X
источник
1

Посмотрите на анакрон (анахроничный хрон) с ключом -s (сериализация). Сериализация гарантирует, что команда больше не будет вызываться, если предыдущая все еще выполняется.

Tu-Reinstate Моника-Дор Дух
источник
Вы, возможно, неправильно поняли вопрос.
Джон Гарденье
Я так не думаю. Вопрос в том, есть ли какой-нибудь гарантированный способ гарантировать, что команда rsync не запустится до того, как предыдущая закончила использовать cronjob? Anacron запускает cronjobs с дополнительной / другой функциональностью. Сериализация гарантирует, что любая команда, которую вы вызываете, не запускается, пока не завершится предыдущая.
Tu-Reinstate Моника-Дор-Дух
Мои извенения. Это я неправильно понял вопрос.
Джон Гарденье
0

Используйте hatools ( http://www.fatalmind.com/software/hatools/ ), чтобы заблокировать rsync cron в режиме ожидания.

Казимирас Алиулис
источник
Разве это не просто обертка вокругflock(1)
WarmWaffles
0

Я не смог заставить решение mgabriel работать на OSX, так как версия pgrep для OSX, по-видимому, не имеет опции -c (я полагаю, это для подсчета). Вместо этого я использовал следующее:

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

Я использовал ping в качестве примера команды.

Надеюсь это поможет.

kabadisha
источник