Чужой опыт экономит время и увеличивает шансы для удачи

Ротация файлов бэкапа

На первый взгляд, ротация бэкапов - задача не сложная.

Казалось бы, что может быть проще - сохранять строго определенное количество папок или архивов с бэкапом, именуя их с использованием даты.

На самом деле не все так просто. Первый вопрос, который возникает сразу - что произойдет если какие-то важные рабочие файлы какое-то продолжительное время не будут изменяться? Будет происходить "холостой" бэкап, а последующая ротация бэкапов через некоторое время приведет к тому, что все эти файлы в старых версиях бэкапов будут одинаковы.

Поэтому для разумного бэкапа лучше все-таки делать анализ резервируемых данных.

И одного простого скрипта, одинакового для всех, здесь может быть недостаточно.


Содержание

  1. Анализ резервируемых данных
  2. Пример разделения файлов на группы
  3. Скрипты ротации - bat и vbs

Анализ резервируемых данных

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

Кроме того нужно определить - получится ли разбить файлы на группы исходя из того чаще или реже они изменяются. И насколько это сложно реализуемо (разделены ли она по разным папкам и т.д.).
Лучше всего конечно было бы, если бы такие файлы находились в разных исходных папках. Если четкого разделения по папкам нет, то необходимо определить - насколько сложно выделить такие файлы по другим признакам - имени, дате или т.п.

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

Пример разделения файлов на группы

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

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

В этом случае, для фотографий может быть определена отдельная папка бэкапа, в которой достаточно хранить копию последней версии фото и "уходящие в прошлое" папки только с фотографиями которые например были удалены (т.е. не дублировать всю папку, а оставлять копии только тех файлов которые были удалены или изменены). См. здесь описание системы, которая позволяет делать избирательный отбор, сохраняя только удаленные и изменяемые файлы.

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

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

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

Итак:

  • В бэкап-папках со старыми версиями фотографий (файлов большого размера) будут сохраняться только отдельные файлы, копируемые туда только после анализа изменений.
  • Папки с бэкапами "непрогнозируемой кучи" будут скорее всего хранить общую копию для всех файлов сразу, и скорее всего цепочка бэкапов будет создаваться каждый день на заданный период в прошлое.
  • Для редко изменяемых файлов у которых известны заранее имена, папки с их старыми версиями могут иметь большие промежутки времени между собой.

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

КСТАТИ! Про избирательный бэкап с дополнительным резервированием только измененных и удаленных от предыдущей версии бэкапа, см. отдельную заметку: Бэкап с сохранением старых версий файлов и папок

Скрипты ротации - bat и vbs

Скрипты ротации здесь приведены для примера, их можно доработать под себя в соответствии со своими задачами.
В примере второго скрипта (на vbs) есть одна папка которая может быть исключена из ротации. При желании можно доработать скрипт так чтобы таких исключенных из ротации папок было несколько.

Так же приведен пример скрипта ротации логов, который анализирует файлы по именам.

Скрипт bat, удаляющий все старые архивы по времени их изменения

Скрипт ротации анализирует время файлов архивов, оставляя только 10 самых "свежих" (независимо от имени файла):

rotation_all_files_date.bat

@echo off
 
setlocal enableextensions enabledelayedexpansion
 
set bPath=C:\Backup_rar_files
set /a iCount = 10
 
for /f "skip=%iCount% usebackq delims=" %%i in (
	`dir /b /a:-d /o:-d /t:w "%bPath%"`
) do del /f /q "%bPath%\%%~i" 
 
endlocal
exit /b 0

Скрипт vbs, удаляющий старые папки за исключением указанной

Скрипт ротации анализирует время папок, присутствующее в их именах, оставляя только последние 30, но игнорирует при этом всегда одну указанную папку.

Запускать так (в консоли):
cscript //NoLogo "C:\_ПУТЬ_\rotation_folders_name.vbs" /path:"D:\Backup" /exclude:"D:\Backup\NoDelFolder" /max:30 /testmode

ВАЖНО! Параметр /testmode для рабочего режима указывать не нужно. Он необходим только для тестирования - если он будет присутствовать, то ничего происходить не будет, хотя в консоли будет отображаться эмуляция реальных операций.


rotation_folders_name.vbs

