Скрипт бэкапа каталогов на SH

📅 12 Июл 2016 12:11 | 👁 52 | 🕐 3 мин.

Простой скрипт дифференциального бэкапа каталогов при помощи TAR.

Скрипт работает следующим образом, каждый день создается дифференциальный бэкап, в случае если бэкапов не было еще сделано, то первый созданный бэкап будет полным, последующие дифференциальными .

При этом раз в неделю создается полный бэкап каталога. После создания полного бэкапа дифференциальные бэкапы начинают перезаписываться.

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

Запускать можно как в ручном режиме, так и добавив задание в расписание по cron.

Например вот так:

> /backup/arch/backup.sh myfolder
> crontab -l
* 6 * * *       /backup/arch/backup.sh /myfolder

Таким образом каждый день в 6 утра будет создоваться бэкап каталога myfolder.

#!/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

Поделиться

One Response to“Скрипт бэкапа каталогов на SH”

  1. AdamS
    13/07/2016 at 08:25 #

    Если ваш сервер бэкапов имеет процессор с несколькими ядрами, то лучше использоваться pigz, в том же процессе что и tar. Скорость сжатия пропорционально возрастает, так как используются все ядра.

    Но я вижу вы об этом указали 🙂 Удачи в развитии скрипта! 🙂

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

(Required)