Как уничтожить все текущие соединения с базой данных SQL Server 2005?

StackOverflow https://stackoverflow.com/questions/11620

  •  08-06-2019
  •  | 
  •  

Вопрос

Я хочу переименовать базу данных, но постоянно получаю сообщение об ошибке «не удалось получить эксклюзивную блокировку» базы данных, что означает, что некоторые соединения все еще активны.

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

Это было полезно?

Решение

Видеть Уничтожить все активные подключения к базе данных.

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

-- set your current connection to use master otherwise you might get an error

use master
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE 

--do you stuff here 

ALTER DATABASE YourDatabase SET MULTI_USER

Другие советы

Для этого в сценарии замените «DB_NAME» на базу данных, чтобы уничтожить все соединения с:

USE master
GO

SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''

Set @DBName = 'DB_NAME'
IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)

IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END

Убей его, и убей его огнем:

USE master
go

DECLARE @dbname sysname
SET @dbname = 'yourdbname'

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

Использование SQL Management Studio Express:

В дереве обозревателя объектов разверните раздел «Управление» до «Монитор активности» (если вы не можете его там найти, щелкните правой кнопкой мыши сервер базы данных и выберите «Монитор активности»).Открыв Монитор активности, вы можете просмотреть всю информацию о процессе.Вы сможете найти блокировки для интересующей вас базы данных и снять эти блокировки, что также приведет к разрыву соединения.

После этого вы сможете переименовать.

Я всегда использовал:


ALTER DATABASE DB_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
GO 
SP_RENAMEDB 'DB_NAME','DB_NAME_NEW'
Go 
ALTER DATABASE DB_NAME_NEW  SET MULTI_USER -- set back to multi user 
GO 
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE

ALTER DATABASE [Test]
SET ONLINE

Работа в автономном режиме занимает некоторое время, и иногда у меня возникают с этим проблемы.

Самый надежный способ, на мой взгляд:

ОтсоединитьЩелкните правой кнопкой мыши БД -> Задачи -> Отсоединить...Проверьте "Drop Connections" ОК

Присоединить сноваЩелкните правой кнопкой мыши Базы данных -> Прикрепить..Добавлять...-> выберите свою базу данных и измените столбец «Прикрепить как» на желаемое имя базы данных.Хорошо

Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'

Declare @query nvarchar(max)
--Select * from #temp
Select @query =STUFF((                              
            select '  ' + KillCommand from #temp
            FOR XML PATH('')),1,1,'') 
Execute sp_executesql @query 
Drop table #temp

используйте базу данных «master» и запустите этот запрос, он уничтожит все активные соединения из вашей базы данных.

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

В MS SQL Server Management Studio в обозревателе объектов щелкните правой кнопкой мыши базу данных.В появившемся контекстном меню выберите «Задачи -> Перейти в автономный режим».

Другой подход «убить огнем» — просто перезапустить службу MSSQLSERVER.Мне нравится делать что-то из командной строки.Вставка этого точно в CMD сделает это:NET STOP MSSQLSERVER и NET START MSSQLSERVER

Или откройте «services.msc», найдите «SQL Server (MSSQLSERVER)», щелкните правой кнопкой мыши и выберите «перезапустить».

Это «наверняка, наверняка» уничтожит ВСЕ соединения со ВСЕМИ базами данных, работающими на этом экземпляре.

(Мне это нравится больше, чем многие подходы, которые меняют и возвращают конфигурацию на сервере/базе данных)

Вот как можно надежно реализовать подобные вещи в MS SQL Server Management Studio 2008 (может работать и для других версий):

  1. В дереве обозревателя объектов щелкните правой кнопкой мыши корневой сервер базы данных (с зеленой стрелкой), затем щелкните Монитор активности.
  2. Откройте вкладку «Процессы» в мониторе активности, выберите раскрывающееся меню «базы данных» и отфильтруйте нужную базу данных.
  3. Щелкните правой кнопкой мыши БД в обозревателе объектов и запустите задачу «Задачи -> Перейти в автономный режим».Оставьте это работать в фоновом режиме, пока вы...
  4. Безопасно отключите все, что можете.
  5. Убейте все оставшиеся процессы на вкладке процессов.
  6. Верните БД в режим онлайн.
  7. Переименуйте БД.
  8. Верните свой сервис в режим онлайн и направьте его на новую БД.

Вариант, работающий для меня в этом сценарии, следующий:

  1. Запустите операцию «Отсоединить» для рассматриваемой базы данных.Откроется окно (в SQL 2005), отображающее активные соединения, которые предотвращают действия с БД.
  2. Уничтожьте активные соединения, отмените операцию отсоединения.
  3. Теперь база данных должна быть доступна для восстановления.

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

ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

Щелкните правой кнопкой мыши имя базы данных, выберите «Свойство», чтобы открыть окно свойств, откройте вкладку «Параметры» и измените свойство «Ограничить доступ» с «Многопользовательский» на «Однопользовательский».Когда вы нажмете кнопку «ОК», вам будет предложено закрыть все открытые соединения, выберите «Да», и вы сможете переименовать базу данных....

У меня это не сработало (SQL2008 Enterprise), я также не видел ни запущенных процессов, ни пользователей, подключенных к БД.Перезапуск сервера (щелкните правой кнопкой мыши по Sql Server в Management Studio и выберите «Перезапустить») позволил мне восстановить БД.

Я использую SQL Server 2008 R2, моя БД уже была настроена для одного пользователя, и было соединение, которое ограничивало любые действия с базой данных.Таким образом, рекомендуемый SQLMenace's решение ответило ошибкой. Вот тот, который сработал в моем случае.

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

declare @proc table(
    SPID bigint,
    Status nvarchar(255),
    Login nvarchar(255),
    HostName nvarchar(255),
    BlkBy nvarchar(255),
    DBName nvarchar(255),
    Command nvarchar(MAX),
    CPUTime bigint,
    DiskIO bigint,
    LastBatch nvarchar(255),
    ProgramName nvarchar(255),
    SPID2 bigint,
    REQUESTID bigint
)

insert into @proc
exec sp_who2

select  *, KillCommand = concat('kill ', SPID, ';')
from    @proc

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

SPID    KillCommand
26      kill 26;
27      kill 27;
28      kill 28;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top