Резервное копирование 1С средствами MS SQL.

В этой статье описано самое обычное резервное копирование ИБ 1С при помощи инструментов MS SQL Server 2008 R2, объяснено почему следует делать именно так, а не иначе, и развеяно несколько мифов.

Резервное копирование 1С средствами MS SQL

Администраторы БД делятся на тех, кто делает бэкапы, и тех, кто будет делать бэкапы.

Введение

В этой статье описано самое обычное резервное копирование ИБ 1С при помощи инструментов MS SQL Server 2008 R2, объяснено почему следует делать именно так, а не иначе, и развеяно несколько мифов. В статье достаточно много ссылок на документацию MS SQL, эта статья скорее обзор механизмов резервного копирования, чем всеобъемлющее руководство. Но для тех, кто сталкивается с этой задачей впервые, даны простые и пошаговые инструкции, которые применимы к простым ситуациям. Статья предназначена не для гуру администрирования, гуру и так всё это знают, но предполагается, что читатель способен сам установить MS SQL Server и заставить это чудо враждебной техники создать в своих недрах базу данных, которую в свою очередь он же способен заставить хранить данные 1С.

Я считаю команду TSQL BACKUP DATABASE (и её брата BACKUP LOG) по сути единственным средством резервного копирования баз 1С, использующих MS SQL Server в качестве СУБД. Почему? Давайте рассмотрим, какие у нас способы вообще есть:

Как Хорошо Плохо Итого
Выгрузка в dt Очень компактный формат. Долго формируется, требует монопольного доступа, не сохраняет часть малозначительных данных (таких как настройки пользователей в ранних версиях), долго разворачивается. Это не столько способ резервного копирования, сколько способ переноса данных из одной среды в другую. Идеален для узких каналов.
Копирование файлов mdf и ldf Очень понятный способ для начинающих админов. Требует освобождения файлов базы данных от блокировки, а это возможно, если база отключена (команда take offline контекстного меню), отсоединена (detach) или просто остановлен сервер. Очевидно, что пользователи в это время работать не смогут. Этот способ имеет смысл применять тогда и только тогда, когда уже произошла авария, чтобы при попытках восстановления хотя бы иметь возможность вернуться к тому варианту, с которого началось восстановление.
Резервное копирование средствами ОС или гипервизора Удобный способ для сред разработки и тестирования. Не всегда дружит с целостностью данных. Ресурсоёмкий способ. Может ограниченно применяться для разработки. В продуктовой среде практического смысла не имеет.
Резервное копироавние средствами MS SQL Не требует простоев. Позволяет восстановить целостное состояние на произвольный момент, если заранее об этом побеспокоиться. Отлично автоматизируется. Экономный по времени и другим ресурсам. Не очень компактный формат. Не все умеют пользоваться этим способом в необходимой мере. Для продуктовых сред — основной инструмент.

Основные сложности при использовании резервного копирования встроенными средствами MS SQL возникают из-за элементарного непонимания принципов работы. Это объясняется отчасти великой ленью, отчасти отсутствием простого и понятного разъяснения на уровне «готовых рецептов» (хм, скажем так, мне не встречалось), да еще и усугубляется ситуация мифосоветами «недогуру» на форумах. Что делать с ленью я не знаю, а вот объяснить основы резервного копирования попробую.

Что и зачем сохраняем?

Давным-давно в далёкой галактике существовал такой продукт инженерно-бухгалтерской мысли, как 1С:Предприятие 7.7. Видимо из-за того, что первые версии 1С:Предприятия разрабатывались для использования популярного формата файлов dbf, его SQL-версия не хранила в базе данных достаточно информации для того, чтобы считать резервное копирование MS SQL полноценным, да еще и при каждом изменении структуры нарушались условия работы полной модели восстановления, поэтому приходилось идти на разные ухищрения, чтобы заставить систему резервного копирования исполнять свою основную функцию. Но, с тех пор, как появилась версия 8 администраторы баз данных наконец-то смогли расслабиться. Штатные средства резервного копирования позволяют создать полную и целостную систему резервных копий. Не входит в резервное копирование только журнал регистрации и некоторые мелочи типа настроек положения форм (в старых версиях), но это потеря этих данных на функциональности системы в не сказывается, хотя безусловно резервные копии журнала регистрации делать правильно и полезно.

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

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

Для того, чтобы резервное копирование применялось только «в мирных» целях, используйте для обеспечения работоспособности и другие средства:

  • Обеспечьте физическую безопасность серверов: пожары, затопления, плохое электропитание, уборщицы, строители, метеориты и дикие животные — все они только и ждут за углом, чтобы уничтожить вашу серверную.
  • Ответственно относитесь к угрозам информационной безопасности.
  • Квалифицированно вносите изменения в систему и заранее максимально убедитесь, что эти изменения не приведут к ухудшениям. Кроме плана внесения изменений желательно иметь и план «что делать, если всё пойдёт не так».
  • Активно используйте технологии повышения доступности и надёжности системы вместо того, чтобы потом разгребать последствия аварий. Для MS SQL следует обратить на следующие возможности:
    • Использование кластеров MS SQL (хотя, если честно, я считаю, это одним из наиболее дорогих и бесполезных способов занять администратора БД для систем не требующих 24х7)
    • Зеркалирование базы данных (в синхронном и асинхронном режиме в зависимости от требований доступности, производительности и стоимости)
    • Доставка журналов транзакций
    • Репликация средствами 1С (распределённые базы данных)

В зависимости от требований доступности системы и от бюджета, выделенного на эти цели, вполне можно выбрать решения, которые позволят на 1-2 порядка сократить время простоя и восстановления при сбоях. Не нужно бояться технологий повышения доступности: они достаточно просты для того, чтобы их изучить за несколько дней при базовых знаниях MS SQL.

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

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

Базовая информация о хранении и обработке данных MS SQL

Данные в MS SQL обычно хранятся в файлах данных (далее ФД — сокращение не общеупотребимое, в данной статье будет еще несколько не очень распространённых сокращений) с расширениями mdf или ndf. Кроме этих файлов есть еще журналы транзакций (ЖТ), которые хранятся в файлах с расширением ldf. Нередко начинающие администраторы безответственно и легкомысленно относятся к ЖТ, как в отношении производительности, так и в отношении надёжности хранения. Это очень грубая ошибка. На самом деле, скорее наоборот, если есть надёжно функционирующая система резервного копирования и на восстановление системы можно выделить много времени, то можно хранить данные на быстром, но крайне ненадёжном RAID-0, но тогда ЖТ должны храниться на отдельном надёжном и производительном ресурсе (хотя бы на RAID-1). Почему так? Давайте рассмотрим подробнее. Сразу оговорюсь, что изложение несколько упрощено, но достаточно для начального понимания.

В ФД хранятся данные страницами по 8 килобайт (которые объединены в экстенты по 64 килобайт, но это не существенно). MS SQL не гарантирует, что сразу после выполнения команды изменения данных, эти изменения попадут в ФД. Нет, просто страница в памяти помечается как «требующая сохранения». Если у сервера достаточно ресурсов, то вскоре эти данные окажутся на диске. Причем, сервер работает «оптимистично» и если эти изменения происходят в транзакции, то они вполне могут попадать на диск до фиксации транзакции. То есть в общем случае, при активной работе ФД содержит разрозненные куски недописанных данных и незавершённых транзакций, для которых неизвестно, будут ли они отменены или зафиксированы. Есть специальная команда «CHECKPOINT«, которая указывает серверу, что нужно «прямо сейчас» сбросить все несохранённые данные на диск, но область применения этой команды достаточно специфична. Достаточно сказать, что 1С её не использует (я не сталкивался) и понимать, что во время работы обычно ФД не находится в целостном состоянии.

Чтобы справиться с этим хаосом нам как раз и нужен ЖТ. В него пишутся следующие события:

  • Информация о старте транзакции и её идентификатор.
  • Информация о факте фиксации или отмене транзакции.
  • Информация обо всех изменениях данных в ФД (грубо говоря, что было и что стало).
  • Информация об изменении самого ФД или структуры базы данных (увеличение файлов, уменьшение файлов, выделение и освобождение страниц, создание и удаление таблиц и индексов)

