Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Копирование резервных копий

Ответить
Настройки темы
CMD/BAT - [решено] Копирование резервных копий

Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


Здравствуйте!
Вопрос в следующем: на сервере делается ежедневный бэкап комплекта баз (с раширением bak), хочу сделать на другом сервере (с подключенным хранилищем) задание на копирование этого комплекта по расписанию.
Месячные комплекты (будут копироваться 1 числа каждого месяца, т.к. копирование в последний день месяца заморочено (для меня) - из-за разного кол-ва дней в месяце) будут копироваться в Y:\Backup\Month (будут архивироваться винраром в файл с именем даты копии; можно копировать из папки ежедневного бэкапа, с проверкой на актуальность);
недельные, по воскресеньям (можно копировать из папки ежедневного бэкапа (если он был, если нет - то с сервера \\192.168.1.1\Backup)) в папку Y:\Backup\Week и каждую неделю будут перезаписываться (архивировать не надо);
и ежедневные в папку Y:\Backup\Day (тоже будут перезаписываться каждый день, без архивирования).
Так же хотелось бы сделать проверку - вдруг сервак 1 числа будет выключен, значит ни ежедневный бэкап, ни месячный не скопируются. Т.е. по идее скрипт должен запускаться каждый день и проверять был ли месячный бэкап в этом месяце, если нет - копировать самый последний (и что бы не проверять когда был дневной бэкап (может он тоже старый) копировать сразу с другого сервера (например \\192.168.1.1\Backup, или все таки проверить на актуальность дневной и копировать из папки Day, сразу через винрар). По этому же принципу проверять и еженедельный бэкап (может через разницу дат? например если разница больше 6 дней - копировать из папки Day (если там актуальный) либо с другого сервера (\\192.168.1.1\Backup) - если не актуальный бэкап.
Имена файлов бэкапов всегда одинаковые, с расширением bak.
Бэкап каждой БД делается в отдельный файл.
Бэкап делается каждый день с перезаписью (\\192.168.1.1\Backup).
Как в целом я себе это представляю (если делать скрипт для всех задач в одном батнике):

rem Устанавливаем переменные
@Echo off
set year=%date:~-4,4%
set month=%date:~-8,4%
set day=%date:~-10,2%
set datetemp=%year%%month%%day%
Set Files=y:\Backup\Day\*.*
Set BackUp=y:\Backup\Month\
set Msg=Nothing to do
set Chk=%datetemp:~0,7%

rem Копируем бэкап за день

rem Проверяем как давно делался недельный бэкап, если больше 6 дней, то копируем либо из папки Day (если актуальный бэкап) либо с сервера (\\192.168.1.1\Backup).

rem Проверяем делался ли месячный бэкап - если нет архива за этот месяц, то делаем архивный бэкап.

rem Соответственно все действия пишем в лог файл.

Заранее благодарю за помощь!

Отправлено: 10:57, 08-10-2018

 

Ветеран


Contributor


Сообщения: 2723
Благодарности: 1693

Профиль | Отправить PM | Цитировать


Linzer,
Вот вариант. Постановку слегка изменил в части недельных копий
Код: Выделить весь код
@Echo Off                                                                                                 
cls
Set "Arc=C:\Program Files\WinRAR\WinRar.exe"
Set "ArcExt=Rar" 

FOR /F "tokens=2 delims==." %%d in ('WMIC OS GET LOCALDATETIME /VALUE') DO SET "tNow=%%d"
Set /A tNow=%tNow:~0,8%

rem ---------
Call :BakCopy "Z:\192.168.1.1_Backup\Base1.bak" "Z:\Backup\Day"  "Z:\Backup\Week" "Z:\Backup\Month" 3 "Z:\Backup\Log\%tNow%.log"
Call :BakCopy "Z:\192.168.1.1_Backup\Base2.bak" "Z:\Backup\Day"  "Z:\Backup\Week" "Z:\Backup\Month" 3 "Z:\Backup\Log\%tNow%.log"
Call :BakCopy "Z:\192.168.1.1_Backup\Base3.bak" "Z:\Backup\Day"  "Z:\Backup\Week" "Z:\Backup\Month" 3 "Z:\Backup\Log\%tNow%.log"
rem ---------

pause
GoTo :Eof

:BakCopy
        Call :MdOut %2 %6 ||Exit /B 3 
        Call :MdOut %3 %6 ||Exit /B 3 
        Call :MdOut %4 %6 ||Exit /B 3
        Call :MdOut "%~dp6" %6 ||Exit /B 3
 
	Set "Fin=%~1"
	Set "Fin=%Fin:\=\\%"
	
	Set "Df=absent"
	For /f "tokens=1* delims=," %%a in ('2^>nul wmic datafile where "name='%Fin%'" get 'Last Modified' /format:csv') Do (
		If /I "%%a"=="%ComputerName%" Set "Df=%%b"
	)
	Set "Df=%Df:~0,8%"

	If Not "%tNow%"=="%Df%" Set Msg=!!! %Date% %Time% %1 no today backup. Last backup %Df%
	If Not "%tNow%"=="%Df%" (Echo %Msg% &>>%6 Echo %Msg% &Exit /B 2)
	
	If Exist "%~2\%~nx1" Move /Y "%~2\%~nx1" "%~2\~%~nx1" >nul
	Copy %1 "%~2\" >nul
	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 copied %2
		Del "%~2\~%~nx1" 2>nul
	) Else (
		Set Msg=!!! %Date% %Time% %1 not copied %2
		If Exist "%~2\~%~nx1" Move /Y "%~2\~%~nx1" "%~2\%~nx1" >nul
	)
	Echo %Msg% &>>%6 Echo %Msg%
	If Not %Err%==0 Exit /B %Err%
	
	If %tNow:~4,2%==01 (Set /A Month=%tNow:~0,6%-89) Else (Set /A Month=%tNow:~0,6%-1)
	
	If Exist "%~4\%~nx1_%Month%.%ArcExt%" GoTo :ArcWeek

	"%Arc%" a -m2 -ep "%~4\%~nx1_%Month%.%ArcExt%" "%~2\%~nx1"
	
	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 created "%~4\%~nx1_%Month%.%ArcExt%"
	) Else (
		Set Msg=!!! %Date% %Time% %1 !!! NOT created !!! "%~4\%~nx1_%Month%.%ArcExt%"
	)
	Echo %Msg% &>>%6 Echo %Msg% &Exit /B %Err%

	:ArcWeek
	"%Arc%" a -m1 -ep "%~3\%~nx1_%tNow%.%ArcExt%" "%~2\%~nx1"

	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 created "%~3\%~nx1_%tNow%.%ArcExt%"
	) Else (
		Set Msg=!!! %Date% %Time% %1 !!! NOT created !!! "%~3\%~nx1_%tNow%.%ArcExt%"
	)
	Echo %Msg% &>>%6 Echo %Msg%

	FOR /F "usebackq skip=%~5 delims=" %%f IN (`2^>nul Dir /B /O:-D /T:W "%~3\%~nx1_*.%ArcExt%"`) DO (
		Del "%~3\%%f" &&(Echo --- %Date% %Time% "%~3\%%f" deleted &>>%6 Echo --- %Date% %Time% "%~3\%%f" deleted)
	)
	Exit /B %Err%
