Ao restaurar um backup, como desconecto todas as conexões ativas?

166

Meu SQL Server 2005 não restaura um backup por causa de conexões ativas. Como posso forçá-lo?

Jader Dias
fonte
Deseja sempre eliminar todas as conexões com o banco de dados que deseja "restaurar"? Ou haverá momentos em que você não deseja eliminar as conexões existentes? Além disso, você precisa se preocupar com o pool de conexões?
Philip Kelley

Respostas:

177

SQL Server Management Studio 2005

Quando você clica com o botão direito do mouse em um banco de dados, clica Taskse, em seguida Detach Database, clica em , ele exibe uma caixa de diálogo com as conexões ativas.

Destacar a tela

Ao clicar no hiperlink em "Mensagens", você pode matar as conexões ativas.

Você pode matar essas conexões sem desanexar o banco de dados.

Mais informações aqui .

SQL Server Management Studio 2008

A interface foi alterada para o SQL Server Management studio 2008, eis as etapas (via: Tim Leung )

  1. Clique com o botão direito do mouse no servidor no Pesquisador de Objetos e selecione 'Monitor de Atividade'.
  2. Quando isso abrir, expanda o grupo Processos.
  3. Agora use o menu suspenso para filtrar os resultados pelo nome do banco de dados.
  4. Elimine as conexões do servidor selecionando a opção 'Kill Process' do botão direito.
George Stocker
fonte
21
Se você está tendo o mesmo problema que o @Ryan, provavelmente é porque está usando o Management Studio 2008 (ou superior), em vez do Management Studio 2005. Para fazer a mesma coisa no Management Studio 2008, clique com o botão direito do mouse no servidor em Objeto Explorer e selecione 'Activity Monitor'. Quando isso abrir, expanda o grupo Processos. Agora use o menu suspenso para filtrar os resultados pelo nome do banco de dados. Agora você pode eliminar suas conexões selecionando a opção 'Kill Process' do botão direito.
Tim Leung
195

Você deseja definir seu banco de dados para o modo de usuário único, fazer a restauração e configurá-lo novamente para multiusuário:

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

Referência: Pinal Dave ( http://blog.SQLAuthority.com )

Referência oficial: https://msdn.microsoft.com/en-us/library/ms345598.aspx

brendan
fonte
11
Em vez de emitir um ROLLBACK IMEDIATO, pode ser pertinente apenas ROLLBACK após um ATRASO específico, dando assim às consultas do usuário a oportunidade de concluir naturalmente.
John Sansom
2
Bom ponto, atualizado para a reversão para incluir o comando após 60 para permitir consultas atuais para completar
Brendan
Oi @brendan, e se a reversão demorar mais de 60 segundos? graças
user3583912
11
Se você estiver restaurando um banco de dados, as transações abertas serão perdidas, seja você ROLLBACK IMMEDIATEou ROLLBACK AFTER 60. A única maneira de salvar esses dados é executar outro backup após a reversão. Mas você está restaurando a partir de um backup diferente. Então, qual é o sentido de esperar? Estou esquecendo de algo?
18715 Dave McMillan # 1:
@ DMason, estou curioso sobre esta questão também. O uso do usuário único com o modo de reversão impede novas conexões durante o tempo de espera? Em caso afirmativo, gostaria de saber se é uma maneira mais limpa / agradável de, pelo menos, permitir que as ações somente leitura sejam concluídas em vez de finalizá-las abruptamente?
Jason
43

Esse código funcionou para mim, mata todas as conexões existentes de um banco de dados. Tudo que você precisa fazer é alterar a linha Set @dbname = 'databaseName' para que ele tenha o nome do seu banco de dados.

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

depois disso eu fui capaz de restaurá-lo

RagnaRock
fonte
1
Essa foi a abordagem mais rápida (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson
Não funcionou para mim. O banco de dados ainda está em uso. Eu uso o SQL Server 2008.
Marek Bar
Eu descobri que executar esse código várias vezes, um após o outro, REALMENTE fará o truque. Às vezes, algo se oculta entre o KILL e a restauração. E às vezes você tem que executar a matança ENTÃO a restauração uma após a outra.
John Waclawski
Depende inteiramente da agressividade do aplicativo que tenta se reconectar. Casal de usuários preguiçosos? Funciona bem. Servidor de aplicativos de alto volume que se reconecta em menos de um segundo? Não muito.
BradC
5

Tente o seguinte:

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
fonte
4

Reiniciar o servidor SQL desconectará os usuários. A maneira mais fácil que eu encontrei - boa também se você quiser colocar o servidor offline.

Mas, por algum motivo muito estranho, a opção 'Take Offline' não faz isso de maneira confiável e pode travar ou confundir o console de gerenciamento. Reiniciando e executando trabalhos offline

Às vezes, essa é uma opção - se, por exemplo, você parou um servidor da web que é a fonte das conexões.

Simon_Weaver
fonte
+1. A resposta aceitou a vontade não trabalho para SQL Express (ambiente por exemplo, em um dev) porque SQL Express não tem Activity Monitor
Matt Frear
1
@ MattFrear: Isso não é verdade! Pelo menos em 2008 R2 Express, vejo um botão da barra de ferramentas e uma entrada do menu de contexto no nó do servidor.
Stephan
4
Reiniciar um servidor SQL inteiro eliminará as conexões com todos os bancos de dados. Um servidor pode suportar muitos bancos de dados, mas apenas um precisa ser restaurado agora.
Ross Presser
3
Esta é absolutamente a pior maneira de eliminar conexões com 1 banco de dados. Especialmente se você tiver muitos outros bancos de dados ainda sendo usados ​​por outros usuários. Eu recomendo CONTRA o uso desse método. É 100%, um exagero total !!
John Waclawski
@ JohnWaclawski Eu não sei o pior, mas certamente o mais preguiçoso - é por isso que eu disse algumas vezes. Realmente não economiza tempo em relação a outros métodos, de qualquer maneira #
Simon_Weaver
3

Eu deparei com esse problema ao automatizar um processo de restauração no SQL Server 2008. Minha abordagem (com êxito) foi uma mistura de duas das respostas fornecidas.

Primeiro, eu corro por todas as conexões do referido banco de dados e as mato.

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

Em seguida, defino o banco de dados para o modo single_user

ALTER DATABASE dbName SET SINGLE_USER

Então, eu executo a restauração ...

RESTORE DATABASE and whatnot

Mate as conexões novamente

(same query as above)

E defina o banco de dados novamente para multi_usuário.

ALTER DATABASE dbName SET MULTI_USER

Dessa forma, garanto que não há conexões mantendo o banco de dados antes de definir o modo único, pois o primeiro congelará se houver.

Eric Wu
fonte
2

Nenhuma delas estava funcionando para mim, não foi possível excluir ou desconectar os usuários atuais. Também não foi possível ver nenhuma conexão ativa com o banco de dados. Reiniciar o SQL Server (clique com o botão direito do mouse e selecione Reiniciar) me permitiu fazê-lo.

O codificador
fonte
2

Para adicionar conselhos já fornecidos, se você tiver um aplicativo Web executando o IIS que usa o banco de dados, também poderá ser necessário interromper (não reciclar) o pool de aplicativos para o aplicativo enquanto você restaura e reinicia. A interrupção do pool de aplicativos elimina as conexões http ativas e não permite mais, o que poderia resultar no desencadeamento de processos que se conectam e bloqueiam o banco de dados. Esse é um problema conhecido, por exemplo, com o Umbraco Content Management System ao restaurar seu banco de dados

Chris Halcrow
fonte
1

Nenhuma das opções acima funcionou para mim. Meu banco de dados não mostrou nenhuma conexão ativa usando o Activity Monitor ou sp_who. Eu finalmente tive que:

  • Clique com o botão direito do mouse no nó do banco de dados
  • Selecione "Desanexar ..."
  • Marque a caixa "Drop Connections"
  • Recolocar

Não é a solução mais elegante, mas funciona e não requer a reinicialização do SQL Server (não é uma opção para mim, pois o servidor DB hospedou vários outros bancos de dados)

Brent Waggoner
fonte
Isso é um exagero total. Use o código KILL acima. Funciona em centenas de trabalhos de restauração para mim.
John Waclawski
O banco de dados com o qual eu estava trabalhando não mataria tudo - no entanto, pode ter sido um problema com sua configuração. Concordo que é muito mais fácil em geral.
Brent Wagoner
0

Eu prefiro fazer assim,

alterar o conjunto de banco de dados offline com reversão imediata

e depois restaure seu banco de dados. depois disso,

alterar banco de dados definido on-line com reversão imediata

Aniyan Kolathur
fonte