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

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


person Jader Dias    schedule 20.07.2009    source источник
comment
Вы всегда хотите прервать все соединения с базой данных, которые хотите восстановить? Или будут моменты, когда вы не захотите убивать существующие соединения? Кроме того, вам нужно беспокоиться о пуле соединений?   -  person Philip Kelley    schedule 20.07.2009


Ответы (10)


Студия управления SQL Server 2005

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

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

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

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

Дополнительная информация здесь.

Студия управления SQL Server 2008

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

  1. Щелкните правой кнопкой мыши сервер в обозревателе объектов и выберите «Мониторинг активности».
  2. Когда это откроется, разверните группу «Процессы».
  3. Теперь используйте раскрывающийся список, чтобы отфильтровать результаты по имени базы данных.
  4. Отключите соединения с сервером, выбрав правой кнопкой мыши опцию «Убить процесс».
person George Stocker    schedule 20.07.2009
comment
Если у вас возникла та же проблема, что и у @Ryan, возможно, это связано с тем, что вы используете Management Studio 2008 (или более позднюю версию), а не Management Studio 2005. Чтобы сделать то же самое в Management Studio 2008, щелкните правой кнопкой мыши свой сервер в Object Проводник и выберите «Мониторинг активности». Когда это откроется, разверните группу «Процессы». Теперь используйте раскрывающийся список, чтобы отфильтровать результаты по имени базы данных. Теперь вы можете отключить свои подключения, выбрав правой кнопкой мыши опцию «Убить процесс». - person Tim Leung; 16.03.2012

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

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

person brendan    schedule 20.07.2009
comment
Вместо выдачи IMMEDIATE ROLLBACK может быть уместным только ROLLBACK после указанной DELAY, тем самым давая возможность запросам пользователя выполняться естественным образом. - person John Sansom; 20.07.2009
comment
Хороший момент, обновлен до отката, чтобы включить команду AFTER 60, чтобы разрешить выполнение текущих запросов. - person brendan; 20.07.2009
comment
Привет @brendan, что, если откат занимает более 60 секунд? Благодарность - person user3583912; 22.07.2015
comment
Если вы восстанавливаете базу данных, открытые транзакции будут потеряны независимо от того, ROLLBACK IMMEDIATE вы или ROLLBACK AFTER 60. Единственный способ сохранить эти данные — выполнить еще одну резервную копию после отката. Но вы восстанавливаетесь из другой резервной копии. Так какой смысл ждать? Я что-то упускаю? - person Dave Mason; 13.11.2015
comment
@DMason, мне тоже интересен этот вопрос. Предотвращает ли использование single_user с режимом отката новые подключения во время ожидания? Если это так, мне интересно, является ли это более чистым/приятным способом, по крайней мере, разрешить выполнение действий только для чтения, а не резко их завершать? - person Jason; 08.02.2018
comment
Для новичка в однопользовательском режиме (как я) это помогает сделать это, когда база данных, которую вы пытаетесь создать резервную копию, не является той, которую вы установили активной. Установите для активной базы данных значение Master перед выполнением этих команд, и вы будете золотыми... - person DaveN59; 03.06.2019

У меня этот код сработал, он убивает все существующие соединения базы данных. Все, что вам нужно сделать, это изменить строку 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

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

person RagnaRock    schedule 31.05.2012
comment
Это был самый быстрый подход (SingleUserMode * 20 = 60 с, Kill * 20 = 5 с). - person Karson; 26.05.2015
comment
Это не сработало для меня. База данных все еще используется. Я использую SQL Server 2008. - person Marek Bar; 13.11.2015
comment
Я обнаружил, что запуск этого кода несколько раз, один за другим, В КОНЕЧНОМ случае добьется цели. Иногда что-то проскальзывает между вашим KILL и Restore. И иногда вам нужно запускать kill ПОТОМ восстановление одно за другим. - person John Waclawski; 20.10.2016
comment
Полностью зависит от агрессивности приложения, пытающегося переподключиться. Пара ленивых пользователей? Работает отлично. Сервер приложений большого объема, который повторно подключается менее чем за секунду? Не так много. - person BradC; 14.04.2017

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

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
person user2276214    schedule 12.04.2013

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

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

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

person Simon_Weaver    schedule 11.04.2010
comment
+1. Принятый ответ не будет работать для SQL Express (например, в среде разработки), поскольку SQL Express не имеет монитора активности. - person Matt Frear; 18.01.2011
comment
@MattFrear: Это неправда! По крайней мере, в 2008 R2 Express я вижу кнопку панели инструментов и пункт контекстного меню на узле сервера. - person Stephan; 14.05.2012
comment
Перезапуск всего SQL-сервера приведет к разрыву соединений со всеми базами данных. Сервер может поддерживать множество баз данных, но сейчас нужно восстановить только одну. - person Ross Presser; 07.12.2015
comment
Это абсолютно худший способ убить соединения с 1 базой данных. Особенно, если у вас есть много других баз данных, которые все еще используются другими пользователями. Я настоятельно НЕ СОВЕТУЮ использовать этот метод. Это 100%, полный перебор!! - person John Waclawski; 20.10.2016
comment
@JohnWaclawski Я не знаю о худшем, но определенно о самом ленивом - поэтому я иногда и говорил. В любом случае, это не экономит время по сравнению с другими методами. - person Simon_Weaver; 20.10.2016

Я столкнулся с этой проблемой при автоматизации процесса восстановления в 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

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

person Eric Wu    schedule 05.10.2016

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

person The Coder    schedule 01.05.2012

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

person Chris Halcrow    schedule 31.07.2013

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

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

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

person Brent Waggoner    schedule 27.01.2016
comment
Это вообще перебор. Используйте код KILL выше. Работает на сотнях заданий восстановления для меня. - person John Waclawski; 20.10.2016
comment
База данных, с которой я работал, не могла УБИТЬ все, однако, возможно, это была проблема с их настройкой. Я согласен, что это намного проще в целом. - person Brent Waggoner; 20.10.2016

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

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

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

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

person Aniyan Kolathur    schedule 04.04.2019