19 октября 2013 г.

Что делать, если не удается импортировать базу данных Microsoft SQL Server (ошибка 3154)?

Недавно мне нужно было импортировать базу данных Microsoft SQL Server, созданной на одном сервере на другой сервер. Обычно я это делаю с помощью SQL Server Management Studio.

Вы, наверняка, в курсе, что простой экспорт и импорт баз данных можно выполнять с помощью функций резервного копирования и восстановления, где команда Back up будет служить экспортом, а команда Restore - импортом. (По умолчанию в подпапке Backups папки, где установлен Microsoft SQL Server, появится файл c расширением *.bak. Его-то и можно использовать для импорта на другом сервере.)

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

The backup set holds a backup of a database other than the existing 'MyDatabase' database. RESTORE DATABASE is terminating abnormally. (Microsoft SQL Server, Error: 3154)

Почему же она возникает и как ее преодолеть?


Интернет дал мне две подсказки.

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


Этот фокус я знал и без интернета. И я как раз эту опцию включал. И мне это никак в этот раз не помогало.

Во-вторых, импортировать базу данных можно не с помощью пункта меню, а с помощью скрипта.

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

Скрипт примерно такой:

RESTORE DATABASE NEW
FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL\Backup\TEST.bak'
WITH REPLACE

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

Путь этот резко отличался от путей, которые давал ему мой сервер. Дело в том, что на сервере, откуда была взята база данных, файлы *.mdf и *.ldf находились не в папке по умолчанию для Microsoft SQL Server, а в соврешенно другом месте. И путь этот был жестко пописан в файле импорта (резервной копии).

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

Что ж, это решаемая проблема.


Неправильный, но рабочий вариант (мой)


Поэтому я (плохо разбираясь в Microsoft SQL Server):
  1. Создал базу данных с точно таким же названием, что и на сервере-источнике. 
  2. Остановил службу SQL Server для следующего шага.
  3. Скопировал новосозданные файлы из папки по умолчанию, где мой сервер их создал, в папку, в которой ожидает ее бэкап, который я пытался импортировать на свой сервер.
  4. Запустил службу SQL Server.
Все. Теперь должно было заработать как нужно.


Правильный путь


Отступление. Умные же люди говорят, что правильно нужно в этом случае использовать еще пару опций MOVE, чтобы дать правильный новый путь к базе данных. Что-то вроде:

RESTORE DATABASE NEW
FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL\Backup\TEST.bak'
WITH REPLACE,
MOVE 'TEST' TO 'C:\Program Files\Microsoft SQL Server\MSSQL\DATA\NEW.mdf',
MOVE 'TEST_Log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL\DATA\NEW_log.ldf'

Либо в окне импорта (восстановления), указать новый путь в колонке Restore As.


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


Опять неправильный, но рабочий вариант (мой)


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

Скопированные в другое место файлы не открывались при восстановлении БД - доступ был запрещен.

Тут я же растерялся. Успех маячил перед глазами - и на тебе. Очередная ошибка.

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

И ларчик просто открывался. Нужно было всего лишь дать доступ к этим файлам. Чтобы долго не возится - так как это одноразовое действие, я просто временно - для импорта- дал все права учетной записи Everyone.

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

Но повторю. Я делал этот фокус с копированием файлов и выставлением прав на них от не знания правильного способа с опцией MOVE.


Итоги


Повторю главные моменты, которые можно или нужно сделать, если возникают ошибки при импорте (восстановлении) одной БД в другую :
  1. включить перезапись своей базы данных, в которую восстанавливается чужая база данных - либо из из окна восстановления, либо с помощью опции REPLACE в скрипте восстановления
  2. проверить путь к базе данных, прописанный в файле резервной копии базы данных (запустив скрипт, приведенный выше, можно отчетливо увидеть ожидаемый путь при ошибке) 
Путь можно исправить с помощью другой опции MOVE указав логическое имя базы данных-источника, и нового пути к файлам (*.mdf, *.ldf) к файлу получателей.

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

Но лучше воспользоваться MOVE и не морочить себе голову, как я.)

Комментариев нет:

Отправить комментарий