GoTo :Eof

:MdOut
	If Exist %1 Exit /B 0
	Md %1 &&Exit /B 0
	Set Msg=!!! %Date% %Time% Не удалось создать папку %1  
	Echo %Msg% &>>%2 Echo %Msg%
Exit /B 3
Ежедневно делается копия бэкапа. Имя бэкапа всегда одинаково.
Если сегодняшней копии нет, ничего не делаем.
Если нет копии прошлого месяца (делаем, в идеале, в первом числе текущего месяца) архивируем сегодняшний бэкап в папку месяца.
Если копия прошлого месяца есть, архивируем сегодняшний бэкап в недельную папку. В этой папке храним не более заданного числа архивов бэкапов каждой базы. В моём примере это 3 дня (можете исправлять как нужно). Подозреваю, больше и не нужно.
Для архивирования выбирал уровень компрессии -m1 для ежедневной копии в папке Week. Работает очень быстро и бэкапы баз жмет неплохо. Для месячной копии можно выбрать более высокий уровень компрессии (у меня здесь -m2)
Вообще-то уровень компрессии стОит выбирать из соображений временнЫх затрат в зависимости от объема бэкапов.
Ведется лог процесса.
Пропишите свои пути к архиватору, файлам и папкам.
В выделенном фрагменте перечисляются нужные базы. В чём удобство - можно для каждой базы прописать свои пути.
Если хотите, можете не перечислять все базы в выделенном фрагменте кода, его можно заменить на
Код: Выделить весь код
rem ---------
FOR %%i IN ("Z:\192.168.1.1_Backup\*.bak") DO Call :BakCopy "%%~i" "Z:\Backup\Day"  "Z:\Backup\Week" "Z:\Backup\Month" 3 "Z:\Backup\Log\%tNow%.log"
rem ---------

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 16-10-2018 в 17:23.

