При восстановлении резервной копии, как отключить все активные подключения?

166

Мой SQL Server 2005 не восстанавливает резервную копию из-за активных подключений. Как я могу заставить это?

Джадер Диас
источник
Вы всегда хотите уничтожить все соединения с базой данных, которые вы хотите «восстановить заново»? Или будут моменты, когда вы не захотите уничтожать существующие соединения? Кроме того, вам нужно беспокоиться о пуле подключений?
Филип Келли

Ответы:

177

SQL Server Management Studio 2005

Когда вы щелкаете правой кнопкой мыши по базе данных, Tasksзатем щелкаете Detach Database, а затем щелкаете , открывается диалоговое окно с активными соединениями.

Отсоединить экран

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

Затем вы можете уничтожить эти соединения, не отключая базу данных.

Больше информации здесь .

SQL Server Management Studio 2008

Интерфейс изменился для SQL Server Management Studio 2008, вот шаги (через: Тим Леунг )

  1. Щелкните правой кнопкой мыши сервер в обозревателе объектов и выберите «Монитор активности».
  2. Когда это откроется, разверните группу Процессы.
  3. Теперь используйте выпадающий список для фильтрации результатов по имени базы данных.
  4. Завершите соединение с сервером, выбрав правую кнопку мыши «Kill Process».
Джордж Стокер
источник
21
Если у вас та же проблема, что и у @Ryan, возможно, это связано с тем, что вы используете Management Studio 2008 (или выше), а не Management Studio 2005. Чтобы сделать то же самое в Management Studio 2008, щелкните правой кнопкой мыши свой сервер в Object Исследуйте и выберите «Монитор активности». Когда это откроется, разверните группу Процессы. Теперь используйте выпадающий список для фильтрации результатов по имени базы данных. Теперь вы можете отключить ваши соединения, выбрав опцию «Kill Process», щелкнув правой кнопкой мыши.
Тим Леунг
195

Вы хотите установить db в однопользовательский режим, выполнить восстановление, а затем установить его обратно в многопользовательский режим:

ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK AFTER 60 --this will give your current connections 60 seconds to complete

--Do Actual Restore
RESTORE DATABASE YourDB
FROM DISK = 'D:\BackUp\YourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:\Data\YourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:\Data\YourLDFFile.ldf'

/*If there is no error in statement before database will be in multiuser
mode.  If error occurs please execute following command it will convert
database in multi user.*/
ALTER DATABASE YourDB SET MULTI_USER
GO

Ссылка: Пинал Дэйв ( http://blog.SQLAuthority.com )

Официальная ссылка: https://msdn.microsoft.com/en-us/library/ms345598.aspx

Brendan
источник
11
Вместо выдачи НЕМЕДЛЕННОГО ROLLBACK может быть уместно только ROLLBACK после определенного ЗАДЕРЖКИ, тем самым предоставляя пользователю возможность для естественного завершения.
Джон Сэнсом
2
Хороший вопрос, добавлен откат для включения команды AFTER 60, позволяющей завершать текущие запросы
brendan
Привет @brendan, что если откат займет более 60 секунд? спасибо
user3583912
11
Если вы восстанавливаете базу данных, открытые транзакции будут потеряны, как у вас, так ROLLBACK IMMEDIATEи у вас ROLLBACK AFTER 60. Единственный способ сохранить эти данные - выполнить другое резервное копирование после отката. Но вы восстанавливаете из другой резервной копии. Итак, какой смысл ждать? Я что-то упускаю?
Дейв Мейсон
@DMason, мне тоже интересно этот вопрос. Предотвращает ли использование single_user с режимом отката новые подключения во время ожидания? Если так, то мне интересно, если это более чистый / приятный способ, по крайней мере, позволить завершить действия, доступные только для чтения, а не завершать их внезапно?
Джейсон
43

Этот код работал для меня, он убивает все существующие соединения базы данных. Все, что вам нужно сделать, это изменить строку Set @dbname = 'databaseName', чтобы она имела имя вашей базы данных.

Use Master
Go

Declare @dbname sysname

Set @dbname = 'databaseName'

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

после этого я смог его восстановить

Ragnarock
источник
1
Это был самый быстрый подход (SingleUserMode * 20 = 60 с, Kill * 20 = 5 с).
Карсон
Это не сработало для меня. База данных все еще используется. Я использую SQL Server 2008.
Марек Бар
Я обнаружил, что запуск этого кода несколько раз, один за другим, ВСЕГДА сделает свое дело. Иногда что-то пробирается между твоим УБИЙСТВОМ и восстановлением. И иногда вам нужно запустить убить ТО реставрацию один за другим.
Джон Вацлавский
Полностью зависит от агрессивности приложения, пытающегося восстановить соединение. Пара ленивых пользователей? Прекрасно работает. Сервер приложений большого объема, который подключается менее чем за секунду? Не так много.
BradC
5

Попробуй это:

DECLARE UserCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
    spid
FROM
    master.dbo.sysprocesses
WHERE DB_NAME(dbid) = 'dbname'--replace the dbname with your database
DECLARE @spid SMALLINT
DECLARE @SQLCommand VARCHAR(300)
OPEN UserCursor
FETCH NEXT FROM UserCursor INTO
    @spid
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQLCommand = 'KILL ' + CAST(@spid AS VARCHAR)
    EXECUTE(@SQLCommand)
    FETCH NEXT FROM UserCursor INTO
        @spid
END
CLOSE UserCursor
DEALLOCATE UserCursor
GO
user2276214
источник
4

Перезапуск сервера SQL отключит пользователей. Самый простой способ, который я нашел - хорошо, если вы хотите отключить сервер.

Но по какой-то очень странной причине опция «Отключить» делает это ненадежно и может повредить или запутать консоль управления. Перезапуск, а затем работает в автономном режиме

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

Simon_Weaver
источник
+1. Принятый ответ не будет работать для SQL Express (например, в среде разработчиков), потому что в SQL Express нет Activity Monitor
Мэтт Фреар,
1
@MattFrear: Это не правда! По крайней мере, в 2008 R2 Express я вижу кнопку на панели инструментов и пункт контекстного меню на узле сервера.
Стефан
4
Перезапуск всего SQL-сервера уничтожит соединения со всеми базами данных. Сервер может поддерживать множество баз данных, но сейчас нужно восстановить только одну.
Росс Прессер
3
Это абсолютно худший способ уничтожить соединения с 1 базой данных. Особенно, если у вас есть много других баз данных, которые все еще используются другими пользователями. Я настоятельно рекомендую ПРОТИВ использования этого метода. Это 100%, полный перебор!
Джон Вацлавски
@JohnWaclawski Я не знаю о худшем, но, конечно, ленивый - вот почему я иногда говорил. В любом случае это не экономит время по сравнению с другими методами
Simon_Weaver
3

Я столкнулся с этой проблемой при автоматизации процесса восстановления в SQL Server 2008. Мой (успешный) подход представлял собой сочетание двух предоставленных ответов.

Сначала я запускаю все соединения указанной базы данных и убиваю их.

DECLARE @SPID int = (SELECT TOP 1 SPID FROM sys.sysprocess WHERE dbid = db_id('dbName'))
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = top 1 spid from master.dbo.sysprocesses
        where dbid = db_id('dbName')
End

Затем я установил базу данных в режим single_user

ALTER DATABASE dbName SET SINGLE_USER

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

RESTORE DATABASE and whatnot

Убей соединения снова

(same query as above)

И установите базу данных обратно в multi_user.

ALTER DATABASE dbName SET MULTI_USER

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

Эрик Ву
источник
2

Ни один из них не работал для меня, не мог удалить или отключить текущих пользователей. Также не видел активных подключений к БД. Перезапуск SQL Server (щелкните правой кнопкой мыши и выберите «Перезагрузить») позволил мне это сделать.

Кодер
источник
2

В дополнение к уже предоставленному совету, если у вас есть веб-приложение, работающее через IIS, использующее БД, вам также может понадобиться остановить (не перезапускать) пул приложений для приложения во время восстановления, а затем перезапустить. Остановка пула приложений убивает активные http-соединения и не позволяет больше, что в противном случае могло бы привести к запуску процессов, которые подключаются к базе данных и тем самым блокируют ее. Это известная проблема, например, с системой управления контентом Umbraco при восстановлении базы данных.

Крис Хэлкроу
источник
1

Ничто из вышеперечисленного не помогло мне. В моей базе данных не было активных соединений с использованием Activity Monitor или sp_who. В конечном итоге мне пришлось:

  • Щелкните правой кнопкой мыши узел базы данных
  • Выберите «Отделить ...»
  • Установите флажок «Отключить соединения»
  • Присоедините

Не самое элегантное решение, но оно работает и не требует перезапуска SQL Server (для меня это не вариант, поскольку на сервере БД размещалась куча других баз данных)

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

Я предпочитаю делать так,

изменить базу данных в автономном режиме с немедленным откатом

а затем восстановить вашу базу данных. после этого,

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

Аниян Колатур
источник