Вся эта информация пишется с указанием идентификатора транзакции в которой она произошла и в достаточном объёме чтобы понять как из состояния до этой операции перейти к состоянию после этой операции и наоборот (исключение — модель восстановления с неполным протоколированием).

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

select * from ::fn_dblog(null,null)

Из-за того, что жёсткие диски значительно эффективнее работают с последовательной записью, чем с хаотичным потоком команд на чтение и запись и из-за того, что команды SQL будут ждать момента окончания записи в ЖТ, возникает следующая рекомендация:

Если есть хоть малейшая возможность, то в продуктовой среде ЖТ должны располагаться на отдельных (от всего остального) физических носителях, желательно с минимальным временем доступа для последовательной записи и с максимальной надёжностью. Для простых систем вполне подойдёт RAID-1.

Если транзакция отменяется, то все уже внесённые изменения сервер вернёт в предыдущее состояние. Именно поэтому

Отмена транзакции в MS SQL Server обычно длится сопоставимо с суммарной длительностью операций изменения данных самой транзакции. Старайтесь не отменять транзакции или принимать решение об отмене как можно раньше.

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

Что происходит когда ЖТ дошёл до конца файла? Всё просто — если есть освобождённое место в начале, то он начнёт писать в свободное место в начале файла до занятого места. Как закольцованная магнитная лента. Если места в начале нет, то сервер обычно попытается расширить файл журнала транзакций, при этом для сервера выделенный новый кусок является новым виртуальным файлом журнала транзакций, которых в физическом файле транзакций может быть много, но это уже к резервному копированию относится мало. Если у сервера не получится расширить файл (закончилось место на диске или запрещено настройками расширять ЖТ), то текущая транзакция отменится с ошибкой 9002.

Упс. А что же надо сделать чтобы место в ЖТ всегда было? Вот тут мы подошли к системе резервного копирования и к моделям восстановления. Для отмены транзакций и для восстановления корректного состояния сервера в случае внезапного выключения необходимо хранить в ЖТ записи, начиная с момента старта самой ранней из открытых транзакций. Этот минимум пишется и хранится в ЖТ обязательно. Вне зависимости от погоды, настроек сервера и желания админа. Сервер не может допустить, чтобы этой информации не было. Поэтому, если открыть в одном сеансе транзакцию, а в других выполнять разные действия, то журнал транзакций может неожиданно закончиться. Самую раннюю транзакцию можно выявить командой DBCC OPENTRAN. Но это только необходимый минимум информации. Дальнейшее зависит от модели восстановления. В SQL Server их три:

  • Simple (Простая) — хранится только необходимый для жизни остаток ЖТ.
  • Full (Полная) — хранится весь ЖТ с момента последнего резервного копирования журнала транзакций. Обратите внимание, не с момента полного бэкапа!
  • Bulk logged (С неполным протоколированием) — часть (очень небольшая обычно часть) операций записываются в очень компактном формате (по сути только запись, что изменена такая-то страница файла данных). В остальном идентична Full.

С моделями восстановления связано несколько мифов.

  • Simple позволяет снизить нагрузку на дисковую подсистему. Это не так. пишется ровно столько же, сколько при Bulk logged, только считается свободным гораздо раньше.
  • Bulk logged позволяет снизить нагрузку на дисковую подсистему. Для 1С это почти не так. По сути одна из немногих операций, которая может без дополнительных плясок с бубном подпадать под минимальное протоколирование — загрузка данных из выгрузки в формате dt и реструктуризация таблиц.
  • При использовании модели Bulk logged какие-то операции не попадают в резервную копию журнала транзакций и она не позволяет восстановить состояние на момент этой резервной копии. Это не совсем так. Если операция относится к минимально протоколируемым, то в резервную копию попадут текущие страницы с данными и будет возможность «проиграть» журнал транзакций до конца (хотя и нельзя на произвольный момент времени, если есть минимально протоколируемые операции).

Модель Bulk logged для баз 1С использовать почти бессмысленно, поэтому дальше мы её не рассматриваем. А вот выбор между Full и Simple расмотрим подробнее в следующей части.

Для любознательных — ссылки на русскоязычную документацию, которая более полно описывает работу журнала транзакций:

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

По типу формирования резервные копии бывают трёх видов:

  • Full (Полная)
  • Differential (Дифференциальная, разностная)
  • Log (Резервная копия журналов транзакций, учитывая, то, насколько часто этот термин используется, будем сокращать до РКЖТ)

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

Полная и дифференциальная копия работают одинаково для Simple и Full. Резервная копия журналов транзакций полностью отсутствует в Simple.

Полная резервная копия

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

Разностная резервная копия

Хранит страницы данных, изменившиеся с момента последней полной резервной копии. При восстановлении нужно сначала восстановить полную резервную копию (в режиме NORECOVERY, примеры будут приведены ниже), потом можно к получившейся «заготовке» применить любую из последующих разностных копий, но, конечно только из тех, которые сделаны до следующей полной резервной копии. За счет этого можно значительно снизить объём дискового пространства для хранения резервной копии.

Важные моменты:

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

РКЖТ

Содержит копию ЖТ за некоторый период. Обычно с момента прошлой РКЖТ до момента формирования текущей РКЖТ. РКЖТ позволяет из восстановленной в режиме NORECOVERY копии на любой момент времени, входящий в период восстанавливаемой копии ЖТ, восстановить состояние на любой последующий момент времени, входящий в интервал восстанавливаемой резервной копии. При формировании резервной копии со стандартными параметрами, место в файле журнала транзакций высвобождается (до момента последней открытой транзакции).

Очевидно, что РКЖТ не имеет смысла в модели Simple (тогда ЖТ содержит лишь информацию с момента последней незакрытой транзакции).

При использовании РКЖТ возникает важное понятие — непрерывная цепочка РКЖТ. Эту цепочку может прервать либо потеря некоторых резервных копий этой цепочки, либо перевод базы данных в Simple и обратно.

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

Частые заблуждения и мифы:

  • «РКЖТ содержит данные журнала транзакций от момента предыдущего полного или разностного бэкапа». Нет, это не так. РКЖТ содержит и на первый взгляд бесполезные данные между предыдущей РКЖТ и последующим полным бэкапом.
  • «Полный или разностный бэкап должны приводить к освобождению места внутри журнала транзакций». Нет, это не так. Полный и разностный бэкап не трогают цепочку РКЖТ.
  • ЖТ нужно перидически чистить вручную, уменьшать, шринкать. Нет, не надо и даже наоборот — нежелательно. Если освобождать ЖТ между РКЖТ, то будет нарушена цепочка РКЖТ, нужная для восстановления. А постоянные уменьшения/расширения файла приведут к его физической и логической фрагментации.

Как это работает в simple

Пусть есть база данных в 1000 ГБ. Каждый день база прирастает на 2 ГБ, при этом меняется 10 ГБ старых данных. Сделаны следующие резервные копии

  • Полная копия F1 от 0:00 1 февраля (объём 1000 ГБ, сжатие для простоты картины не учитываем)
    • Разностная копия D1.1 от 0:00 2 февраля (объём 12 ГБ)
    • Разностная копия D1.2 от 0:00 3 февраля (объём 19 ГБ)
    • Разностная копия D1.3 от 0:00 4 февраля (объём 25 ГБ)
    • Разностная копия D1.4 от 0:00 5 февраля(объём 31 ГБ)
    • Разностная копия D1.5 от 0:00 6 февраля (объём 36 ГБ)
    • Разностная копия D1.6 от 0:00 7 февраля (объём 40 ГБ)
  • Полная копия F2 от 0:00 8 февраля (объём 1014 ГБ)
    • Разностная копия D2.1 от 0:00 9 февраля (объём 12 ГБ)
    • Разностная копия D2.2 от 0:00 10 февраля (объём 19 ГБ)
    • Разностная копия D2.3 от 0:00 11 февраля (объём 25 ГБ)
    • Разностная копия D2.4 от 0:00 12 февраля(объём 31 ГБ)
    • Разностная копия D2.5 от 0:00 13 февраля (объём 36 ГБ)
    • Разностная копия D2.6 от 0:00 14 февраля (объём 40 ГБ)

