Резервное копирование держится на парадоксе человеческой природы. Все знают, что копии нужны, все собираются их делать, и почти никто не делает регулярно, пока однажды не теряет данные и не хватается за голову. Беда ручного копирования в том, что оно требует дисциплины, которой у людей не хватает: сегодня забыл, завтра некогда, послезавтра подумал, что и так сойдёт, а потом сбой диска, и месяцы работы пропали без всякой копии. Единственное надёжное копирование это то, которое делается само, без участия человека и его ненадёжной памяти. Автоматическое архивирование с разбивкой по дате и есть такая система, что каждую ночь сама создаёт датированную копию и сама убирает устаревшие, не требуя от человека ничего, кроме одной первоначальной настройки.

Суть в сочетании двух механизмов. Первый это датирование: каждая копия получает в имя дату создания, отчего копии не затирают друг друга, а накапливаются летописью, по которой можно вернуться к состоянию на любой прошедший день. Второй это ротация: старые копии автоматически удаляются по достижении заданного возраста, чтобы летопись не разрослась бесконечно, съев всё место. Вместе они дают самоподдерживающуюся систему, которая и хранит историю нужной глубины, и не требует ручной уборки. Понять, как собрать такую систему, значит раз и навсегда решить вопрос регулярного копирования, переложив его с ненадёжного человека на безотказную автоматику.

Датирование архивов как основа летописи копий

Сердце системы это присвоение каждому архиву уникального имени с датой. Без этого свежая копия затирала бы предыдущую, и история не накапливалась бы. Формирование имени архива с датой собирается так:

$data = Get-Date -Format "yyyy-MM-dd"
Compress-Archive -Path "C:\Rabochie" -DestinationPath "C:\Backup\rabochie-$data.zip" -Force

Здесь текущая дата в удобном для сортировки формате подставляется в имя архива, отчего каждая копия получает уникальное датированное имя. Формат даты с года, месяца и дня выбран не случайно: при таком порядке архивы при сортировке по имени выстраиваются и по времени, что удобно для поиска. Это мелочь, но важная, ведь при ином порядке частей даты сортировка по имени перемешала бы копии, и найти нужную стало бы труднее.

Когда копии создаются чаще раза в день, в имя добавляют и время, чтобы они не сталкивались. Имя архива с датой и временем формируется добавлением часов и минут:

$metka = Get-Date -Format "yyyy-MM-dd_HH-mm"
Compress-Archive -Path "C:\Rabochie" -DestinationPath "C:\Backup\rabochie-$metka.zip" -Force

Здесь к дате добавлено время, отчего уникальны даже копии, сделанные в один день. Это нужно для частого копирования, скажем каждый час, где одной даты мало для различения. Гибкость формата метки позволяет подстроить детальность под частоту копирования: для ежедневных копий хватает даты, для ежечасных нужно и время. Выбор детальности метки под ритм копирования и есть первое решение при настройке системы.

Ротация старых копий для сдерживания роста

Датированные копии накапливаются, и без ротации они со временем съедят всё место, ведь каждая ночь добавляет новую, а старые никуда не деваются. Ротация это автоматическое удаление копий старше заданного возраста, удерживающее хранилище в разумных пределах. Удаление архивов старше определённого срока собирается так:

Get-ChildItem "C:\Backup\*.zip" | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | Remove-Item -Force

Здесь удаляются архивы старше тридцати дней, а более свежие остаются. Так хранилище удерживает копии лишь за последний месяц, не разрастаясь бесконечно. Срок хранения подбирают под нужную глубину истории и доступное место: чем дольше хранишь и чем больше копии, тем больше места нужно. Это размен между глубиной летописи и занимаемым местом, который каждый решает под свои условия и объёмы данных.

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

Сборка полного цикла в один скрипт

Датирование и ротация соединяются в один скрипт, который и создаёт свежую копию, и убирает старьё за один прогон. Это и есть самоподдерживающаяся система в действии. Полный цикл копирования с датированием и ротацией собирается так:

$data = Get-Date -Format "yyyy-MM-dd"
Compress-Archive -Path "C:\Rabochie" -DestinationPath "C:\Backup\rabochie-$data.zip" -Force
Get-ChildItem "C:\Backup\rabochie-*.zip" | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | Remove-Item -Force

Здесь скрипт сначала создаёт свежую датированную копию, а затем удаляет копии старше месяца. За один прогон хранилище пополняется свежим и очищается от устаревшего, оставаясь в постоянных пределах. Этот замкнутый цикл создания и уборки и есть ядро автоматического копирования: он не только делает копии, но и сам следит, чтобы они не накапливались бесконечно, что отличает продуманную систему от наивного скрипта, который копит копии, пока не забьёт диск.

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

Постановка на расписание для полной автоматизации

Скрипт копирования становится системой, лишь когда его ставят на расписание, ведь иначе его всё равно надо запускать вручную, и возвращается та самая ненадёжность человеческой дисциплины. Постановка на ночной запуск через планировщик и превращает скрипт в безотказную автоматику. Создание задания ежедневного ночного копирования делается командой:

schtasks /create /tn "НочноеКопирование" /tr "powershell -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1" /sc daily /st 02:00 /ru SYSTEM

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

Ночное время для копирования выбрано не случайно. Ночью машина обычно свободна, и тяжёлая операция архивирования не мешает работе, а данные в этот час стабильны, ведь с ними никто не работает, и копия выходит цельной. Копирование днём, в разгар работы, и нагружало бы машину, и рисковало захватить файлы в момент их изменения, получив несогласованную копию. Поэтому ночь это естественное время для автоматического копирования, и расписание настраивают на безлюдные часы, когда операция пройдёт незаметно и захватит данные в покое.

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

Автоматическая система таит коварную опасность: сломавшись, она молчит, и человек узнаёт об отказе лишь тогда, когда копия понадобится, а её нет. Поэтому автоматическое копирование обязательно снабжают контролем, сигналящим о сбоях. Скрипт должен проверять успех создания копии и оповещать, если что-то пошло не так. Проверка создания свежей копии собирается так:

$svezhij = Get-ChildItem "C:\Backup\rabochie-*.zip" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($svezhij.LastWriteTime -lt (Get-Date).AddHours(-25)) { Write-Warning "Свежей копии нет! Последняя: $($svezhij.Name)" }

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

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

Где хранить копии и почему не на том же диске

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

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

Перенос копий на сетевое или удалённое хранилище тоже встраивают в автоматику. Скрипт после создания свежей копии отправляет её на сетевую папку или иное удалённое хранилище, и тогда копия живёт отдельно от исходной машины, переживая её отказ. Копирование свежего архива на сетевой ресурс добавляется в скрипт строкой переноса:

Copy-Item "C:\Backup\rabochie-$data.zip" "\\backup-server\kopii\" -Force

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

Экономия места через копирование лишь изменившегося

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

Идея проста: первая копия полная, а последующие содержат лишь то, что изменилось со времени предыдущей. Тогда ночное копирование захватывает только свежие правки, что быстро и компактно. Восстановление при этом сложнее, ведь надо взять полную копию и наложить на неё последующие изменения, но выигрыш в месте и времени для больших редко меняющихся данных огромен. Этот размен между простотой восстановления и экономией ресурсов решают под объём и изменчивость данных: для небольших проще полные копии, для больших и инертных выгоднее копировать лишь изменения.

Стоит понимать и риски такого подхода, чтобы применять его осознанно. Цепочка из полной копии и последующих изменений надёжна ровно настолько, насколько цело каждое её звено, ведь потеря промежуточного звена рвёт возможность восстановиться на более поздний момент. Полная же копия самодостаточна и восстанавливается сама по себе. Поэтому при копировании лишь изменений периодически делают и новую полную копию, начиная цепочку заново, чтобы не зависеть от слишком длинной вереницы изменений. Этот баланс между экономией от копирования изменений и надёжностью полных копий и есть тонкость, которую решают, выстраивая систему под конкретные данные и требования к надёжности.

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