Я написал бы сценарий, который проверяет, существует ли резервная копия больше чем 1,7 или 30 дней и действует соответственно. Вы этого не сказали, но я предполагаю, что вы используете Linux (я добавил тег linux к вашему вопросу), и вы выполняете резервное копирование на удаленный сервер. Первым шагом будет написание небольшого скрипта, который запускает вашу команду rsync
а также создает файл на удаленном сервере после завершения резервного копирования. Это будет использоваться как для того, чтобы узнать, выполняется ли резервное копирование в настоящее время, так и для проверки срока его хранения (я предполагаю, что вы сохраняете исходные метки времени при создании резервных копий файлов, поэтому вы не можете получить дату из самих файлов):
Скрипт Rsync (предполагается, что у вас есть доступ без пароля к удаленному серверу):
#!/usr/bin/env bash
ssh user@remote rm /path/to/daily/backup/backup_finished.txt
rsync /path/to/source/ user@remote:/path/to/daily/backup/
ssh user@remote touch /path/to/daily/backup/backup_finished.txt
На локальном компьютере настройте задачу cron, которая выполняет ежедневное резервное копирование:
@daily rsync_script.sh
На удаленной машине вам нужно запускать скрипт, который я приведу ниже, каждые несколько часов:
@hourly check_backup.sh
Сценарий check_backup.sh:
#!/usr/bin/env bash
daily=/path/to/daily;
weekly=/path/to/weekly;
monthly=/path/to/monthly;
## The dates will be measured in seconds since the UNIX epoch,
## so we need to translate weeks and months (31 days) to seconds.
week=$((60*60*24*7));
month=$((60*60*24*31));
## Make sure no backup is currently running
if [ ! -e $daily/backup_finished.txt ]; then
echo "A backup seems to be running, exiting." && exit;
fi
## Get the necessary dates
weekly_backup_date=$(stat -c %Y $weekly/backup_finished.txt)
monthly_backup_date=$(stat -c %Y $monthly/backup_finished.txt)
now=$(date +%s)
monthly_backup_age=$((now - monthly_backup_date))
weekly_backup_age=$((now - weekly_backup_date))
## Check the age of the daily backup and copy it accordingly
if [[ "$monthly_backup_age" -gt "$month" ]]; then
## Copy unless the current $daily is identical to $weekly
diff $daily $weekly > /dev/null ||
## Delete the previous backup and copy the new one over
rm -rf $monthly && cp -rp $daily $monthly
fi
## Copy the weekly backup if it is older than a week but only
## if it is not identical to $monthly. The -r flag makes cp
## recursive and the -p flag makes it preserve dates and permissions.
if [[ "$weekly_backup_age" -gt "$week" ]]; then
## Copy unless the current $daily is identical to $monthly
diff $daily $monthly > /dev/null ||
rm -rf $weekly && cp -rp $daily $weekly
fi
Таким образом, этот скрипт (check_backup.sh
) будет запускаться каждый час на вашем сервере резервного копирования. Поскольку он ничего не делает, если резервная копия не достаточно старая, запускать ее так часто не составит труда. Теперь каждый раз, когда ежедневная резервная копия старше 31 дня, она будет копироваться в monthly
каталог, а содержимое monthly
будет удаляться. Точно так же для еженедельного, когда резервное копирование более 7 дней.
Я использую diff
для сравнения резервных копий. Это означает, что мы будем копировать daily
в weekly
если текущему weekly
больше недели, но только если резервная копия, которая будет скопирована (текущая daily
), не совпадает с существующей weekly
и аналогично для monthly
. Например, если скрипт только что запустился и увидел, что ежемесячное резервное копирование совпадает с текущим еженедельным, оно не будет перезаписывать существующее monthly
. Однако через неделю, когда weekly
изменится, он будет копировать monthly
.
Конечным результатом этого является то, что в любое время у вас должно быть минимум две разные резервные копии, и обычно у вас будет три. В худшем случае, что-то выходит из строя, и у вас нет резервной копии недельной давности, только месячной или, наоборот, у вас нет месячной резервной копии, но у вас есть резервная копия на прошлой неделе.