Что нового

Резервное копирование базы SQL с заменой папки старше 4 дней

araneon

Новичок
Сообщения
59
Репутация
0
Уважаемые знатоки, помогите пожалуйста со скриптом, ситуация следующая.
Нужно сделать резерв базы SQL находящейся по пути
C:\Bases
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data
По сути, нужно просто скопировать две папки, но перед этим необходимо остановить SQL службу MSSQLSERVER (иначе не копируются некоторые основные файлы)
D:\Backup\Data1
D:\Backup\Data2
D:\Backup\Data3
D:\Backup\Data4
DataX -Название папки состоит из даты создания резерва
В папках DataX создать Bases и Data и копировать в них соответствующие папки, дождаться окончания копирования и запустить службу MSSQLSERVER.
Так как резерв делается каждый день и размер базы примерно 20-30 Gb, то необходимо хранить резервные копии не более 4 штук, соответственно при создании резервной копии базы нужно сделать проверку, если резерв осуществляется в день который старше Data1 на 3 дня то необходимо перезаписать папку Data1 и соответственно присвоить её имя текущей даты, и так с остальными Data2 Data3 Data4

P.S. Извеняюсь если что-то не так оформил :-[

За ранее Спасибо!
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
1. Проверка даты. Можно получить с каталога, а можно записывать/читать с ini-файла.
2. Удаление DirRemove, с обязательным циклом проверки удаления о повторной попыткой с включением снятия атрибутов "только чтение" -RST
3. Сравнение дат. Если с ini файла то можно просто здвигать данные в параметрах имён папок, а если по имени папки, то даты сравнивать _DateDiff.
4. Копирование DirCopy, папку можно создать зарание - DirCreate.
5. Остановить службу можно командой взятой из ярлыка остановки службы.
6. Проверка по дням: поместить в автозапуск и в определённое время сравнивать даты.
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
Вот что примерное получилось,

Код:
; Останавливаем службу SQL Server
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$aRet_Info = _Service_Proc("MSSQLSERVER", "stop")
$sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1])
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$Backup = "D:\Backup\"  ; Путь 1 для резервных копий

$Data = @MDAY & "-" & @MON & "-" & @YEAR ; Получаем текущую дату
$Backup_D = $Backup & $Data ; Полный путь с именем каталога на диске D

$Bases = "C:\Bases" ; Откуда берём базу навижин
$SData = @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Data" ; Путь к базам SQL

$sPath_ini=@ScriptDir & "\Backup.ini" ; Файл настроек IP сетевого хранилища
$IP = IniRead($sPath_ini, "IP", "NAS","") ; Получаем из INI IP адрес сетевого хранилища
$public = "\public\Backup\"
$IP_Put = "\\" & $IP & $public & $Data


If FileExists($IP_Put) Then
Else
	DirCreate ( $IP_Put ) ;Создаём папку с текущей датой
	DirCopy ($Bases, $IP_Put & "\Bases", 1) ;Копируем базу Навижин
	DirCopy ($SData, $IP_Put & "\Data", 1) ;Копируем базу SQL

EndIf

If FileExists($Backup_D) Then
Else
	DirCreate ( $Backup_D ) ;Создаём папку с текущей датой
	DirCopy ($Bases, $Backup_D & "\Bases", 1) ;Копируем базу Навижин
	DirCopy ($SData, $Backup_D & "\Data", 1) ;Копируем базу SQL
EndIf



; Стартуем службу SQL Server
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$aRet_Info = _Service_Proc("MSSQLSERVER", "start")
$sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1])
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Func _Service_Proc($sService, $sAction)
    Local $iPID = Run('net ' & $sAction & ' "' & $sService & '"', '', @SW_HIDE, 2 + 4)
    Local $sStdRead, $sStdErrRead, $stBuffer, $aRet, $aRet[2]

    While 1
        $sStdRead &= StdoutRead($iPID)
        If @error Then ExitLoop

        $sStdErrRead &= StderrRead($iPID)
        If @error Then ExitLoop
    WEnd

    $aRet[0] = $sStdRead
    $aRet[1] = $sStdErrRead

    For $i = 0 To 1
        $stBuffer = DllStructCreate("char[" & StringLen($aRet[$i])+1 & "]")
        $aOemToChar = DllCall("User32.dll", "int", "OemToChar", "str", $aRet[$i], "ptr", DllStructGetPtr($stBuffer))

        If Not IsArray($aOemToChar) Then ContinueLoop ;ошибка DLL
        If $aOemToChar[0] = 0 Then ContinueLoop ;ошибка функции

        $aRet[$i] = DllStructGetData($stBuffer, 1)
    Next

    Return $aRet