Это сообщение посчитали полезным следующие участники:

Отправлено: 16:20, 08-10-2018 | #2



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

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Contributor


Сообщения: 2723
Благодарности: 1693

Профиль | Отправить PM | Цитировать


Linzer, При указания сетевого пути WMIC не определяет дату файла. Замените зачеркнутый кусок на
Код: Выделить весь код
        Call :MdOut "%~dp6" %6 ||Exit /B 3
        Call :MdOut %2 %6 ||Exit /B 3 
        Call :MdOut %3 %6 ||Exit /B 3 
        Call :MdOut %4 %6 ||Exit /B 3
 
	Pushd "%~dp1"
	FOR /F "delims=" %%d IN ('CD') DO Set "Fin=%%d"
	If Not "%Fin:~-1%" =="\" Set "Fin=%Fin%\"

	Set "Df=absent"
	For /f "tokens=1* delims=," %%a in ('2^>nul wmic datafile where "name='%Fin:\=\\%%~nx1'" get 'Last Modified' /format:csv') Do (
		If /I "%%a"=="%ComputerName%" Set "Df=%%b"
	)
	Popd

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 16-10-2018 в 18:07.


Отправлено: 17:25, 16-10-2018 | #3


Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата megaloman:
При указания сетевого пути WMIC не определяет дату файла. Замените зачеркнутый кусок на »
Скрипт начал работать!
Архивы делаются, но почему то архив за месяц (за этот) делается с именем Base1.bak_201809.Rar.
И еще вопрос - если использовать копирование сразу всех баз:
rem ---------
FOR %%i IN ("Z:\192.168.1.1_Backup\*.bak") DO Call :BakCopy "%%~i" "Z:\Backup\Day" "Z:\Backup\Week" "Z:\Backup\Month" 3 "Z:\Backup\Log\%tNow%.log"
rem ---------
Можно ли указать кол-во дней хранения для каждой папки? Может так:
FOR %%i IN ("Z:\192.168.1.1_Backup\*.bak") DO Call :BakCopy "%%~i" "Z:\Backup\Day" 1 "Z:\Backup\Week" 5 "Z:\Backup\Month" 30 "Z:\Backup\Log\%tNow%.log"

Отправлено: 12:29, 22-10-2018 | #4


Ветеран


Contributor


Сообщения: 2723
Благодарности: 1693

Профиль | Отправить PM | Цитировать


