Назад | Перейти на главную страницу

Как лучше всего запланировать выполнение команды, убедившись, что предыдущий набор команд выполнен?

А именно, мне нужно повернуть папки с резервными копиями. У меня есть много машин по расписанию для rsync с одной резервной машиной. Хотя я планирую начало резервного копирования поздно вечером и планирую ротацию папок (чтобы папка day0 стала day1, начиная с самой старой) поздним утром следующего дня (обеспечивая, скажем, 10 часов для завершения резервного копирования) , Я хотел бы иметь возможность убедиться, что все резервные копии завершены, прежде чем разрешить начало ротации, вместо того, чтобы делать предположения (потому что, если я чередую папки во время резервного копирования, моя резервная копия будет неточной).

Это было бы тривиально для одной машины, но для нескольких, я надеюсь, кто-то знает лучший метод ... Я могу придумать несколько, но предпочел бы не «экспериментировать» с работающими системами:

Должна ли каждая резервная копия создавать отметку о завершении и запускать сценарий ротации каждые несколько минут по истечении определенного времени, проверяя, что он еще не был успешно запущен и что все отметки являются текущими (старше, чем последняя отметка сценария вращения)?

У каждой резервной копии mv их предыдущий rsync в текущую папку, rsync, затем mv обратно на day0, чтобы при ротации эта резервная копия просто пропускалась, если она не завершена?

Просто жить с потенциально неточными резервными копиями?

Я бы, вероятно, написал файл завершения на центральном сервере, который включает дату и имя хоста; вы можете использовать это:

#!/bin/bash
# when each backup completes, write a completion file:
ssh user@central-server "touch /path/to/completion-files/$HOST-$(date +%F).complete"

И на центральном сервере:

#!/bin/bash
# on the central server, run this before attempting folder rotation
for h in (list of hosts); do
  if [[ -e "/path/to/completion-files/$h-$(date +%F)" ]]; 
    then # do your thing
  fi
done

Чтобы атаковать более общий случай, то есть "Как лучше всего запланировать выполнение команды, убедившись, что предыдущий набор команд выполнен?"

вам нужно запустить команду и проверить успешность (код выхода), затем вы можете запланировать выполнение команды с помощью системного планировщика (обычно в). Например:

 #!/bin/bash
 rsync "${opts[@]}" "$source" "$dest"
 if [[ $? -eq 0 ]]; then
   at now+10hours <<<"~jdoe/bin/rotatefolders.sh"
 fi

Я предположил, что здесь был назван сценарий поворота вашей папки rotatefolders.sh в мусорное ведро в домашней папке jdoe.

Поскольку вы используете rsync, я предполагаю, что вы делаете это через ssh-туннель. Если да, то у вас тоже есть ssh.

Вместо цикла ожидания занятости лучше использовать сигнализацию о завершении задания rsync.

«Сигнал» может запускать log-rotate в системе backup.server - либо путем прямого запуска logrotate, либо косвенного запуска (через sudo или ssh-key).

Вы можете использовать файл pid:

PID_FILE="/path/to/pid.pid"   
    if [ -f $PID_FILE ]
    then
            OLD_PID=`cat $PID_FILE`
            RUNNING=`ps aux |grep $OLD_PID|grep -v grep|wc -l`
            if [ $RUNNING -gt 0 ]
            then
                    echo "WARNING PROGRAM already running"
                    exit 0
            else
                    echo "PID file exists but program is not running. Overriding PID file"
            fi
    fi
    echo $$ > $PID_FILE
    trap "rm -f $PID_FILE; exit" INT TERM EXIT

Совместно используя файл pid, вы убедитесь, что B не запустится, пока A не завершит работу, и наоборот.