Option Explicit
On Error Resume Next
 
Dim FSO, WshShell
Dim excldPath, bPath, maxFolders, testMode
 
bPath = Wscript.Arguments.Named.Item("path")
excldPath = Wscript.Arguments.Named.Item("exclude")
maxFolders = Wscript.Arguments.Named.Item("max")
If (Wscript.Arguments.Named.Exists("testmode")) Then
    testMode = True
Else
    testMode = False
End If
 
Set WshShell = WScript.CreateObject("WScript.Shell")
'WshShell.Exec "cmd /c chcp 866"
 
Set FSO = CreateObject("Scripting.FileSystemObject")
 
If (testMode = True) Then
    Wscript.Echo vbCrLf & "Exclude -	" & excldPath
    Wscript.Echo "Path folders -	" & bPath
    Wscript.Echo "Max folders -	" & maxFolders & vbCrLf
End If
 
If (FSO.FolderExists(excldPath) And FSO.FolderExists(bPath)) Then
    If (testMode = True) Then
	Wscript.Echo vbCrLf & "Deleted - [" & DeleteOldFolders(Array(bPath, maxFolders, excldPath)) & "] old folders"
    Else
	DeleteOldFolders(Array(bPath, maxFolders, excldPath))
    End If
End If
 
' Out: testMode
Function DeleteOldFolders(pDirArr)
    Dim savP, maxF, excldP
    Dim FSO, FSOsf
    Dim savFolders, savFolder, delFolder, fldrsArr(), cF, dF
 
    savP = pDirArr(0)
    maxF = pDirArr(1) * 1
    excldP = pDirArr(2)
 
    cF = 0
    dF = 0
 
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set FSOsf = FSO.GetFolder(savP)
    Set savFolders = FSOsf.SubFolders
 
    For Each savFolder In savFolders
	If (StrComp(excldP, savFolder.Path, vbTextCompare) <> 0) Then 
	    If (testMode = True) Then
		Wscript.Echo "-> ADD  - " & savFolder.Path
	    End If
	    ReDim Preserve fldrsArr(cF)
	    fldrsArr(cF) = savFolder.Path
	    cF = cF + 1
	Else
	    If (testMode = True) Then
		Wscript.Echo "-> SKIP - " & savFolder.Path
	    End If
	End If
    Next
    If ((cF > 0) And (cF > maxF)) Then
	If (testMode = True) Then
	    Wscript.Echo vbCrLf & "After Sort:"
	End If
        For Each delFolder In SortArray(fldrsArr)
	    If (cF > maxF) Then
		If (testMode = True) Then
		    Wscript.Echo "-> DEL  - " & Right("      " & cF, 6) & " -> " & delFolder
		Else
		    'WshShell.Exec "cmd /c rmdir /S /Q " & Chr(34) & delFolder & Chr(34)
		    FSO.DeleteFolder delFolder, True
		End If
		dF = dF +1
	    Else
		If (testMode = True) Then
		    Wscript.Echo "-> SKIP - " & Right("      " & cF, 6) & " -> " & delFolder
		End If
	    End If
	    cF = cF - 1
        Next
    End If
    DeleteOldFolders = dF
End Function
 
Function SortArray(arr)
	Dim m, n 'counters
	Dim b 'buffer
	Dim f 'flag
	If IsArray(arr) Then
		For m = 0 To UBound(arr)-1
			f = True
			For n = 0 To UBound(arr)-1
				If arr(n) > arr(n+1) Then
					b = arr(n)
					arr(n) = arr(n+1)
					arr(n+1) = b
					f = False
				End If
			Next
			If f Then Exit For
		Next
	End If
	SortArray = arr
End Function

ВАЖНО! Сортировка папок происходит по их имени (а не временной метке), поэтому в имени папок должна присутствовать дата в формате подходящем для сортировки (всегда две цифры в дне и месяце - 0 вначале если число меньше 10, а так же подходящий для сортировки порядок в имени - сначала год, потом месяц, после чего день, например: ".../backup_2017-08-21").


Скрипт vbs, удаляющий старые лог-файлы

Скрипт ротации логов, который ищет в указанной папке только файлы с расширением ".log", сортирует их по имени и оставляет только последние 30 (остальные удаляет).