Цитата Linzer:
Архивы делаются, но почему то архив за месяц (за этот) делается с именем Base1.bak_201809.Rar. »
Цитата Linzer:
Месячные комплекты (будут копироваться 1 числа каждого месяца, т.к. копирование в последний день месяца заморочено »
Вы собрались делать архивы каждый день. Первого числа Вы получите практически архив базы прошлого месяца. Если первого числа скрипт не работал, то при запуске в другой день скрипт возьмет имеющийся бэкап и обзовёт его бэкапом прошлого месяца. ИМХО, это логично.
Можно указать, конечно, кол-во бэкапов для каждой папки. Доработаю. Выложу.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Отправлено: 12:38, 22-10-2018 | #5


Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата megaloman:
Вы собрались делать архивы каждый день. Первого числа Вы получите практически архив базы прошлого месяца. Если первого числа скрипт не работал, то при запуске в другой день скрипт возьмет имеющийся бэкап и обзовёт его бэкапом прошлого месяца. ИМХО, это логично.
»
Лучше пускай обзывает месячный бэкап как есть (в данном случае Base1.bak_201810.Rar).

Цитата megaloman:
Можно указать, конечно, кол-во бэкапов для каждой папки. Доработаю. Выложу. »
Зачем кол-во? Дневной каждый день перезаписывается, недельный - в определенное время (настраиваемое), месячный - раз в месяц.
Спасибо за ответы!

Отправлено: 14:45, 22-10-2018 | #6


Ветеран


Contributor


Сообщения: 2723
Благодарности: 1693

Профиль | Отправить PM | Цитировать


Ваши пожелания, включая те, от которых Вы отказались
Код: Выделить весь код
@Echo Off                                                                                                 
cls
Set "Arc=C:\Program Files\WinRAR\WinRar.exe"
Set "ArcExt=Rar" 

FOR /F "tokens=2 delims==." %%d in ('WMIC OS GET LOCALDATETIME /VALUE') DO SET "tNow=%%d"
Set /A tNow=%tNow:~0,8%

rem ---------
	FOR %%i IN ("\\192.168.100.4\Test1\*.bak") DO Call :BakCopy "%%~i" "Z:\Backup\Day"  "Z:\Backup\Week" 7 "Z:\Backup\Month" 1 "Z:\Backup\Log\%tNow%.log" 35
rem ---------

pause
GoTo :Eof

:BakCopy
        Call :MdOut "%~dp7" %7 ||Exit /B 3
        Call :MdOut %2 %7 ||Exit /B 3 
        Call :MdOut %3 %7 ||Exit /B 3 
        Call :MdOut %5 %7 ||Exit /B 3
 
	Pushd "%~dp1"
	FOR /F "delims=" %%d IN ('CD') DO Set "Fin=%%d"
	If Not "%Fin:~-1%" =="\" Set "Fin=%Fin%\"

	Set "Df=absent"
	For /f "tokens=1* delims=," %%a in ('2^>nul wmic datafile where "name='%Fin:\=\\%%~nx1'" get 'Last Modified' /format:csv') Do (
		If /I "%%a"=="%ComputerName%" Set "Df=%%b"
	)
	Popd

	Set "Df=%Df:~0,8%"

	If Not "%tNow%"=="%Df%" Set Msg=!!! %Date% %Time% %1 no today backup. Last backup %Df%
	If Not "%tNow%"=="%Df%" (Echo %Msg% &>>%7 Echo %Msg% &Exit /B 2)

rem Копия ежедневного бэкапа	
	If Exist "%~2\%~nx1" Move /Y "%~2\%~nx1" "%~2\~%~nx1" >nul
	Copy %1 "%~2\" >nul
	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 copied %2
		Del "%~2\~%~nx1" 2>nul
	) Else (
		Set Msg=!!! %Date% %Time% %1 not copied %2
		If Exist "%~2\~%~nx1" Move /Y "%~2\~%~nx1" "%~2\%~nx1" >nul
	)
	Echo %Msg% &>>%7 Echo %Msg%
	If Not %Err%==0 Exit /B %Err%
	
rem	If %tNow:~4,2%==01 (Set /A Month=%tNow:~0,6%-89) Else (Set /A Month=%tNow:~0,6%-1)
	Set /A Month=%tNow:~0,6%
	
	If Exist "%~5\%~nx1_%Month%.%ArcExt%" GoTo :ArcWeek

rem Архив месячного бэкапа	
	"%Arc%" a -m2 -ep "%~5\%~nx1_%Month%.%ArcExt%" "%~2\%~nx1"
	Call :NDel "%~5\%~nx1_*.%ArcExt%" %~6 "%~7" 
	
	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 created "%~5\%~nx1_%Month%.%ArcExt%"
	) Else (
		Set Msg=!!! %Date% %Time% %1 !!! NOT created !!! "%~5\%~nx1_%Month%.%ArcExt%"
	)
	Echo %Msg% &>>%7 Echo %Msg% &Exit /B %Err%

rem Архив бэкапов за неделю	
	:ArcWeek
	"%Arc%" a -m1 -ep "%~3\%~nx1_%tNow%.%ArcExt%" "%~2\%~nx1"

	Set "Err=%ErrorLevel%"
	If %Err%==0 (
		Set Msg=+++ %Date% %Time% %1 created "%~3\%~nx1_%tNow%.%ArcExt%"
	) Else (
		Set Msg=!!! %Date% %Time% %1 !!! NOT created !!! "%~3\%~nx1_%tNow%.%ArcExt%"
	)
	Echo %Msg% &>>%7 Echo %Msg%

	Call :NDel "%~3\%~nx1_*.%ArcExt%" %~4 "%~7" 
	Call :NDel "%~dp7*%~x7" %~8 "%~7" 

	Exit /B %Err%
GoTo :Eof

:MdOut
	If Exist %1 Exit /B 0
	Md %1 &&Exit /B 0
	Set Msg=!!! %Date% %Time% Не удалось создать папку %1  
	Echo %Msg% &>>%2 Echo %Msg%
Exit /B 3

:NDel
	FOR /F "usebackq skip=%~2 delims=" %%f IN (`2^>nul Dir /B /O:-D /T:W "%~1"`) DO (
		Del "%~dp1%%f" &&(Echo --- %Date% %Time% "%~dp1%%f" deleted &>>%3 Echo --- %Date% %Time% "%~dp1%%f" deleted)
	)
GoTo :Eof
Для бэкапов за неделю в папке "Z:\Backup\Week" 7 бэкапов
Для бэкапов за месяц в папке "Z:\Backup\Month" 1 бэкап
Число лог файлов "Z:\Backup\Log\%tNow%.log" 35 штук

Числа можете выставить свои.
Имя месячного бэкапа (выделил красным) сделал как Вы хотите. Но это нелогично.
Цитата Linzer:
Дневной каждый день перезаписывается, недельный - в определенное время (настраиваемое), месячный - раз в месяц »
Вы должны просто запланировать исполнение скрипта. Всё остальное сделает скрипт.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Отправлено: 16:36, 22-10-2018 | #7



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Копирование резервных копий

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2012 R2 - Wbadmin и загадочное удаление резервных копий kudrik_tt Windows Server 2012/2012 R2 9 24-08-2018 06:14
CMD/BAT - [решено] Несколько резервных копий файла с датами в названии Sisin Скриптовые языки администрирования Windows 2 03-08-2017 17:40
CMD/BAT - bat файл, удаление старых резервных копий share Скриптовые языки администрирования Windows 2 23-06-2016 23:00
V. 2010 - Создание резервных копий Exchange после развертывания DAG. Alexchandr Microsoft Exchange Server 7 03-03-2015 14:51
CMD/BAT - копирование по SHH (psftp) резервных копий enkil@vk Скриптовые языки администрирования Windows 1 05-05-2012 16:56




 
Переход