Простой скрипт дифференциального бэкапа каталогов при помощи TAR.
Скрипт работает следующим образом, каждый день создается дифференциальный бэкап, в случае если бэкапов не было еще сделано, то первый созданный бэкап будет полным, последующие дифференциальными .
При этом раз в неделю создается полный бэкап каталога. После создания полного бэкапа дифференциальные бэкапы начинают перезаписываться.
Для того чтоб восстановить бэкап на конкретную дату, необходимо развернуть полный бэкап и в него же развернуть дифференциальный бэкап с нужной датой.
Запускать можно как в ручном режиме, так и добавив задание в расписание по cron.
Например вот так:
1 2 3 |
> /backup/arch/backup.sh myfolder > crontab -l * 6 * * * /backup/arch/backup.sh /myfolder |
Таким образом каждый день в 6 утра будет создоваться бэкап каталога myfolder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#!/bin/sh - # Для дебага использоват -vx # Copyright labor24krs - http://blog.nahoste.ru/ # Цель бэкапа TARGET=$1 # Чем баэкапим TAR=/bin/tar # Откуда бэкапим SOURCE_PATH=/backup/nas # Куда бэкапим BACKUP_PATH=/backup/arch/bc # День недели в который создается полный бэкап FULL_BACKUP_DAY=6 # Формат дат ддммгг # Текущая дата DATE=`/bin/date +%d%m%y` # Вчерашний день DAY_AGO=`/bin/date --date="1 days ago" +%d%m%y` # Неделя назад WEEK_AGO=`/bin/date --date="1 weeks ago" +%d%m%y` # 2 неделя назад TWO_WEEK_AGO=`/bin/date --date="2 weeks ago" +%d%m%y` # Текущий день недели DAY_WEEK=`/bin/date +%u` # Число в этот день недели, неделю назад DATE_WEEK_AGO=`/bin/date --date="1 weeks ago" +%d` # Название дня DAY_NAME=`/bin/date +%A` # Устаревший полный бэкап OLD_BACKUP=$TWO_WEEK_AGO # Устаревший диференциальный бэкап OLD_DIFF_BACKUP=$WEEK_AGO # Бэкап логи #touch $BACKUP_PATH/logs/$DATE-$TARGET-backup.log #$BLOG=$BACKUP_PATH/logs/$DATE-$TARGET-backup.log full_backup(){ echo `date`" Сегодня $DAY_NAME, делаем полный бэкап таргета $TARGET" > $BACKUP_PATH/logs/$DATE-$TARGET-backup.log start_time=`/bin/date +%s` # Перед созданием нового полного бэкапа, необходимо удалить старый не актульный бэкап. # Если полный бэкап существует. if [ -f $BACKUP_PATH/$TARGET/$OLD_BACKUP-Full.tar.gz ] then echo `date`" Удаляем не актуальный полный бэкап $BACKUP_PATH/$TARGET/$OLD_BACKUP-Full.tar.gz" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log rm $BACKUP_PATH/$TARGET/$OLD_BACKUP-Full.tar.gz echo `date`" Удаляем не актуальный мета файл полного бэкапа $BACKUP_PATH/$TARGET/.$DAY_WEEK-Full.meta" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log rm $BACKUP_PATH/$TARGET/.$DAY_WEEK-Full.meta fi # Проверяем есть ли у нас каталог таргета if [ -d $BACKUP_PATH/$TARGET ] then echo `date`" Каталог таргета $TARGET создан" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log else echo `date`" Создаем каталог таргета $TARGET" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log mkdir $BACKUP_PATH/$TARGET fi echo `date`" Создаем полный бэкап таргета $TARGET" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log $TAR --create --ignore-failed-read --one-file-system --preserve-permissions --recursion --sparse --totals --gzip \ --file=$BACKUP_PATH/$TARGET/$DATE-Full.tar.gz --listed-incremental=$BACKUP_PATH/$TARGET/.$DAY_WEEK-Full.meta $SOURCE_PATH/$TARGET end_time=`/bin/date +%s` result_time=$(($end_time-$start_time)) SIZE_TARGET=`du -sh $SOURCE_PATH/$TARGET | awk '{print ($1)}'` SIZE_ARCH=`du -sh $BACKUP_PATH/$TARGET/$DATE-Full.tar.gz | awk '{print ($1)}'` echo `date`" Cоздание полного архива $TARGET завершено за $result_time сек. Размер полного архива $SIZE_ARCH, размер таргета $SIZE_TARGET." >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log } diff_backup(){ echo `date`" Сегодня $DAY_NAME, делаем дифференциальный бэкап таргета $TARGET" > $BACKUP_PATH/logs/$DATE-$TARGET-backup.log start_time=`/bin/date +%s` # Перед созданием нового диффиринциального бэкапа, необходимо удалить старый не актульный бэкап. # Если дифференциальный бэкап существует. if [ -f $BACKUP_PATH/$TARGET/$OLD_DIFF_BACKUP-diff.tar.gz ] then echo `date`" Удаляем не актуальный дифференциальный бэкап $BACKUP_PATH/$TARGET/$OLD_DIFF_BACKUP-diff.tar.gz" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log rm $BACKUP_PATH/$TARGET/$OLD_DIFF_BACKUP-diff.tar.gz fi # Проверяем есть ли у нас каталог таргета if [ -d $BACKUP_PATH/$TARGET ] then echo `date`" Каталог таргета $TARGET создан" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log else echo `date`" Создаем каталог таргета $TARGET" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log mkdir $BACKUP_PATH/$TARGET fi echo `date`" Создаем дифференциальный бэкап таргета $TARGET" >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log $TAR --create --ignore-failed-read --one-file-system --preserve-permissions --recursion --sparse --totals --gzip \ --file=$BACKUP_PATH/$TARGET/$DATE-diff.tar.gz --listed-incremental=$BACKUP_PATH/$TARGET/.$FULL_BACKUP_DAY-Full.meta $SOURCE_PATH/$TARGET end_time=`/bin/date +%s` result_time=$(($end_time-$start_time)) SIZE_TARGET=`du -sh $SOURCE_PATH/$TARGET | awk '{print ($1)}'` SIZE_ARCH=`du -sh $BACKUP_PATH/$TARGET/$DATE-diff.tar.gz | awk '{print ($1)}'` echo `date`" Cоздание полного архива $TARGET завершено за $result_time сек. Размер полного архива $SIZE_ARCH, размер таргета $SIZE_TARGET." >> $BACKUP_PATH/logs/$DATE-$TARGET-backup.log } if [ $DAY_WEEK == $FULL_BACKUP_DAY ] then full_backup else diff_backup fi |
Данное решение вы используете на свой страх и риск, у скрипта есть еще достаточно не дороботок, например таких как:
- ! архив удаляется до создания нового(в случае автора, связанно с нехваткой места на файловой системе)
- ! не используется код возврата операции, возможны варианты, когда бэкап будет создан пустым или вовсе не создан
- отсутствие оповещение о созданном архиве и использованном месте(есть только в логах)
- не используется много ядерность при упаковке в архив
! — критические моменты
Скачать скрипт дифференциального бэкапа backup.sh.tar
Если ваш сервер бэкапов имеет процессор с несколькими ядрами, то лучше использоваться pigz, в том же процессе что и tar. Скорость сжатия пропорционально возрастает, так как используются все ядра.
Но я вижу вы об этом указали 🙂 Удачи в развитии скрипта! 🙂