Почему нарушается цепочка резервных копий MSSQL при использовании Veeam и скриптов Ola Hallengren?

Системный администратор IT и автоматизация бизнеса
← На главную

В этой статье мы подробно разберем ситуацию, с которой часто сталкиваются системные администраторы и администраторы баз данных 1С, использующие MS SQL Server. Речь пойдет о нарушении цепочки резервного копирования (Backup Chain), когда, казалось бы, настроенные регламентные задания перестают корректно выполнять разностные (Differential) бэкапы.

Рассмотрим конкретный сценарий: для обслуживания базы используется популярный набор скриптов от Ola Hallengren. В какой-то момент цепочка ломается, и попытки восстановить её путем создания ручного полного (FULL) бэкапа не приводят к долгосрочному успеху — на следующий день дифференциальные копии снова падают в ошибку или заменяются на полные.

Давайте проанализируем механику работы LSN, влияние сторонних систем резервного копирования (таких как Veeam или Proxmox) и найдем решение проблемы.

Понимание механики: как работает цепочка бэкапов и LSN

Чтобы разобраться в корне проблемы, нам необходимо вспомнить теорию. Работа цепочки резервного копирования в MS SQL Server строится на последовательности номеров транзакций в логе — LSN (Log Sequence Number).

Когда мы создаем резервные копии, SQL Server проставляет метки, чтобы знать, от какой точки отсчитывать изменения. Основные правила выглядят так:

  1. Полный бэкап (FULL): Создает базовую точку. У базы данных обновляется параметр DifferentialBaseLSN. Это означает, что SQL Server "запоминает": все будущие разностные копии должны содержать изменения, произошедшие строго после этого момента.
  2. Разностный бэкап (DIFF): Содержит только те страницы данных (экстенты), которые изменились с момента последнего обычного полного бэкапа. Он сверяет свой текущий LSN с DifferentialBaseLSN базы.
  3. Копия только для чтения (COPY_ONLY): Это специальный вид полного бэкапа, который не обновляет DifferentialBaseLSN. Он создает копию базы, но не разрывает существующую цепочку. Для SQL Server это выглядит так, будто этого бэкапа и не было в контексте истории изменений.

Суть проблемы: Если кто-то или что-то делает полный бэкап без флага COPY_ONLY, SQL Server считает это новой точкой отсчета. Старый полный бэкап (сделанный скриптом Ola Hallengren) становится неактуальным для создания новых DIFF-копий.

Влияние систем виртуализации (Veeam, Proxmox)

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

Разберем, что происходит ночью в инфраструктуре:

  1. Работает система резервного копирования виртуальных машин (например, Veeam Backup & Replication).
  2. Для обеспечения целостности данных (чтобы бэкап не был "битым") Veeam использует технологию VSS (Volume Shadow Copy Service) и обращается к компоненту SQL Server VSS Writer.
  3. Veeam инициирует создание снепшота (снимка) системы. Если в настройках задания Veeam включена опция Application-Aware Processing (обработка с учетом приложений), то Veeam сообщает SQL Server: "Я сделал резервную копию".
  4. По умолчанию, если не настроено иначе, SQL Server воспринимает это действие как успешный FULL Backup.
  5. В результате DifferentialBaseLSN обновляется. Но сам файл бэкапа лежит внутри проприетарного хранилища Veeam, и SQL Server о его физическом расположении в файловой системе (в привычном понимании скриптов обслуживания) не знает.

Как реагируют скрипты Ola Hallengren

Скрипты Ola Hallengren написаны достаточно умно и содержат защитные механизмы. Давайте посмотрим, как они ведут себя в описанной ситуации:

  1. Наступает время выполнения задания DIFF-бэкапа (например, днем).
  2. Скрипт проверяет текущее состояние базы и видит, что LSN изменился (ночью "кто-то" сделал бэкап).
  3. Скрипт пытается найти файл последнего полного бэкапа, чтобы удостовериться в целостности цепочки.
  4. Так как последний полный бэкап был сделан через VSS (Veeam) и не является файлом .bak в папке назначения скрипта, скрипт понимает, что не сможет обеспечить восстановление цепочки.
  5. Срабатывает логика параметра @ChangeBackupType (по умолчанию включена). Вместо того чтобы выдать ошибку и оставить вас без копии, скрипт принимает решение: "Цепочка нарушена, я сделаю новый FULL бэкап прямо сейчас".

Именно поэтому в логах мы наблюдаем картину: ночью работает Veeam, а днем регламентное задание вместо DIFF делает FULL. Если же в скрипте жестко отключена смена типа бэкапа, то мы получим ошибку выполнения задания.

Диагностика: как подтвердить виновника

Прежде чем переходить к лечению, давайте убедимся в диагнозе. Нам нужно посмотреть историю резервных копий в системной базе msdb. Выполним следующий запрос в Management Studio:


SELECT TOP 20
    s.database_name,
    m.physical_device_name,
    CAST(CAST(s.backup_size / 1000000 AS INT) AS VARCHAR(14)) + ' ' + 'MB' AS bkSize,
    CAST(DATEDIFF(second, s.backup_start_date, s.backup_finish_date) AS VARCHAR(4)) + ' ' + 'Seconds' AS TimeTaken,
    s.backup_start_date,
    CAST(s.first_lsn AS VARCHAR(50)) AS first_lsn,
    CAST(s.last_lsn AS VARCHAR(50)) AS last_lsn,
    CASE s.[type]
        WHEN 'D' THEN 'Full'
        WHEN 'I' THEN 'Differential'
        WHEN 'L' THEN 'Transaction Log'
    END AS BackupType,
    s.server_name,
    s.recovery_model,
    s.is_copy_only
FROM msdb.dbo.backupset s
INNER JOIN msdb.dbo.backupmediafamily m ON s.media_set_id = m.media_set_id
WHERE s.database_name = 'ИМЯ_ВАШЕЙ_БАЗЫ'
ORDER BY backup_start_date DESC;

На что обратить внимание в результатах:

Решение проблемы

Чтобы скрипты Ola Hallengren и Veeam (или другая система резервного копирования ВМ) работали дружно, нам нужно настроить их так, чтобы они не мешали друг другу управлять LSN.

Шаг 1. Настройка Veeam Backup & Replication

Нам необходимо указать Veeam, чтобы он делал бэкапы с флагом COPY_ONLY. Это позволит ему создавать снепшоты и проверять целостность, не сбрасывая DifferentialBaseLSN в SQL Server.

  1. Откройте консоль Veeam.
  2. Найдите задание резервного копирования (Backup Job), в котором находится ваш SQL-сервер.
  3. Зайдите в свойства задания (Edit) и перейдите на вкладку Guest Processing.
  4. Убедитесь, что галочка Enable application-aware processing стоит (это важно для консистентности бэкапа ВМ).
  5. Нажмите кнопку Applications...
  6. Выберите вашу ВМ с SQL Server и нажмите Edit...
  7. Перейдите на вкладку Transaction Logs (или SQL, в зависимости от версии Veeam).
  8. Выберите опцию "Perform copy only" (Выполнять только копирование).

    Примечание: Если вы выбираете "Process transaction logs with this job", Veeam будет пытаться урезать логи, что требует создания полноценного бэкапа (не Copy Only) с точки зрения Veeam, но для SQL это может быть настроено корректно. Однако самым безопасным вариантом для сохранения цепочки Ola Hallengren является именно явный "Copy Only". Если вам нужно, чтобы Veeam тоже бекапил логи — это требует более тонкой настройки, но обычно администраторы выбирают один инструмент: либо Ola Hallengren делает всё (Full+Diff+Log), а Veeam только образ диска (Copy Only), либо Veeam делает всё. Смешивать их опасно.

    Рекомендуемая конфигурация при использовании скриптов Ola Hallengren: В Veeam ставим "Copy Only".

Шаг 2. Восстановление цепочки (Reset)

После того как мы изменили настройки Veeam, текущее состояние цепочки в SQL Server все еще может быть "сломанным" (привязанным к вчерашнему неправильному бэкапу). Нам нужно начать новую правильную цепочку.

  1. Запустите задание полного бэкапа (FULL) скриптом Ola Hallengren вручную.

    Это можно сделать через SQL Server Agent -> Jobs -> Правой кнопкой на задании ...DatabaseBackup - USER_DATABASES - FULL -> Start Job at Step...

  2. Дождитесь успешного завершения.
  3. Теперь параметр DifferentialBaseLSN указывает на файл, который лежит в вашей папке бэкапов.

Шаг 3. Проверка

На следующий день проверьте выполнение заданий. Ночью должен пройти бэкап Veeam (не влияя на цепочку), а днем — успешно выполниться DIFF-бэкап от Ola Hallengren.

Важное замечание о восстановлении

Разберем момент, который упоминался в обсуждении: "Когда нужно было раскатать бэкапы базы за несколько дней, копии поднять не смог".

Если цепочка была нарушена (сделан "левый" Full без Copy Only), то все предыдущие дифференциальные бэкапы становятся бесполезными для накатывания на новый полный бэкап. И наоборот — дифференциальные бэкапы, сделанные после "левого" Full, невозможно накатить на "старый" (ваш) Full бэкап.

Правило восстановления: Вы можете восстановить базу только используя пару: Конкретный FULL + DIFF, основанный именно на этом FULL. Если Full утерян (например, остался внутри удаленного снепшота Veeam), то связанные с ним Diff-бэкапы восстановить не удастся.

Именно поэтому критически важно настроить флаг COPY_ONLY в сторонних системах резервного копирования сразу при их внедрении.

← На главную