При помощи этого набора мы можем восстановить данные на момент 0:00 любого из дней с 1 по 14 февраля. Для этого нам нужно взять полную копию F1 для недели 1-7 февраля или полную копию F2 для 8-14 февраля, восстановить её в режиме NORECOVERY и потом применить разностную копию нужного дня.

Как это работает в full

Пусть у нас есть такой же набор резервных полных и разностных резервных копий, как в предыдущем примере. В дополнение к этому есть следующие РКЖТ:

  • РКЖТ 1 за период с 12:00 31 января по 12:00 2 февраля (около 30 ГБ)
  • РКЖТ 2 за период с 12:00 2 февраля по 12:00 4 февраля (около 30 ГБ)
  • РКЖТ 3 за период с 12:00 4 февраля по 12:00 6 февраля (около 30 ГБ)
  • РКЖТ 4 за период с 12:00 6 февраля по 12:00 7 февраля (около 30 ГБ)
  • РКЖТ 5 за период с 12:00 8 февраля по 12:00 10 февраля (около 30 ГБ)
  • РКЖТ 6 за период с 12:00 10 февраля по 12:00 12 февраля (около 30 ГБ)
  • РКЖТ 7 за период с 12:00 12 февраля по 12:00 14 февраля (около 30 ГБ)
  • РКЖТ 8 за период с 12:00 14 февраля по 12:00 16 февраля (около 30 ГБ)

Обратите внимание:

  1. Размер РКЖТ будет примерно постоянным.
  2. Резервные копии мы можем делать реже, чем разностные или полные, а можем и чаще, тогда они будут меньше по размеру.
  3. Теперь мы можем восстановить состояние системы на любой момент с 0:00 1 февраля, когда у нас есть самая ранняя полная копия по 12:00 16 февраля.

В самом простом случае нам для восстановления понадобятся:

  1. Последняя полная копия до момента восстановления
  2. Последняя разностная копия до момента восстановления
  3. Все РКЖТ, от момена последней разностной копии до момента восстановления

Пример. Для восстановления на 13:13:13 10 февраля нам понадобятся:

  • Полная копия F2 от 0:00 8 февраля
  • Разностная копия D2.2 от 0:00 10 февраля
  • РКЖТ 6 за период с 12:00 10 января по 12:00 12 февраля

Сначала будет восстановлена F2, потом D2.2, потом РКЖТ 6 до момента 13:13:13 10 февраля. Но существенное преимущество Full модели в том, что у нас появляется выбор — использовать последнюю полную или разностную копию или НЕ последнюю. Например, если бы обнаружилось, что копия D2.2 была испорчена, а нам надо восстановить на момент до 13:13:13 10 февраля, то для модели Simple это бы значило, что мы можем восстановить данные только на момент D2.1. При Full — «DON’T PANIC», у нас есть следующие возможности:

  1. Восстановить F2, потом потом D2.1, потом РКЖТ 5, потом потом РКЖТ 6 до момента 13:13:13 10 февраля.
  2. Восстановить F2, потом РКЖТ 4, потом РКЖТ 5, потом потом РКЖТ 6 до момента 13:13:13 10 февраля.
  3. Или вообще восстановить F1 и прогнать все РКЖТ до РКЖТ 6 до момента 13:13:13 10 февраля.

Как видно, полная модель предоставляет нам больший выбор.

А теперь представим, что мы очень хитрые. И за пару дней до сбоя (13:13:13 10 февраля.) знаем, что сбой будет. Мы восстанавливаем на соседнем сервере базу данных из полной резервной копии, оставляя возможность донакатывать последующие состояния разностными копиями или РКЖТ, т. е. оставили в режиме NORECOVERY. И каждый раз сразу после формирования РКЖТ применяем её к этой резервной базе, оставляя в режиме NORECOVERY. Ого! Да ведь на восстановление базы данных у нас теперь уйдёт всего 10-15 минут, вместо того, чтобы восстанавливать огромную базу! Поздравляю, мы заново изобрели механизм доставки журналов, один из способов снижения времени простоев. Если так передавать данные не раз в период, а постоянно, то получится уже зеркалирование, причем если база-источник ждёт пока база-зеркало обновится, то это синхронное зеркалирование, если не ждёт, то асинхронное.

Подробнее о средствах высокой доступности можно прочтитать в справке:

Прочие аспекты резервного копирования

Этот раздел можно смело пропустить, если вам наскучила теория и руки чешутся опробовать настройки резервного копирования.

Файловые группы

1С:Предприятие по сути не умеет работать с файловыми группами. Есть единственная файловая группа и всё. На самом деле программист или администратор базы данных MS SQL способен некоторые таблицы, индексы или даже куски таблиц и индексов положить в отдельные файловые группы (в простейшем варианте — в отдельные файлы). Это нужно либо для того, чтобы ускорить доступ к каким-то данным (положив на очень быстрые носители), либо наоборот, пожертвовав скоростью поместить на более дешёвые носители (например, малоиспользуемые но объёмные данные). При работе с файловыми группами есть возможность делать их резервные копии отдельно, также отдельно можно и восстанавливать, но нужно учесть, что все файловые группы придётся «догнать» до одного момента накатыванием РКЖТ.

Файлы данных

Если помещением данных в разные файловые группы управляет человек, то когда внутри файловой группы есть несколько файлов, то данные по ним распихивает MS SQL Server самостоятельно (при равном объёме файлов — постарается равномерно). С прикладной точки зрения это используется для распараллеливания операций ввода-вывода. А с точки зрения резервных копий есть другой момент. Для очень больших баз данных в эпоху «до SQL 2008» была типичной проблема выделить непрерывное окно для полной резервной копии, да и диск-приемник для этой резервной копии мог просто её не вместить. Самым простым способом в этом случае было делать резервную копию каждого файла (или файловой группы) в своё окно. Сейчас, с активным распространением сжатия резервных копий эта проблема стала меньше, но всё же этот прием можно иметь в виду.

Сжатие резервных копий

В MS SQL Server 2008 появилась супер-мега-ультра возможность. Отныне и навсегда резервные копии могут быть компрессированными при формировании на лету. Это уменьшает размер резервной копии БД 1С в 5-10 раз. А учитывая, что обычно производительность дисковой подсистемы является узким местом СУБД, то это даёт не только снижение стоимости хранения, но и еще мощное ускорение резервного копирования (хотя и повышается нагрузка на процессоры, но обычно процессорные мощности вполне достаточны на сервере СУБД).

Если в версии 2008 эта возможность была только для Enterprise редакции (которая стоит очень дорого), то в 2008 R2 эта возможность отдана в версию Standard, что сильно радует.

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

Один файл бэкапа — много внутренностей

На самом деле резервная копия это не просто файл, это достаточно сложный контейнер, в котором может храниться много резервных копий. У этого подхода очень древняя история (я лично её наблюдаю с версии 6.5), но на текущий момент для администраторов «обычных» баз данных, особенно баз данных 1С, нет каких-либо серьёзных причин не использовать подход «одна резервная копия — один файл». Для общего развития полезно изучить возможность складывать в один файл несколько резервных копий, но использовать её скорее всего не придётся (или если и придётся, то разбирая завалы горе-администратора, который эту возможность неквалифицированно использовал).

Несколько зеркальных копий

В SQL Server есть еще одна замечательная возможность. Можно резервную копию формировать параллельно в несколько приемников. Как простейший пример, можно сваливать одну копию на локальный диск и одновременно складывать на сетевой ресурс. Локальная копия удобна, так как восстановление из неё существенно быстрее, удалённая копия зато гораздо лучше перенесёт физическое уничтожение основного сервера базы данных.

Примеры систем резервного копирования

Довольно теории. Пора практикой доказать, что вся эта кухня работает.

Настройка типичного резервирования сервера через Планы обслуживания (MaintenancePlan)

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