Запускать так (в консоли):
cscript //NoLogo "C:\_ПУТЬ_\rotation_log_files.vbs" /path:"D:\Log_Folder" /max:30 /testmode

ВАЖНО! Параметр /testmode для рабочего режима указывать не нужно. Он необходим только для тестирования - если он будет присутствовать, то ничего происходить не будет, хотя в консоли будет отображаться эмуляция реальных операций.


rotation_log_files.vbs

Option Explicit
On Error Resume Next
 
Dim FSO, WshShell
Dim logPath, maxFiles, testMode
 
logPath = Wscript.Arguments.Named.Item("path")
maxFiles = Wscript.Arguments.Named.Item("max")
If (Wscript.Arguments.Named.Exists("testmode")) Then
    testMode = True
Else
    testMode = False
End If
 
Set WshShell = WScript.CreateObject("WScript.Shell")
'WshShell.Exec "cmd /c chcp 866"
 
Set FSO = CreateObject("Scripting.FileSystemObject")
 
If (testMode = True) Then
    Wscript.Echo vbCrLf & "Path log -	" & logPath
    Wscript.Echo "Max files -	" & maxFiles & vbCrLf
End If
 
If (FSO.FolderExists(logPath)) Then
    If (testMode = True) Then
	Wscript.Echo vbCrLf & "Deleted - [" & DeleteOldLogs(Array(logPath, maxFiles)) & "] old log files"
    Else
	Wscript.Echo DeleteOldLogs(Array(logPath, maxFiles))
    End If
End If
 
' Out: testMode
Function DeleteOldLogs(logArr)
    Dim logP, maxF
    Dim FSO, FSOsf
    Dim sFiles, sFile, delFile, flArr(), cF, dF
 
    logP = logArr(0)
    maxF = logArr(1) * 1
 
    cF = 0
    dF = 0
 
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set FSOsf = FSO.GetFolder(logP)
    Set sFiles = FSOsf.Files
 
    If (sFiles.Count > maxF) Then
	For Each sFile In sFiles
	    If (Right(sFile.Name,3) = "log") Then
		If (testMode = True) Then
		    Wscript.Echo "-> ADD  - " & sFile.Name
		End If
		ReDim Preserve flArr(cF)
		flArr(cF) = sFile.Path
		cF = cF + 1
	    Else
		If (testMode = True) Then
		    Wscript.Echo "-> SKIP - " & sFile.Name
		End If
	    End If
	Next
	If ((cF > 0) And (cF > maxF)) Then
	    If (testMode = True) Then
		Wscript.Echo vbCrLf & "After Sort:"
	    End If
            For Each delFile In SortArray(flArr)
		If (cF > maxF) Then
		    If (testMode = True) Then
			Wscript.Echo "-> DEL  - " & Right("      " & cF, 6) & " -> " & delFile
		    Else
			FSO.GetFile(delFile).Delete(True)
		    End If
		    dF = dF +1
		Else
		    If (testMode = True) Then
			Wscript.Echo "-> SKIP - " & Right("      " & cF, 6) & " -> " & delFile
		    End If
		End If
		cF = cF - 1
            Next
	End If
    End If
    DeleteOldLogs = dF
End Function
 
Function SortArray(arr)
	Dim m, n 'counters
	Dim b 'buffer
	Dim f 'flag
	If IsArray(arr) Then
		For m = 0 To UBound(arr)-1
			f = True
			For n = 0 To UBound(arr)-1
				If arr(n) > arr(n+1) Then
					b = arr(n)
					arr(n) = arr(n+1)
					arr(n+1) = b
					f = False
				End If
			Next
			If f Then Exit For
		Next
	End If
	SortArray = arr
End Function

ВАЖНО! Сортировка логов происходит по имени файлов, поэтому в имени логов должна присутствовать дата в формате подходящем для сортировки (всегда две цифры в дне и месяце - 0 вначале если число меньше 10, а так же подходящий для сортировки порядок в имени - сначала год, потом месяц, после чего день, например: "backup_2017-08-21.log").

Рекламные ссылки:
Вопросы по теме статьи (просьба - без личностей), - присутствует премодерация:
   - регистрироваться НЕ обязательно! -

Комментарий будет опубликован только после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)