EndFunc


Подскажите как теперь удалять папку созданую 4 и более дней незад ?
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Пример в _DateDiff в справке содержит то как определить разницу между текущим временем и указанным. Только нужно преобразовать к нужному формату, например точку "." заменить на "\", а секунды просто дописать справа нули.
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
AZJIO ОГРОМНОЕ тебе спасибо за помощь !!!

Ситуация немного изменилась, теперь из-за недостатка свободного места на диске требуется добавить ко всему прочему и архивацию созданых резервных копий.
Отсюда задаюсь вопросом как сюда ещё и архивацию замастырить? :stars:
Предпологаю что нужно сделать проверку не папок а архивов.
То есть после того как сервис запустится, произвести проверку архивов, если есть архив старше вновь созданного на 4-5 дней, то его удалить (старый). А в новь созданую папку удалять после архивации.
Вот только как ? :shok:? Уже бошка кругом :'(
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
araneon
У меня времени мало, поэтому готовое некогда делать.
Например RunWait содержит в справке пример
Код:
; Сжатие файла "Boot.ini" в архив "Archive.7z" с паролем "Мой пароль"
RunWait(@ProgramFilesDir & '\7-Zip\7z.exe a "' & @HomeDrive & '\Archive.7z" -p"Мой пароль" -mhe -mx9 "' & @HomeDrive & '\Boot.ini"', '', @SW_HIDE)
Особенностью функции RunWait ожидать завершение процесса (в данном случае архивации) и возврата кода ошибки, по которому оценивать успешно ли выполнена архивация.
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
AZJIO

СПАСИБО завтра попробую!


Добавлено:
Сообщение автоматически объединено:

Рушил попробовать Zip.au3
Только не пойму возможно ли тут степень сжатия менять?

Код:
#include "Zip.au3"
$Data = @MDAY & "-" & @MON & "-" & @YEAR
$Backup = "D:\Backup\"
$Zip_Data = $Data & ".zip"
$Zip = _Zip_Create($Backup & $Zip_Data)
_Zip_AddFolder($Zip, $Backup_D)
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
araneon [?]
произвести проверку архивов, если есть архив старше вновь созданного на 4-5 дней, то его удалить (старый)
Код:
#include <Date.au3>

$Data = @MDAY & "-" & @MON & "-" & @YEAR
$Backup = "D:\Backup\"

$Search = FileFindFirstFile($Backup & "*.zip")
If $Search = -1 Then
  MsgBox(0, "Ошибка", "Файлы не найдены")
Else
  Dim $ar[4]
  While 1
    $File = FileFindNextFile($Search)
    If @error Then ExitLoop
    $ar = StringSplit(StringTrimRight($File, 4), "-")
    $str = $ar[3] & "/" & $ar[2] & "/" & $ar[1]
    If _DateDiff("D", $str, @YEAR & "/" & @MON & "/" & @MDAY) > 4 Then FileDelete($Backup & $File)
  WEnd
  FileClose($Search)