Пользуемся мастером создания плана обслуживания

  1. Запускаем SSMS, подключаемся к нужному серверу.
  2. Запускаем мастер:

  3. Задаём имя плана «Резервное копирование» и описание, указываем галочку «Separate schedules for each task», переходим дальше

  4. Устанавливаем режимы работы (другие галочки лучше оставить отдельным планам обслуживания), переходим дальше

  5. Начинаем настраивать полное резервное копирование:

  6. Настраиваем полное копирование всех пользовательских баз данных. Системные базы данных тоже желательно сохранять, но во-первых не все (имеет смысл только master и msdb, если вы специально не изменяете model), во-вторых, возможно, с другой периодичностью, в-третьих для master не нужно сохранять РКЖТ.

  7. Настраиваем детали копирования. Обратите внимание на следующие моменты:

    • удобнее для каждой БД делать отдельный подкаталог, если этих БД больше 2-3 на сервере;
    • если нет дополнительных средств проверки, то крайне желательно выставить галочку «Verify backup integrity». Хотя возможна ситуация, когда даже проверенная таким образом копия не восстановится, но такая проверка лучше, чем никакая;
    • вариант сжатия установлен «по настройкам сервера», очень желательно включить эту возможность на уровне сервера;
    • папку «C:Backup» я использую только для примера.
  8. Настраиваем расписание (например, раз в неделю по воскресеньям в полночь, примерно как в рассмотренном ранее примере):

  9. Аналогично настраиваем разностные резервные копии, но раз в день, кроме воскресенья. Тоже в полночь.

  10. РКЖТ. Ежедневно в 12:00 (остальное аналогично предыдущим).

    • Обратите внимание, что базы данных с моделью восстановления simple будут игнорироваться.
    • Обратите внимание, что галочку «Back up the tail…» ставить не следует. Она не предназначена для обычного резервного копирования журналов транзакций.
  11. Настроим разумный горизонт хранения резервных копий в этой папке (например, 4 недели, предполагается, что резервные копии из этой папки копируются еще куда-то и хранятся существенно дольше):

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

  13. Проверяем, убеждаемся, что всё правильно …

  14. Вот в общем-то и всё. Резервное копирование, подходящее для большинства баз данных размером от 1-2 ГБ до 200-300 ГБ готово.

  15. Как проверить, что система работает?
    • Проверяем, что нужные объекты созданы:

    • Для каждого из заданий (Резервное копирование.Subplan_1, Резервное копирование.Subplan_2, Резервное копирование.Subplan_3, Резервное копирование.Subplan_4) проверяем, что они запускаются:


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

    • Проверяем, что в целевой папке появились резервные копии.
    • Проверяем, что разностная копия существенно меньше полной.
    • Снова запускаем задание Резервное копирование.Subplan_3 (это РКЖТ) и проверяем, что второй сгенерированный файл РКЖТ в каждой базе имеет небольшой размер относительно первого (В MS SQL Server 2005 стоит перед повторным выполнением нужно подождать пару минут.)
    • Проверяем папку протоколов и читаем (у меня это папка C:Program FilesMicrosoft SQL ServerMSSQL10_50.MSSQLSERVERMSSQLLog — та, которая была настроена на шаге 12). Читаем протоколы, убеждаемся, что ошибок нет.
  16. …????
  17. PROFIT!!!

Настройка резервирования сервера скриптами TSQL, примеры некоторых возможностей

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

  • Использовать зеркальное резервирование
  • Использовать настройки сжатия отличные от настроек сервера
  • Не позволяет гибко реагировать на возникающие ситуации (никаких возможностей по обработке ошибок)
  • Не позволяет гибко использовать настройки безопасности
  • Планы обслуживания очень неудобно развёртывать (и поддерживать одинаковыми) на большом количестве серверов (даже, пожалуй, уже на 3-4)

Ниже приведены типичные команды резервного копирования

Полная резервная копия

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

BACKUP DATABASE [mydb] TO DISK = N'C:Backupmydb.bak'
WITH INIT, FORMAT, STATS = 1, CHECKSUM

Разностная резервная копия

Аналогично — разностная копия

BACKUP DATABASE [mydb] TO DISK = N'C:Backupmydb.diff'
WITH DIFFERENTIAL, INIT, FORMAT, STATS = 1, CHECKSUM

РКЖТ

Резервная копия журнала транзакций

BACKUP LOG [mydb] TO DISK = N'C:Backupmydb.trn' WITH INIT, FORMAT

Зеркальное резервирование

Часто удобно делать сразу не одну резервную копию, а две. Например, одна может лежать локально на сервере (чтобы была под рукой), а вторая сразу формируется в физически удалённое и защищённое от неблагоприятных воздействий хранилище:

BACKUP DATABASE [mydb] TO
DISK = N'C:Backupmydb.bak',
MIRROR TO DISK = N'\safe-serverackupmydb.bak'
WITH INIT, FORMAT

Важный момент, который часто упускается: у пользователя, от имени которого запускается процесс MSSQL Server должен быть доступ к ресурсу «\safe-serverackup», иначе копирование завершится с ошибкой. Если MSSQL Server запущен от имени системы, то доступ нужно давать пользователю домена «имя_сервера$», но лучше всё-таки корректно настроить запуск MS SQL от имени специально созданного пользователя.

Если не указать MIRROR TO, то это будет не 2 зеркальных копии, а одна копия, разбитая на 2 файла, по принципу чередования. И каждая из них в отдельности будет бесполезна.

Ссылки

Полезнее всего для понимания работы резервного копирования ознакомиться со следующими статьями:

Примеры использования систем резервного копирования

Так, так, так. Вы думаете что резервное копирование работает? А вы уверены? А вы уверены, что то, что формируется резервным копированием при аварии можно будет использовать для восстановления? Давайте проверим, а заодно научимся восстанавливать данные. Проверка возможностей восстановления — это обязательный этап настройки резервного копирования.

Проверяем резервную копию без восстановления

Файл лежит на диске. Но может быть это вовсе и не резервная копия? Как проверить:

RESTORE VERIFYONLY FROM DISK = N'C:Backupmydb.bak'

Здесь, правда, как с анализами в больнице: если результат анализа положительный, то болезнь есть, если отрицательный, то это еще не гарантирует, что болезни нет. Вот и тут также: если RESTORE VERIFYONLY ругается на ваш файл, то он некорректный. Но если не ругается, то это еще не окончательная гарантия, что он восстановится. Особенно это актуально для предыдущих версий MS SQL Server.

Восстановление полной копии в новую базу данных

Это, пожалуй, самая частая операция с файлами резервных копий. Делать её можно как скриптом, так и интерактивно. Давайте сначала интерактивно:

  1. Выбираем Restore Database из контекстного меню:

  2. Выбираем базу данных, в которую надо восстановить файл, и сам файл

  3. На закладке Options настраиваем, где будут лежать файлы восстановленной базы данных. Если базу данных восстанавливаем поверх существующей, то нужно установить флажок WITH REPLACE

  4. Жмем OK

А вот вариант TSQL:

RESTORE DATABASE mydb FROM DISK = N'C:Backupmydb.bak'

Для самых хитрых и ленивых есть очень полезная возможность создать вариант TSQL из настроенного окна восстановления:

Восстановление полной копии и разностной

RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.bak'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.diff'
WITH RECOVERY;

Восстановление полной копии, разностной и нескольких журналов транзакций

RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.bak'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.diff'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backuplog1.trn'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backuplog2.trn'
WITH RECOVERY;

Восстановление до определённой точки

RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.bak'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backupmydb.diff'
WITH NORECOVERY;
RESTORE DATABASE mydb
FROM DISK = N'C:Backuplog1.trn'
WITH STOPAT = '2013-02-12 21:45:00';
RESTORE DATABASE mydb
FROM DISK = N'C:Backuplog2.trn'
WITH STOPAT = '2013-02-12 21:45:00';

Обратите внимание, если указанное время STOPAT назначено после создания последней резервной копии журналов, база данных остается в невосстановленном состоянии, как если бы инструкция RESTORE LOG работала с параметром NORECOVERY.

Факультативно рекомендую посмотреть самостоятельно

  • Восстановление с использованием «хвоста» журнала транзакций (WITH TAIL)
  • Восстановление в состояние standby (но важно понимать, что обычно 1С не сможет работать с БД, доступной только для чтения)
  • Восстановление сбойных страниц, восстановление файлов (факультатив)

