Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Копирование резервных копий (http://forum.oszone.net/showthread.php?t=337060)

Linzer 08-10-2018 10:57 2834914

Копирование резервных копий
 
Здравствуйте!
Вопрос в следующем: на сервере делается ежедневный бэкап комплекта баз (с раширением 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 Соответственно все действия пишем в лог файл.

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

megaloman 08-10-2018 16:20 2834965

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:25 2836158

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


Linzer 22-10-2018 12:29 2836965

Цитата:

Цитата 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"

megaloman 22-10-2018 12:38 2836967

Цитата:

Цитата Linzer
Архивы делаются, но почему то архив за месяц (за этот) делается с именем Base1.bak_201809.Rar. »

Цитата:

Цитата Linzer
Месячные комплекты (будут копироваться 1 числа каждого месяца, т.к. копирование в последний день месяца заморочено »

Вы собрались делать архивы каждый день. Первого числа Вы получите практически архив базы прошлого месяца. Если первого числа скрипт не работал, то при запуске в другой день скрипт возьмет имеющийся бэкап и обзовёт его бэкапом прошлого месяца. ИМХО, это логично.
Можно указать, конечно, кол-во бэкапов для каждой папки. Доработаю. Выложу.

Linzer 22-10-2018 14:45 2836978

Цитата:

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

Лучше пускай обзывает месячный бэкап как есть (в данном случае Base1.bak_201810.Rar).

Цитата:

Цитата megaloman
Можно указать, конечно, кол-во бэкапов для каждой папки. Доработаю. Выложу. »

Зачем кол-во? Дневной каждый день перезаписывается, недельный - в определенное время (настраиваемое), месячный - раз в месяц.
Спасибо за ответы!

megaloman 22-10-2018 16:36 2836988

Ваши пожелания, включая те, от которых Вы отказались
Код:

@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
Дневной каждый день перезаписывается, недельный - в определенное время (настраиваемое), месячный - раз в месяц »

Вы должны просто запланировать исполнение скрипта. Всё остальное сделает скрипт.


Время: 13:41.

Время: 13:41.
© OSzone.net 2001-