EndIf
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
InnI Спасибо, но чет у меня небольшая печалька возникает :(

Код:
C:\Users\ass\Desktop\SQL\data test.au3 (15) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$str = $ar[3] & "/" & $ar[2] & "/" & $ar[1]
$str = ^ ERROR
->10:12:36 AutoIT3.exe ended.rc:1
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
araneon [?]
небольшая печалька
Проверьте имена файлов архивов. Они должны быть следующего формата:
Код:
@MDAY & "-" & @MON & "-" & @YEAR & ".zip"
Например, 25-02-2013.zip
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
Странно, при выполнении скрипта архив удаляется :ok: а в логе с нова

Код:
C:\Users\ass\Desktop\SQL\data test.au3 (15) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$str = $ar[3] & "/" & $ar[2] & "/" & $ar[1]
$str = ^ ERROR
->08:03:11 AutoIT3.exe ended.rc:1

:scratch:
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
araneon [?]
Вероятно у вас там есть и другие zip-файлы, имена которых не соответствуют выбранному вами шаблону. Попробуйте так
Код:
$Search = FileFindFirstFile($Backup & "??-??-????.zip")
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
InnI Огромное спасибо

Код:
#include <Date.au3>

$Data = @MDAY & "-" & @MON & "-" & @YEAR
$Backup = "D:\Backup\"

$Search = FileFindFirstFile($Backup & "*.zip")
If $Search = -1 Then
  MsgBox(0, "Ошибка", "Файлы не найдены")
Else
  Dim $ar[4]
  While 1
    $File = FileFindNextFile($Search)
    If @error Then ExitLoop
    $ar = StringSplit(StringTrimRight($File, 4), "-")
    $str = $ar[3] & "/" & $ar[2] & "/" & $ar[1]
    If _DateDiff("D", $str, @YEAR & "/" & @MON & "/" & @MDAY) > 4 Then FileDelete($Backup & $File)
  WEnd
  FileClose($Search)
EndIf


Вот этот вариант всё же лучше, всё просто замечательно работает :ok: :beer: :IL_AutoIt_1:
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
InnI подскажи а как удалять папки с такими же именами как и у архивов.
То есть, скрипт удаляет архивы старше 4 дней, а так же что бы и папки соответствующие удаляемым архивам удалял.
:scratch:
Я не много не пойму, вроде убрал *.zip типа
Код:
$Search = FileFindFirstFile($Backup & "*.*")
, а он всё равно при поиске в каталоге выдаёт только zip архивы, а папки пропускает.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
araneon [?]
удалять папки с такими же именами как и у архивов
Код:
If _DateDiff("D", $str, @YEAR & "/" & @MON & "/" & @MDAY) > 4 Then
      FileDelete($Backup & $File)
      DirRemove($Backup & StringTrimRight($File, 4), 1)
    EndIf
 
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
Фух, на конец то ки добрался до писанины.
Вроде доделал скриптик, только чёт он перестал удалять файлы и папки, но это думаю можно будет поправить, сейчас прошу знающих людей взглянуть на код и подсказать что и как можно изменить в лучшую сторону

Код:
Opt("TrayIconDebug",1)

#include <Date.au3>
#include "Zip.au3"

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;		Указываем переменные для дальнейшей работы
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	$Base = "C:\Base" ; Откуда берём базу Навижин
	$Bases = "C:\Bases" ; Откуда берём базу Навижин
	$SqlData = @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Data" ; Путь к базам SQL
	$Data = @MDAY & "-" & @MON & "-" & @YEAR ; Получаем текущую дату

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 		Останавливаем службу SQL Server
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$aRet_Info = _Service_Proc("MSSQLSERVER", "start")
If ProcessExists("sqlservr.exe") Then
Else
	Run("sqlservr.exe", @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\")
EndIf

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 		Получаем пути  из ini файла для копирования и копируем
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if FileExists (@ScriptDir & "\Backup.ini") Then  ; Проверка на наличие данного файла, если нет то проходим мимо
	$sPath_ini=@ScriptDir & "\Backup.ini" ; Файл настроек IP сетевого хранилища
	$A = IniRead($sPath_ini, "A", "Patch","") ; Путь на диск D в папку Backup (D:\Backup)
	$B = IniRead($sPath_ini, "B", "Patch","") ; Путь на диск L
	$IP = IniRead($sPath_ini, "IP", "Patch","") ; Получаем из INI IP адрес и путь к папке сетевого хранилища

	DirCopy ($Base, $A &  "\" & $Data & "\Base", 1) ;Копируем базу Навижин в $A
	DirCopy ($Bases, $A &  "\" & $Data & "\Bases", 1) ;Копируем базу Навижин в $A
	DirCopy ($SqlData, $A &  "\" & $Data & "\Data", 1) ;Копируем базу SQL в $A

	DirCopy ($Base, $B & "\" & $Data & "\Base", 1) ;Копируем базу Навижин в $B
	DirCopy ($Bases, $B & "\" & $Data & "\Bases", 1) ;Копируем базу Навижин в $B
	DirCopy ($SqlData, $B & "\" & $Data & "\Data", 1) ;Копируем базу SQL в $B

	DirCopy ($Base, $IP & "\" & $Data & "\Base", 1) ;Копируем базу Навижин в $IP
	DirCopy ($Bases, $IP & "\" & $Data & "\Bases", 1) ;Копируем базу Навижин в $IP
	DirCopy ($SqlData, $IP & "\" &  $Data & "\Data", 1) ;Копируем базу SQL в $IP

Else
	$Backup = "D:\Backup\"  ; Путь 1 для резервных копий
	$Backup_D = $Backup & $Data ; Полный путь с именем каталога на диске D

	DirCopy ($Base, $Backup & $Data & "\Base", 1) ;Копируем базу Навижин
	DirCopy ($Bases, $Backup & $Data & "\Bases", 1) ;Копируем базу Навижин
	DirCopy ($SqlData, $Backup & $Data & "\Data", 1) ;Копируем базу SQL

EndIf

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 		Стартуем службу SQL Server
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$aRet_Info = _Service_Proc("AmmyyAdmin", "start")
If ProcessExists("AA_v3.exe") Then
Else
	Run("sqlservr.exe", @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\")
EndIf

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  		Функции для старта и остановки службы
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Func _Service_Proc($sService, $sAction)
    Local $iPID = Run('net ' & $sAction & ' "' & $sService & '"', '', @SW_HIDE, 2 + 4)
    Local $sStdRead, $sStdErrRead, $stBuffer, $aRet, $aRet[2]

    While 1
        $sStdRead &= StdoutRead($iPID)
        If @error Then ExitLoop

        $sStdErrRead &= StderrRead($iPID)
        If @error Then ExitLoop
    WEnd

    $aRet[0] = $sStdRead
    $aRet[1] = $sStdErrRead

    For $i = 0 To 1
        $stBuffer = DllStructCreate("char[" & StringLen($aRet[$i])+1 & "]")
        $aOemToChar = DllCall("User32.dll", "int", "OemToChar", "str", $aRet[$i], "ptr", DllStructGetPtr($stBuffer))

        If Not IsArray($aOemToChar) Then ContinueLoop ;ошибка DLL
        If $aOemToChar[0] = 0 Then ContinueLoop ;ошибка функции

        $aRet[$i] = DllStructGetData($stBuffer, 1)
    Next

    Return $aRet
EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 		Создаём архив того что скопировали
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$Zip_Data = $Data & ".zip"

if FileExists (@ScriptDir & "\Backup.ini") Then

If FileExists($A & $Zip_Data) Then
Else
    $Zip = _Zip_Create($A & $Zip_Data)
    _Zip_AddFolder($Zip, $A  & $Data )
EndIf

Else
$Zip = _Zip_Create($Backup & $Zip_Data)
_Zip_AddFolder($Zip, $Backup_D)
EndIf


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  		Удаление старых папок и архивов
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$Search = FileFindFirstFile($A & "*.*")
If $Search = -1 Then
  MsgBox(0, "Ошибка", "Файлы не найдены")
Else
  Dim $ar[4]
  While 1
    $File = FileFindNextFile($Search)
    If @error Then ExitLoop
    $ar = StringSplit(StringTrimRight($File, 4), "-")
    $str = $ar[3] & "/" & $ar[2] & "/" & $ar[1]
    If _DateDiff("D", $str, @YEAR & "/" & @MON & "/" & @MDAY) > 4 Then
	FileDelete($A & $File)
	DirRemove($A & StringTrimRight($File, 3), 1)
  EndIf
  WEnd
  FileClose($Search)
EndIf


или ошибки какте есть тут.
СПАСИБО !!!
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
araneon [?]
или ошибки какие есть тут
Строка 16: Останавливаем службу SQL Server. А ниже идёт код запуска службы.
Строка 58: Стартуем службу SQL Server. А ниже идёт запуск AmmyyAdmin.
Строка 123:
Код:
$Search = FileFindFirstFile($A & "*.*")
Во-первых, убедитесь, что путь $A содержит "\" в конце.
Во-вторых, с маской "*.*" (любые файлы) возможны проблемы. Лучше используйте маску "??-??-????.zip".
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Это
Код:
If ProcessExists("AA_v3.exe") Then
Else
    Run("sqlservr.exe", @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\")
EndIf

Пишется так
Код:
If Not ProcessExists("AA_v3.exe") Then Run("sqlservr.exe", @ProgramFilesDir & "\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\")


Зачем использовать FileFindFirstFile, если есть готовая функция _FileListToArray.

Массив не обязательно инициализировать
Код:
Dim $ar[4]

Он сам инициализируется функцией StringSplit. Dim не рекомендуется использовать, вместо него Local или Global.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Автор
A

araneon

Новичок
Сообщения
59
Репутация
0
Огромное спасибо за указанные моменты, да со стартом службы немного в запарке напутал, спасибо
А вот на счёт _FileListToArray как то не до понял :( :-[ :stars:
 
Верх