Все эти возможности можно посмотреть в MSDN:

Заключение

Приведённой информации достаточно для ликбеза по резервным копиям, но недостаточно для практических навыков. Читайте, изучайте, тренируйтесь (в «песочнице», естественно). Всё вышеперечисленное применимо далеко не только к 1С:Предприятияю.

Напоследок ссылочка по теме: Пошаговая инструкция восстановления повреждённой БД (доля шутки)

79 Comments

  1. DMSDeveloper

    Спасибо автору за развернутое описание принципов резервного копирования!

    Утащил в свою библиотеку.

    Reply
  2. DoctorRoza

    Ух! Написано то, «ни салили, букавак многа». Зачетный пост, плюс однозначно! 🙂

    Reply
  3. speshuric

    (1) пожалуй, просто слегка устал читать «шринкателей логов» и «поставил simple чтобы база быстрее была»

    (2) DoctorRoza, картинок много, а букв в меру 🙂

    Reply
  4. headMade

    Спасибо, интересная статья.

    Посоветуете может книгу по настройке, администрированию MSQL, где так же доходчиво все было было показано ?

    Reply
  5. apatyukov

    (3) speshuric, Вот и ты в писатели подался 🙂 перешлю статью для БД 🙂

    Reply
  6. andr_andrey

    спасибо за лаконичную статью, будет куда отправлять некоторых 1сников.

    хотя, чего греха таить, пока таких статей мало или их никто не читает, не пыльная работа по настройке бэкапа давала на конфеты и мороженное 🙂

    Reply
  7. Новиков

    Автор молодец. Давно не видел такой грамотной подачи — с одной стороны, и — не скатывания к адаму и еве — с другой.

    Ждем следующую обзорную статью, которые позволяют автоматизировать всю рутину, которая описана в статье «в несколько кликов мыши» (с).

    Reply
  8. speshuric
    Reply
  9. apatyukov

    (8) speshuric, Наскольку помню в книге знаний для Мисты у тебя публикации были… Сюда переносить будешь?

    Reply
  10. speshuric

    (9) apatyukov, оно устарело, к счастью, в марте. Марте 2005 года 🙂

    Reply
  11. vbuots

    О, да!

    Так и надо писать статьи!

    Пошел делать все правильно 🙂

    Reply
  12. VallyD

    Спасибо за огромный труд. Много интересного и нового почерпнула из статьи, так как только начинаю осваивать азы программирования.

    Reply
  13. andr_andrey

    (8) speshuric,

    просто в последнее время часто встречается: при полной модели восстановления и двух полных резервных копиях базы в сутки, делают бэкап 60Гбайтного журнала транзакций 1 раз в 2 недели исключительно для того чтобы шринкнуть журнал и удалить этот «ненужный» бэкап. При этом форумы пестрят вопросом, что делать с переполняющим диск журналом транзакций. Пусть хоть тут они прочитают введение в суть вопроса без страшного слова «мануал».

    Добавлю тут пример простенького скрипта архивирования резервных копий с помощью WinRar для владельцев SQLserver-а без возможности сжатия (пусть резервные копии хранятся в папке «C:Backup» имеют расширение «bak», и WinRar у нас установлен в папку «C:WinRAR»):

    cd «C:Backup»

    for %%i in (*.bak) do «C:WinRARwinrar» m -ibck %%~ni %%i

    Reply
  14. speshuric

    (13) andr_andrey,

    Лично я не вижу смысла сейчас в RARении. SQL Server 2005 уже с поддержки планируют снимать, и сейчас, наверное, ни одной причины не назову оставаться на нём для 1С 8, а Express использовать в продукте как-то странно. Поэтому сейчас лучше всё-таки использовать сжатие.

    Reply
  15. andr_andrey

    Вы забыли про 2008 Standard, там нет сжатия 🙁

    Reply
  16. speshuric

    (15) andr_andrey,

    Не забыл, на 2008 R2 лучше мигрировать, если лицензия или совесть позволяет.

    Reply
  17. RomanUzmov

    Автору — зачет! Полная и написанная понятным языком статья, очень полезная для начинающих сисадмов! 🙂

    Reply
  18. sevushka

    Отличная статья, но не раскрыт один маленький нюанс.

    Что надо написать в t-sql, чтобы сделать бекап (с помощью mirror), который на локальном жестком диске будет хранить 1 месяц, а на удаленном (сетевом) — 1 год?

    Reply
  19. speshuric

    (18) Не раскрыт потому что ничего писать не нужно. С mirror бэкап делается, а не удаляется. Для удаления нужно cleanup task настраивать, если в терминах maintenance планов.

    Reply
  20. denisk37

    Спасибо. Просвятился. Перенастроил у себя backup-ы

    Reply
  21. WWWolfy

    0) не забыть USE MASTER

    1) в случае загрузки логов — RESTORE LOG:

    RESTORE LOG mydb
    FROM DISK = N’C:Backuplog2.trn’
    WITH STOPAT = ‘12.02.2013 21:45:00’;

    2) В случае загрузки в существующую базу не забыть указать параметр REPLACE

    3) Когда вручную создаете бэкап, то ещё раз помните — в поле где указываются файлы бэкапа будет использоваться не выделенный файл, а ВСЕ файлы. Т.е. MS:SQL размажет бэкап по всем указанным файлам.

    В тексте статьи это есть, но только мельком.

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

    PS

    Хотел спросить — только у меня при загрузке через Management Studio не получается загрузить «на точку» (указываю вверху)?

    Грузит полностью лог.

    Через скрипты всё ОК.

    Reply
  22. turbo232

    Статья понравилась, спасибо!

    Непонятен следующий момент:

    Пример. Для восстановления на 13:13:13 10 февраля нам понадобятся:

    Полная копия F2 от 0:00 8 февраля

    Разностная копия D2.2 от 0:00 10 февраля

    РКЖТ 6 за период с 12:00 10 января по 12:00 12 февраля

    Видимо, «10 января» — опечатка?

    Где взять ЖТ с 0:00 по 12:00 10 февраля, в РКЖТ 5?

    Reply
  23. speshuric

    (22) turbo232, да, опечатка, спасибо за отзыв и замечание.

    Reply
  24. suxo

    Подскажите, можно ли создать план резервного копирования, как описано выше НО добавить к нему MIRROR TO ?

    Т.е. у меня настроен план копирования всех баз(Backup Database Task) в папку. Для каждой базы свои подпапки. Но хотелось бы копировать их сразу в две папки.

    Reply
  25. zzz_natali

    Мои «5 копеек»:

    Целостность и живучесть отложенных яиц(архивов) я контролирую с помощью ежедневного резервного копирования и восстановления рабочей базы в параллельное состояние. Иными словами, ночью главная база(base1) бакапится и тут же средствами TSQL реанимируется параллельно рабочей(base2).

    Т.е. на каждое утро имеем две актуальные базы. Все развлекухи(отчеты, программные дописки) главбух «марьиванна» и иже с ней делают на base2, чтобы не сажать(по нагрузке) манагеров в рабочей(base1).

    Reply
  26. speshuric

    (25) zzz_natali,

    Автоматическое создание «игрушечной» копии рабочей базы по расписанию в целом хорошая идея, если только вы не забыли про такие «милые особенности»:

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

    А вот держать подготовленную копию в режиме stand by на соседнем сервере, восстановленную с заранее оговоренным запаздыванием — полезная практика. Для переключения на эту БД остаётся только восстановить кусочек журналов транзакций и не нужно ждать восстановления копии.

    Reply
  27. victorree

    Спасибо за статью! Не получилось сделать восстановление из полной копии с журналами транзакций через мастер восстановления. Если делать последовательно восстановление бака, потом журналов по одному то работает, при попытке добавить все файлы выдает ошибку. Неужели через мастер нельзя за раз сделать восстановление? Или я как то не так делаю?

    Reply
  28. ZergKRSK

    (27) victorree, какую ошибку у Вас выдает? У меня тоже не получается через мастера сделать.

    Reply
  29. speshuric

    (28) А что именно не получается?

    Reply
  30. tolyan_ekb

    Я наверно не внимательно читал. Как бороться с переполнением ЖТ?

    Reply
  31. speshuric

    (30) Собственно, регулярное резервное копирование ЖТ избавляет от самой частой причины его переполнения. Он не переполняется, потому что своевременно сливается и место внутри файлов освобождается. Если при настроенном резервном копировании ЖТ всё равно переполняется, то это может быть из-за:

    • Незавершённых длительных транзакций
    • Поломанной репликации
    • Огромных изменений в БД (например, нередко при перестроении индексов).

    Проверить причину разрастания можно командой:

    SELECT [name], recovery_model_desc, log_reuse_wait_desc FROM sys.databases;

    Каждая из этих проблем сама по себе достаточно серьёзна, чтобы с ней разбираться безотлагательно. Для корректной «бережливой» переиндексации можно использовать скрипт из моей другой статьи.

    Reply
  32. AHDP

    (24) suxo,

    Через xp_cmdshell выполняйте xcopy.exe

    Reply
  33. tolyan_ekb

    (31) speshuric, т.е. нужно отдельно делать его резервное копирование ЖТ, даже если делаем полное ФД?

    Reply
  34. speshuric

    (33) Да, обязательно при полной модели восстановление делать не только резервные копии данных, но и резервные копии журналов. Иначе полная модель не нужна.

    Reply
  35. VVi3ard

    (34) speshuric,

    Если нет необходимости восстанавливать базу на любой момент времени и достаточно возможности восстановить «на начало дня» тогда есть смысл использовать Simple + Разностный BackUp в течении недели.

    В этом случае не нужно делать копию ЖТ (смысла все равно нет) при этом ЖТ разрастается, вот сейчас посмотрел для базы с режимом Simple у меня в журнале 82% неиспользуемого места (280 Гб) и он вырос достаточно сильно.

    В этом случае я думаю shrink не помешал бы?

    Может в этом случае есть смысл после очередного разностного BackUp делать Shrink с реорганизацией так что бы оставалось 10% свободного места в журнале. ?

    Reply
  36. speshuric

    (35) почти уверен, что ЖТ разросся на какой-то конкретной операции: либо перестроение всех индексов, либо большая реструктуризация, либо проведение огромного куска БД в транзакции. Если это не победимо, то в этом случае в принципе может быть и имеет смысл шринкнуть до 25-40% от объёма файла данных

    Reply
  37. AleksSF

    А с какой периодичностью и в какой последовательности необходимо выполнять регламентные операции:

    — Проверка БД

    — Сокращение БД

    — Реорганизация индексов

    — Перестроение индексов

    — Обновление статистики

    — Очистка КЭШа

    А то в разных публикациях разная информация

    Reply
  38. speshuric

    (37) AleksSF,

    А с какой периодичностью и в какой последовательности необходимо выполнять регламентные операции:

    — Проверка БД

    — Сокращение БД

    — Реорганизация индексов

    — Перестроение индексов

    — Обновление статистики

    — Очистка КЭШа

    А то в разных публикациях разная информация

    Ну потому и разная, что для разных БД — разные рекомендации. Если говорить о небольших БД (до 500 ГБ на всем сервере), то я бы сделал примерно так:

    Проверка БД — никогда или раз в 1-2-4 недели по выходным, если уж очень хочется.

    Сокращение БД — никогда (или раз в год, если база сворачивается)

    Реорганизация и перестроение индексов вместе с обновлением статистики — раз в неделю, но не для всех таблиц, а с анализом фрагментации (в другой моей статье пример скрипта)

    «Очистка кэша» не нужна никогда.

    Reply
  39. AleksSF

    (38) speshuric,

    Спасибо, думаю меня это устроит.

    А вторую статью я тоже читал и очень благодарен за нее.

    Reply
  40. AleksSF

    И еще вопрос. Нужно ли делать резервное копирование системных БД.

    Reply
  41. МихаилМ

    С файловыми группами лучше не экспериментировать. тк 1с 82 при реструктуризации пере создает

    таблицы в первичную группу. и придется заново переносить таблицы.

    Reply
  42. OrsoBear

    Огреб только что странную ошибку,

    При восстановлении в непустую базу с отметкой перезаписывать данные.

    Все перенеслось, но у некоторых справочников часть данных потерялась.

    При этом отчеты с оборотами, остатками сходятся.

    Пробую второй раз с выгрузкой в Новую (пустую) базу

    SQL 2008

    раньше вроде таких проблем не было.

    Reply
  43. Just

    Возможно как-нибудь сделать резервную копию без одной-двух таблиц, не создавая для 1с-ки файловые группы?

    Reply
  44. ADirks

    Нарисовал немножко скриптов для работы с бэкапами, может пригодится кому.

    Схема работы такая:

    Делается полный бэкап (раз в сутки, к примеру), складывается в отдельный файл <dbName>-yyy-mm-dd_hh-mm-ss.bak.

    Далее раз в N минут делается бэкап лога, складывается также в отдельный файл <dbName>-yyy-mm-dd_hh-mm-ss_Log.bak,

    т.е. все логи — в одном файле.

    Расположение и имена файлов фиксируются в момент полного бэкапа — для этого создаётся табличка в msdb.

    На сервере, базы которого нужно бэкапить создаются вспомогательные 2 таблички, и 3 SP-шки.

    Таблички

    — BackupLog — информация о полных резервных копиях

    — BackupLog_Diff — информация о разностных копиях

    SP-шки для бэкапа:

    — dbo.BackupDatabase(@dbName, @dir)

    — dbo.BackupTransactionLog(@dbName)

    — dbo.BackupDatabaseDiff(@dbName, @dir)

    SP-шки для просмотра содержимого файлов, и восстановления:

    — dbo.RestoreDatabase(@DestDatabase, @SrcServer, @SrcDb = », @idBackup = -1)

    Разворачивает основной бэкап, в режиме NORECOVERY

    Параметры:

    @DestDatabase — имя базы, куда хотим развернуть бэкап

    @SrcServer — имя сервера, на котором делается бэкап (т.е. где живёт табличка BackupLog)

    @SrcDb — имя базы, бэкап которой надо развернуть. Если не указано, то д.б. указан параметр @idBackup

    @idBackup — ID из таблички BackupLog. Если указан, то будет восстановлен соотв. файл

    — dbo.RestoreTransactionLog(@DestDatabase, @SrcServer, @idBackup, @nStartFile int = -1, @nEndFile int = -1, @fFinal int = 0)

    Разворачивает набор логов

    Параметры:

    @DestDatabase

    @SrcServer

    @idBackup

    @nStartFile, @nEndFile — диапазон номеров логов внутри файла

    @fFinal — если 1, то восстановление последнего лога будет с параметром RECOVERY. По умолчанию NORECOVERY

    — dbo.ShowBackupHeader(@SrcServer, @idBackup)

    Показывает содержимое файлов бэкапа с указанным ID

    Reply
  45. alexfps79

    Здравствуйте! Я прочитал вашу статью про бэкапы SQL, у меня вопрос я делаю .bak файл он получается 7 гигабайт больше чем база. Это реально?

    Reply
  46. speshuric

    (46) alexfps79,

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

    Reply
  47. inomaratadeath

    Спасибо большое за статью! Настраивал бэкап по инструкции — возникли вопросы. при настройке 2 плана дифференциального копирования на скриншоте и в пояснениях не указано — разширение файла ставить так же как и в полном бэкапе *.bak , или ставить *.diff — как в примерах?

    Разностная резервная копия

    Аналогично — разностная копия

    BACKUP DATABASE [mydb] TO DISK = N’C:Backupmydb.diff’

    WITH DIFFERENTIAL, INIT, FORMAT, STATS = 1, CHECKSUM

    Я к чему спрашиваю — при проверке планов было всё нормально, создался файл .bak (правда, не заметил, чтоб сжатие сработало), потом создался *.diff и *.tm для ркжт. Сегодня утром проверяю логи — вижу что дифференциальное копирование не сработало :

    GO
    BACKUP DATABASE [82PMOVK_AK] TO  DISK = N»F:\_arhive82PMOVK_AK82PMOVK_AK_backup_2015_10_21_105824_7325670.diff» WITH  DIFFERENTIAL , NOFORMAT, NOINIT,  NAME = N»82PMOVK_AK_backup_2015_10_21_105824_7325670», SKIP, REWIND, NOUNLOAD,  STATS = 10
    GO
    declare @backupSetId as int
    select @backupSetId = position from msdb..backupset where database_name=N»82PMOVK_AK» and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N»82PMOVK_AK» )
    if @backupSetId is null begin raiserror(N»Ошибка верификации. Сведения о резервном копировании для базы данных «82PMOVK_AK» не найдены.», 16, 1) end
    RESTORE VERIFYONLY FROM  DISK = N»F:\_arhive82PMOVK_AK82PMOVK_AK_backup_2015_10_21_105824_7325­670.diff» WITH  FILE = @backupSetId,  NOUNLOAD,  NOREWIND
    

    И так по всем 16 базам пользователей 🙁

    Это первый момент. Второй — из статьи я так и не понял, что делать с огромным файлом лога транзакций? Почитал по рекомендуемой тут ссылке : заявлялось, что *.ldf сам усекается после создания полной ркжт.

    Описываю ситуацию. файл базы CSM_TEST.mdf весом 3,91 ГБ (4 203 544 576 байт)… и есть файлик CSM_TEST_log.LDF весом 33,9 ГБ (36 402 692 096 байт). И что с ним делать?

    Reply
  48. HDRX

    Такой вопрос по теме: есть рабочая база, есть также развернутая на том же SQL серваке копия для экспериментов, куда периодически загружается SQL бэкап рабочей. Загрузка идет с флагом WITH REPLACE. При выборе бэкапа пути автоматом проставляются базы источника, и вот никак не могу разобраться, нужно ли менять имена на имена файлов базы-приемника? По идее если мы загружаем с WITH REPLACE, должны перезатираться файлы приемника, по факту — то пишет, что файлы используются, то загружает без вопросов, перезатирая файлы приемника (пути при этом не меняются, т.е. остаются от приемника)

    Reply
  49. ADirks

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

    Лог усекается при полном бэкапе базы (а не лога). Если он всё время растёт, то возможно проблема в чём-то другом.

    (49) Вот да, тоже было бы интересно побороть эту особенность. У нас в основном экспериментальные базы на отдельном сервере, но иной раз бывает необходимость.

    Reply
  50. inomaratadeath

    (50) ADirks, Лог получилось усечь, выполнив

    DBCC SHRINKFILE

    А вот с дифференциальным копированием — беда прямо. Принудительно запустил все задачи, как показано в шаге №15 — успешно создался полный бэкап, потом дифференциальный, потом ркжт.

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



    скрин запроса

    И так выборочно по каждой из 16ти баз. Почему SQL не находит полный бэкап, который лежит в той же папке — для меня загадка 🙁

    Reply
  51. ADirks

    (51) А точно ли есть полный бэкап? Проверяется легко: делаешь восстановление базы вручную, если в списке «… резервные наборы» внизу нет ничего — значит нет бэкапа (по крайней мере с точки зрения сервера). Может, файл после бэкапа перемещался/переименовавался?

    Опять же, можно в студии запустить скрипт полного бэкапа, и сразу же дифф — может что-то прояснится.

    Кстати, эти самые дифференциальные бэкапы актуальны только при совсем уж больших объемах баз. У нас к примеру база 40Г, и я делаю полный бэкап по пятницам, и каждые 15 мин. бэкап лога. Лога за неделю всего гиг набегает, восстанавливается за 15мин, а с диффами только гемор один.

    Reply
  52. inomaratadeath

    (52) ADirks, судя по скриншоту — -сервер не видит файла полного бэкапа? Если указываю вручную — вроде опознаёт его корректно.

    Может, файл после бэкапа перемещался/переименовавался?

    Нет, не перемещался, не переименовывался. Всё настраивалось по статье в этом топике.

    У нас к примеру база 40Г, и я делаю полный бэкап по пятницам, и каждые 15 мин. бэкап лога. Лога за неделю всего гиг набегает, восстанавливается за 15мин, а с диффами только гемор один.

    То есть- при восстановлении сначала восстанавливается полный лог, а потом вся цепочка ркжт, создаваемые каждые 15 минут? Или нужен будет только последний ркжт?

    Reply
  53. ADirks

    (53) По первой части ничего сказать не могу, вроде должно всё работать. Когда экспериментировал с диффами — работало.

    Про восстановление по логам:

    Сначала восстанавливается полный бэкап в режиме NORECOVERY, потом восстанавливаются все куски ркжт начиная с первого, до нужного. Самый последний кусок ркжт восстанавливается с флагом RECOVERY, и получаем рабочую базу.

    Как это делается можно посмотреть в скриптах, которые я в (44) приводил. Удобная фигня, как раз когда баз много. Не надо каждый раз всё прописывать в планах обслуживания.

    к примеру, так выглядит еженедельный бэкап:

    use msdb

    exec dbo.BackupDatabase ‘dinal2011’, ‘\NAS2Backup1Cv77’

    а так бэкап лога:

    use msdb

    exec dbo.BackupTransactionLog ‘dinal2011’

    развёртывание тестовой среды (на тестовом сервере):

    exec msdb.dbo.RestoreDatabase ‘test77’, ‘[1CSQL]’, », 59

    exec msdb.dbo.RestoreTransactionLog ‘test77’, ‘[1CSQL]’, 59, 1, 389, 1

    Reply
  54. inomaratadeath

    (54) ADirks, посмотрел скрипты в (44) — ещё больше запутался. Я так понял там идёт работа с файловыми группами? Синтаксис в скриптах очень отличается от синтаксисе в статье. Если делать ежедневный полный бэкап, а потом каждый час ркжт, то — грубо говоря, при сбое я могу ограничиться восстановлением последнего полного бэкапа в режиме норекавери, а потом поочерёдно накатывать ркжт с флагом норекавери от момента полного бэкапа и до последней ркжт с флагом рекавери? Максимум что я потеряю — данные за 1 час работы? Или я что-то упустил?

    Статью несколько раз перечитывал, и с каждым разом всё больше и больше вопросов, чем ответов.

    Частые заблуждения и мифы:

    «РКЖТ содержит данные журнала транзакций от момента предыдущего полного или разностного бэкапа». Нет, это не так. РКЖТ содержит и на первый взгляд бесполезные данные между предыдущей РКЖТ и последующим полным бэкапом.

    Почему последующим полным бэкапом, а не следующим ркжт? Речь же идёт о цепочке ркжт?

    «Полный или разностный бэкап должны приводить к освобождению места внутри журнала транзакций». Нет, это не так. Полный и разностный бэкап не трогают цепочку РКЖТ.

    Причём же тут РКЖТ? Я думал — речь идёт о логе транзакций, который разрастается и весит в несколько раз больше самой базы?

    [CUOTE]ЖТ нужно перидически чистить вручную, уменьшать, шринкать. Нет, не надо и даже наоборот — нежелательно. Если освобождать ЖТ между РКЖТ, то будет нарушена цепочка РКЖТ, нужная для восстановления. А постоянные уменьшения/расширения файла приведут к его физической и логической фрагментации.[/IS-QUOTE] Если нежелательно, что делать с логом транзакций в 30-40 гигабайт при размере базы 3-7 гигабайт? Это разве нормальная ситуация? И разве плохо будет сделать болный бэкап, потом перевести базу в simple, шринкануть лог транзакций до нуля, вернуть в полную модель восстановления?

    Reply
  55. ADirks

    Скрипты выглядят непонятно, т.к. там все SQL-команды генерируются динамически

    По сути, при восстановлении выполняется серия команд

    RESTORE DATABASE [Database] FROM DISK = N’\pathDatabase.bak’ WITH NORECOVERY, NOUNLOAD, REPLACE, STATS = 5

    RESTORE LOG [Database] FROM DISK = N’\pathDatabase_Log.bak’ WITH FILE = 1, NORECOVERY, NOUNLOAD

    RESTORE LOG [Database] FROM DISK = N’\pathDatabase_Log.bak’ WITH FILE = 2, NORECOVERY, NOUNLOAD

    RESTORE LOG [Database] FROM DISK = N’\pathDatabase_Log.bak’ WITH FILE = 3, NORECOVERY, NOUNLOAD



    RESTORE LOG [Database] FROM DISK = N’\pathDatabase_Log.bak’ WITH FILE = 200, RECOVERY, NOUNLOAD

    В принципе, имея бэкап лога можно восстановить состояние БД на любое время, с точностью до SQL-транзакции (не пробовал). Но проще делать бэкап лога почаще.

    Что касается размера файла лога — то он никогда не уменьшается. В момент полного бэкапа базы место внутри файла «освобождается», таким образом, чтобы файл лога не рос сильно, надо чаще делать полный бэкап. У нас, при описанных выше условиях, файл лога 25Г. Т.е. при еженедельном полном бэкапе лог вырастает чуть больше, чем пол базы. Ну и ладно, никого не парит. И шринкать его совершенно ни к чему.

    Reply
  56. inomaratadeath

    что-то SQL кривит, не могу понять где. Поудалял все планы обслуживания и архивации, в логе ERRORLOG всё равно регулярно появляются записи

    2015-11-14 21:00:27.11             Database backed up. Database: 83BP_NN_TRIM, creation date(time): 2015/02/10(12:34:50), pages dumped: 90401, first LSN: 756:4676:37, last LSN: 756:4692:1, number of dump devices: 1, device information: (FILE=1, TYPE=VIRTUAL_DEVICE: {‘{101F414D-13B6-4E75-9E34-9A17172239BB}19’}). This is an informational message only. No user action is required.

    Что это такое, почему оно стартует регулярно в 21.00 и по всем базам? Подозрение, что именно после этого и не видит SQL изначально созданного полного бэкапа.

    Reply
  57. grachev1c

    Стоит задача иметь возможность восстановить или откатить базу с потерей данных максимум за один час. Есть два сервера: на одном одна база до 50 гб, на втором 30-50 баз по 1-2 гб. Что будет эффективнее (по параметрам: надежность, минимальная нагрузка на сервер резервированием, минимальных размер арихивов сам посмотрю) для каждого из серверов делать каждый час по всем базам сервера разностных архив или архив журнала транзакции?

    Reply
  58. speshuric

    (58) grachev1c,

    Для суммы в 150 ГБ с двух серверов и планировать-то лень. Это ж даже полный размер на 2 минуты неспешного копирования на современном железе. Я бы сделал раз в день полный и раз в 5-10 минут ЖТ. Если дисковая система нормально спроектирована (данные, ЖТ и темпдб на разных дисках), то нагрузки не будет. При этом можно где-нибудь сразу разворачивать болванку в norecovery и время восстановления почти равно времени обнаружения — как бы тёплый резерв, как бы аналог доставки журналов (лог шиппинг). С учетом сжатия (5-8 раз обычно, но таблица конфигурации хуже) одного раздела в 1 ТБ хватит «навсегда» (годовая история бэкапов).

    Reply
  59. Вурдалак

    Я конечно дико извиняюсь, что поднимаю старую тему, но все таки. Не совсем понятно, как сделать зеркальную резервную копию? В 24 уже спрашивали, но на этот вопрос тихо ответили в 32 и не совсем понятно как это сделать. Можно ли какой нибудь пример?

    Reply
  60. AlexO

    (60) зеркальная — это что?

    Смысл SQL-ю базу MDF копировать, SQL еще и не даст это сделать.

    Через xcopy делается копия любого файла: запускаешь по расписанию xcopy, и средствами этой команды копируешь куда надо.

    Reply
  61. speshuric

    (60) Зеркальную резервную копию делать при помощи «MIRROR TO», но насколько я помню в maintenance plan это не настраивается, надо писать скрипт. Способ обхода — копировать после создания (это можно настроить). Пример есть и в статье и в справке

    (61) Речь о предложении «MIRROR TO» из синтаксиса BACKUP DATABASE.

    Reply
  62. Вурдалак

    (62) я наверное не внимательно читал 🙁 оказывается MIRROR TO работает только в версии Enterprise

    Reply
  63. TeZooL

    Добрый день.

    Копирую бэкапы bak и trn на сетевой диск, при этом скорость копирования 500-1000КБ, это нормально ?)

    В архив (также на сетевой диск) эти файлы сжимает на скорости 2000 КБ/сек, что тоже мало. Как ускорить копирование?

    Железо 4 sas винта в 10RAID, сеть гигабит, ничего не загружено, другие файлы копирует нормально.

    Reply
  64. user603532_fan_club_chelsea

    Здравствуйте. Почему у меня такая ошибка выходит при проверке задания??? вроде все делал по описанию в статье. И главное где этот самый ЛОГ о котором пишет программа?

    Reply
  65. speshuric

    (65) Это лог конкретного джоба. Его можно посмотреть в свойствах джоба и шага. Дальше зависит от настроек.

    Reply
  66. user603532_fan_club_chelsea

    (66) просто непонятно, что там менять7! что ему не нравится… с такими же настройками на двух других серваках работает без проблем. а тут не хочет

    Reply
  67. sssss_aaaaa_2011

    (64)

    Копирую бэкапы bak и trn на сетевой диск

    А вот не надо так делать. Надо на локальный, а уже с него на сетевой.

    Reply
  68. sssss_aaaaa_2011

    (67) Вы предлагаете нам отгадать? Может таки посмотрите предложенный лог джоба и сами таки поищете причины возникновения ошибки?

    Reply
  69. user603532_fan_club_chelsea

    (69) то что там указано, мне лично не понятно.

    Вот такой текст в логах выходит…

    «Executed as user WorkgRoUPсистема. Microsoft® SQL Server Execute Package Utility Version 10.0.1600.22 for 64-bit Copyright© Microsoft Corp 1984-2005. All rights reserved. The SQL Server Execute Package Utility requires integration Services to be installed one of these editions of SQL 2008: Standard, Enterprise, Develope, or Evalution. To install integration Services, run SQL Server Setup and select integration Services. The package execution failed. The step failed».

    Reply
  70. sssss_aaaaa_2011

    (70)

    то что там указано, мне лично не понятно.

    И потому должно игнорироваться?

    Небось на Express запускаете? Так на нем нет SSIS (SQL Server integration Service), который требуется для этого. О чем вам и написано. Так трудно было перевести?

    Reply
  71. user603532_fan_club_chelsea

    (71) не игнорировалось. а именно, почему здесь не работает, на другом сервере работает??? установка производилась одинаковая и с одного инсталятора… Настройки все одинаковые были…

    Reply
  72. sssss_aaaaa_2011

    (72)В сообщении было написано почему не работает. Не ваша ли задача выяснить

    (72)

    почему здесь не работает, на другом сервере работает??? установка производилась одинаковая и с одного инсталятора… Настройки все одинаковые были…
    Reply
  73. user603532_fan_club_chelsea

    (73) так то оно так… но я серверами SQL ранее вообще не занимался… посмотрел как устанавливают по выложенным инструкциям на сайтах… Поэтому знания по ним нулевые… вот и спрашиваю «глупости» тут…

    Reply
  74. user603532_fan_club_chelsea

    (73) А получится доустановить через «Добавление узла в кластер отработки отказа SQL Server» ???

    Reply
  75. sssss_aaaaa_2011

    (75)ЧЯ что-то не понял, а какое отношение «Добавление узла в кластер » относится к установке отсутствующего SSIS?

    Reply
  76. user603532_fan_club_chelsea

    (76) http://tavalik.ru/wp-content/uploads/2013/01/Ustanovka_1C_SQL_002.png

    или также как устанавливал SQL просто выбрать только недостающую службу… мне просто чтоб после этого программа гнать не начала…

    Reply
  77. sssss_aaaaa_2011

    (77)Ну да. А с чего ей начать «гнать»? Думать не пробовали?

    Reply
  78. user603532_fan_club_chelsea

    (78) Как раз таки и подумал… если не знаешь, что делаешь… лучше спросить!

    Reply
  79. user603532_fan_club_chelsea

    (78) Ладно. В любом случае, спасибо. Заработал SQL.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *