Программно восстанавливать системную базу данных ms-sql из C # - PullRequest
1 голос
/ 21 марта 2019

Несмотря на то, что существует множество вопросов и ответов по поводу восстановления программной резервной копии с точки зрения восстановления «нормальной» базы данных, это делается для системной базы данных, такой как [master], [msdb] или [model], с которой я сталкиваюсьмного разных вопросов.Интересно, есть ли у кого-то что-то, особенно для [master], но все это, похоже, вызывает проблемы.На данный момент я запустил ms-sql в однопользовательском режиме (весь сервис), чтобы восстановить базу данных master с флагом T3608, но в тот момент, когда я пытаюсь выполнить запрос RESTORE DATABASE, это разрывает мое соединение ссообщение о сломанной трубе.Проверка консоли служб services.msc показывает, что служба базы данных больше не работает.

Другими словами, выполнение этого запроса приводит к сбою sql-сервера без полезного результата сообщения.

Давайте рассмотрим пример кода.Код генерации запроса выглядит следующим образом:

string query = "RESTORE DATABASE @dbName FROM DISK " + 
    "= @backupPath WITH FILE = @fileID, REPLACE, ";
if (dataFileName != "") {
    query += "MOVE @dataFileName TO @dataFileLocation, ";
}
if (logFileName != "") {
    query += "MOVE @logFileName TO @logFileLocation, ";
}
query += "STATS=1";
SqlCommand cmdData = new SqlCommand(query, conn);
cmdData.Parameters.AddWithValue("@dbName", databaseName);
cmdData.Parameters.AddWithValue("@backupPath", filePath);
cmdData.Parameters.AddWithValue("@fileID", fileIndex);
if (dataFileName != "") {
    cmdData.Parameters.AddWithValue("@dataFileName", dataFileName);
    cmdData.Parameters.AddWithValue("@dataFileLocation", mdfPath);
}
if (logFileName != "") {
    cmdData.Parameters.AddWithValue("@logFileName", logFileName);
    cmdData.Parameters.AddWithValue("@logFileLocation", ldfPath);
}
cmdData.ExecuteNonQuery();

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

Журнал событий делает вещи еще более странными.Я наблюдаю это сообщение:

Изоляция моментального снимка или зафиксированный моментальный снимок чтения недоступны в «главном» базы данных, поскольку SQL Server был запущен с одним или несколькими недокументированными флагами трассировки, которые не позволяют включить базу данных для управления версиями.Транзакция, запущенная с изоляцией моментального снимка, завершится неудачно, и запрос, выполненный в моментальном снимке с фиксацией чтения, будет выполнен успешно, но вернется к фиксации на основе блокировки чтения.

, где он предположительно жалуется на T3608.Журнал событий также содержит сообщения об «успешном восстановлении», но проверка содержимого папки DATA показывает, что моя программа фактически не возвращает файлы базы данных, которые я удалил вручную, но вместо этого, похоже, ничего не делает?

Меня очень смущает странное поведение сервера sql на этом этапе.Кто-нибудь может пролить свет на то, как это может произойти?

Редактировать:

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

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

Я обнаружил, что ms-sql хранит специальную папку «Шаблон данных».Здесь есть несколько шаблонов для специальных баз данных.Я могу скопировать эти шаблоны в настоящую папку DATA, чтобы иметь работающий sql-сервер для восстановления из резервной копии специальных баз данных.

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

Дальнейшая проверка файлов журналов выявляет следующие две интересные ошибки:

Во время повторного выполнения зарегистрированной операции в базе данных «модель» произошла ошибка с идентификатором записи журнала (32: 151:1).Как правило, конкретный сбой ранее регистрировался как ошибка в службе журнала событий Windows.Восстановите базу данных из полной резервной копии или восстановите базу данных.

Операционная система возвратила ошибку 5 (доступ запрещен) для SQL Server во время чтения со смещением 0000000000000000 в файле 'E: \ backupdb \ MSSQL12.TBUINST \ MSSQL \ Template Data \ modellog.ldf'.Дополнительные сообщения в журнале ошибок SQL Server и журнале системных событий могут предоставить более подробную информацию.Это серьезная ошибка системного уровня, которая угрожает целостности базы данных и должна быть немедленно исправлена.Выполните полную проверку согласованности базы данных (DBCC CHECKDB).Эта ошибка может быть вызвана многими факторами;для получения дополнительной информации см. Электронную документацию по SQL Server.

Почему теперь он пытается что-то прочитать в «Данные шаблона»?Это потому, что система шаблонов db или msdb db или модель db содержит ссылки на жестко запрограммированные пути (ы) модели шаблона / msdb / etc db внутри себя , и мне нужно выдавать команды перемещения?Когда / Как в процессе восстановления я выдаю их?

Я также понял, что: если я сначала восстановлю базу данных master и что it содержит пути к другим специальным базам данных, почему сервер SQL теперь выполняет поиск в данных шаблонапапка?В конце концов, он перезапускается при восстановлении базы данных master, поэтому пути к ним теперь должны быть значениями по умолчанию.Не говоря уже о том, что в каждой отдельной операции восстановления я четко указываю, где и файл .bak, и новые файлы .ldf и .mdf должны быть расположены?Это имеет нулевой смысл.

1 Ответ

1 голос
/ 21 марта 2019

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

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