Используемые средства
К сожалению, Windows по сравнению с *nix
-системами имеет очень слабый функционал для подготовки и копирования бэкапов. В последнее время имеется тенденция к улучшению (PowerShell), однако, полезных утилит все равно недостаточно. Обычные Windows-утилиты copy/xcopy
очень плохо работают на большом количестве файлов. В интернете можно найти «продвинутую» версию xcopy
под названием robocopy
, именно её мы и будем использовать.
Полные бэкапы
Будем размещать резервные копии на сервере srv-bak
. Копировать будем в сетевую шару \\srv-bak\bak\srv01
, где srv01
— директория с именем сервера на бэкапном. Таким образом в одной директории будут храниться бэкапы с разных серверов.
На сервере с резервными копиями для каждой из них будем создавать директорию с текущей датой в качестве имени. Для удобства поместим исходные пути, которые нужно забэкапить, в файлик D:\backup\dirs.txt
. Переносим всё это дело «на клавиатуру» и получаем такой скрипт:
set backupdir=\\srv-bak\bak\srv01 IF NOT EXIST %backupdir% ( mkdir %backupdir% ) set d=%date:~0,2% set m=%date:~3,2% set y=%date:~6,4% set ndate=%y%%m%%d% set dirsfile=D:\backup\dirs.txt set dstpath=%backupdir%\%ndate% IF NOT EXIST %dstpath% ( mkdir %dstpath% ) for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do ( mkdir "%dstpath%%%~pi%%~ni" robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /E /ZB /NP )
Чтобы всё работало автоматически, добавляем скрипт в планировщик. Таким (простым!) способом можно бэкапить достаточно большие объемы. Единственный, но существенный, наблюдаемый баг — если какой-то из копируемых файлов занят, скрипт отработает некорректно.
Инкрементные/дифференциальные бэкапы
Приведённая схема с использованием robocopy
позволяет делать и инкрементные бэкапы. Утилита имеет ключ, позволяющий копировать только файлы с определённой датой последнего изменения. Поэтому, можно модифицировать скрипт, чтобы он делал инкрементный бэкап: например копировал файлы изменившиеся за последние сутки.
set backupdir=\\srv-bak\bak\srv01 IF NOT EXIST %backupdir% ( mkdir %backupdir% ) set d=%date:~0,2% set m=%date:~3,2% set y=%date:~6,4% set ndate=%y%%m%%d% if "%d%"=="01" ( set dstpath=%backupdir%\%ndate% ) ELSE ( set dstpath=%backupdir%\d%ndate% ) IF NOT EXIST %dstpath% ( mkdir %dstpath% ) set /A prev=1%d%-100-1 if %prev% LSS 10 ( set prev=0%prev% ) set dirsfile=D:\backup\dirs.txt if "%d%"=="01" ( for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do ( :: xcopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni\" /C /E /H /Y mkdir "%dstpath%%%~pi%%~ni" robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /E /ZB /NP ) ) ELSE ( for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do ( :: xcopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni\" /D:%m%-%prev%-%y% /C /S /H /Y mkdir "%dstpath%%%~pi%%~ni" robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /MAXAGE:2 /S /ZB /NP rmdir "%dstpath%%%~pi%%~ni" ) ) IF EXIST %dstpath% ( rmdir %dstpath% )
Заключительные замечания
Вместо копирования по сети иногда бывает полезным разбиение этой задачи на 2 части: монтирование шары как локального диска и последующее копирование (и размонтирование по окончании). Приведённые скрипты несложным образом дорабатываются до такой версии.
Также, на принимающем сервере возможно организовать архивирование резервных копий. Если для сервера бэкапов используется Samba
, то в шелле это элементарно делается периодическим выполнением в директории с бэкапами архивации вроде:
find -mindepth 2 -maxdepth 2 -type d -ctime +7 -execdir /usr/local/bin/tar_and_remove.sh "{}" \;
или
find -mindepth 2 -maxdepth 2 -type d -ctime +7 -execdir rar a -t -m5 -r -rr1 -df -inul "{}.rar" "{}" \; &> /dev/null
Кроме этого, с никсового сервера эти бэкапы очень удобно копировать с помощью ssh/scp/rsync
.