Как получить эксклюзивный доступ к базе данных SQL Server 2005 для восстановления? - PullRequest
20 голосов
/ 08 октября 2008

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

Msg 3101, Level 16, State 1, Line 1
Exclusive access could not be obtained because the database is in use.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

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

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

Есть ли способ написания сценариев в T-SQL, чтобы иметь возможность получить эксклюзивный доступ или разорвать все соединения?

Ответы [ 7 ]

19 голосов
/ 08 октября 2008

Вы можете принудительно отключить базу данных и сбросить соединения с помощью:

EXEC sp_dboption N'yourDatabase', N'offline', N'true'

Или вы можете

ALTER DATABASE [yourDatabase] SET OFFLINE WITH
ROLLBACK AFTER 60 SECONDS

Откат указывает, выполняется ли что-либо. После этого периода они будут откатаны. Так что это обеспечивает некоторую защиту.

Извините, я не думал / читал правильно. Вы можете вернуться в онлайн и сделать резервную копию. Была также статья о переполнении стека в фрагменте T-SQL , предназначенном для отбрасывания всех соединений, а не отключения в автономном режиме: Скрытые возможности SQL Server

14 голосов
/ 19 мая 2009

Я считаю, что это намного быстрее и в целом лучше, чем отключаться. Прочтите об этом в MSDN , чтобы понять предостережения. Если вы используете статистику aysnc, ее тоже необходимо отключить.

-- set single user, terminate connections
ALTER DATABASE [target] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE ...
ALTER DATABASE [target] SET MULTI_USER

«С немедленным откатом» является обязательным условием «прекращения». Оставить это ждет навсегда. Более приятная версия вышеупомянутого дает пользовательским транзакциям несколько секунд для завершения.

ALTER DATABASE [target] SET SINGLE_USER WITH ROLLBACK AFTER 5

Offline - хорошая идея, если вы хотите копировать файлы базы данных, сценарий, который может быть полезен в настольных версиях SQL. Слишком тяжелый для этого сценария. В автономном режиме это было бы предпочтительным. SQL удаляется от sp_dboption .

ALTER DATABASE [target] SET OFFLINE WITH ROLLBACK AFTER 5
8 голосов
/ 08 октября 2008

@ Mattlant - это то, что я искал. Я принес это сюда, так что это в теме.

Use Master
Go

Declare @dbname sysname

Set @dbname = 'name of database you want to drop connections from'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End
2 голосов
/ 08 октября 2008

Пока это работало для меня. Я щелкнул правой кнопкой мыши на базе данных> Задачи> Отделить ...

Это вызвало экран, который позволяет просматривать все активные подключения. Затем вы можете пройти и отключить каждое соединение. Когда вы нажмете «ОК», вы отсоединили базу данных и должны присоединить базу данных. Щелкните правой кнопкой мыши на Базы данных и выберите вложение, выберите файл mdf, и БД прилагается. На этом этапе у вас должен быть эксклюзивный доступ к восстановлению.

Примечание: Я проверил это, подключившись к одной из его баз данных с моего локального компьютера, и с сервера сбросил соединения с моей базой данных, и я не потерял соединение с его базой данных.

1 голос
/ 08 октября 2008

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

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

Затем запустите процесс восстановления.

1 голос
/ 08 октября 2008

Ну, вы можете убить процессы и сеансы SQL с помощью KILL .

Но если вы просто отбросите все его текущие соединения, разве он не откроет их снова?

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

1 голос
/ 08 октября 2008

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

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

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