Al restaurar una copia de seguridad, ¿cómo desconecto todas las conexiones activas?


166

Mi SQL Server 2005 no restaura una copia de seguridad debido a conexiones activas. ¿Cómo puedo forzarlo?


¿ Siempre desea eliminar todas las conexiones a la base de datos que desea "restaurar"? ¿O habrá ocasiones en las que no querrás eliminar las conexiones existentes? Además, ¿tiene que preocuparse por la agrupación de conexiones?
Philip Kelley el

Respuestas:


177

SQL Server Management Studio 2005

Cuando hace clic derecho en una base de datos y hace clic Tasksy luego hace clic Detach Database, aparece un cuadro de diálogo con las conexiones activas.

Separar pantalla

Al hacer clic en el hipervínculo debajo de "Mensajes" puede eliminar las conexiones activas.

Luego puede eliminar esas conexiones sin separar la base de datos.

Más información aquí .

SQL Server Management Studio 2008

La interfaz ha cambiado para SQL Server Management Studio 2008, estos son los pasos (a través de: Tim Leung )

  1. Haga clic derecho en el servidor en el Explorador de objetos y seleccione 'Monitor de actividad'.
  2. Cuando esto se abra, expanda el grupo Procesos.
  3. Ahora use el menú desplegable para filtrar los resultados por nombre de base de datos.
  4. Elimine las conexiones del servidor seleccionando la opción del botón derecho 'Eliminar proceso'.

21
Si tiene el mismo problema que @Ryan, probablemente sea porque está usando Management Studio 2008 (o superior), en lugar de Management Studio 2005. Para hacer lo mismo en Management Studio 2008, haga clic con el botón derecho en su servidor en Object Explorador y seleccione 'Monitor de actividad'. Cuando esto se abra, expanda el grupo Procesos. Ahora use el menú desplegable para filtrar los resultados por nombre de base de datos. Ahora puede eliminar sus conexiones seleccionando la opción 'Eliminar proceso' con el botón derecho.
Tim Leung

195

Desea configurar su base de datos en modo de usuario único, realice la restauración y luego vuelva a configurarla en multiusuario:

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

Referencia: Pinal Dave ( http://blog.SQLAuthority.com )

Referencia oficial: https://msdn.microsoft.com/en-us/library/ms345598.aspx


11
En lugar de emitir un ROLLBACK INMEDIATO, puede ser pertinente solo ROLLBACK después de un RETARDO específico, lo que brinda a las consultas de los usuarios la oportunidad de completar de forma natural.
John Sansom el

2
Buen punto, actualizado a la reversión de incluir el comando después de 60 para permitir consultas actuales para completar
Brendan

Hola @brendan, ¿qué pasa si la reversión demora más de 60 segundos? gracias
user3583912

11
Si está restaurando una base de datos, las transacciones abiertas se perderán si usted ROLLBACK IMMEDIATEo ROLLBACK AFTER 60. La única forma de guardar esos datos es realizar otra copia de seguridad después de la reversión. Pero está restaurando desde una copia de seguridad diferente. Entonces, ¿qué sentido tiene esperar? ¿Me estoy perdiendo de algo?
Dave Mason

@DMason, también tengo curiosidad por esta pregunta. ¿El uso de single_user con modo de reversión impide nuevas conexiones durante el tiempo de espera? Si es así, me pregunto si es una forma más limpia / agradable de al menos dejar que las acciones de solo lectura se completen en lugar de terminarlas abruptamente.
Jason

43

Este código funcionó para mí, mata todas las conexiones existentes de una base de datos. Todo lo que tiene que hacer es cambiar la línea Set @dbname = 'databaseName' para que tenga el nombre de su base de datos.

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

después de esto pude restaurarlo


1
Este fue el enfoque más rápido (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson

A mi no me sirvió. La base de datos todavía está en uso. Uso SQL Server 2008.
Marek Bar

He encontrado que ejecutar ese código varias veces, uno después del otro, EVENTUALMENTE hará el truco. A veces algo se cuela entre tu KILL y la restauración. Y a veces tienes que ejecutar el kill LUEGO la restauración uno tras otro.
John Waclawski

Depende completamente de la agresividad de la aplicación que intenta reconectarse. ¿Un par de usuarios perezosos? Funciona genial. ¿Servidor de aplicaciones de alto volumen que se vuelve a conectar en menos de un segundo? No tanto.
BradC

5

Prueba esto:

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

4

Reiniciar el servidor SQL desconectará a los usuarios. La forma más fácil que he encontrado, también es bueno si quieres desconectar el servidor.

Pero por alguna extraña razón, la opción 'Desconectar' no lo hace de manera confiable y puede colgar o confundir la consola de administración. Reiniciar y luego desconectar trabajos

A veces, esta es una opción, si, por ejemplo, ha detenido un servidor web que es la fuente de las conexiones.


+1. La respuesta aceptada no funcionará para SQL Express (por ejemplo, en un entorno de desarrollo) porque SQL Express no tiene Monitor de actividad
Matt Frear

1
@MattFrear: ¡Esto no es cierto! Al menos en 2008 R2 Express veo un botón de barra de herramientas y una entrada de menú contextual en el nodo del servidor.
Stephan

44
Reiniciar un servidor SQL completo eliminará las conexiones a todas las bases de datos. Un servidor puede admitir muchas bases de datos, pero solo una necesita ser restaurada ahora.
Ross Presser

3
Esta es absolutamente la peor forma de eliminar conexiones a 1 base de datos. Especialmente si tiene muchas otras bases de datos que todavía están siendo utilizadas por otros usuarios. Recomiendo encarecidamente CONTRA el uso de este método. ¡Es 100%, exageración total!
John Waclawski

@JohnWaclawski No sé sobre lo peor, pero ciertamente lo más flojo, por eso dije a veces En realidad, no guarda ningún momento sobre otros métodos de todos modos
Simon_Weaver

3

Me encontré con este problema mientras automatizaba un proceso de restauración en SQL Server 2008. Mi enfoque (exitoso) fue una combinación de dos de las respuestas proporcionadas.

Primero, me encuentro con todas las conexiones de dicha base de datos y las elimino.

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

Luego, configuro la base de datos en modo de usuario único

ALTER DATABASE dbName SET SINGLE_USER

Entonces, ejecuto la restauración ...

RESTORE DATABASE and whatnot

Mata las conexiones de nuevo

(same query as above)

Y vuelva a configurar la base de datos en multi_user.

ALTER DATABASE dbName SET MULTI_USER

De esta manera, me aseguro de que no haya conexiones que detengan la base de datos antes de configurarla en modo único, ya que la primera se congelará si la hay.


2

Ninguno de estos funcionaba para mí, no podía eliminar ni desconectar a los usuarios actuales. Tampoco pude ver ninguna conexión activa a la base de datos. Reiniciar SQL Server (haga clic derecho y seleccione Reiniciar) me permitió hacerlo.


2

Para agregar a los consejos ya dados, si tiene una aplicación web que se ejecuta a través de IIS que usa la base de datos, es posible que también deba detener (no reciclar) el grupo de aplicaciones para la aplicación mientras restaura, luego reinicie. La detención del grupo de aplicaciones elimina las conexiones http activas y no permite más, lo que de otro modo podría terminar permitiendo que se activen procesos que se conectan y, por lo tanto, bloquean la base de datos. Este es un problema conocido, por ejemplo, con el sistema de gestión de contenido Umbraco al restaurar su base de datos


1

Nada de lo anterior funcionó para mí. Mi base de datos no mostró ninguna conexión activa usando Activity Monitor o sp_who. Finalmente tuve que:

  • Haga clic derecho en el nodo de la base de datos
  • Seleccione "Separar ..."
  • Marque la casilla "Desconectar conexiones"
  • Vuelva a colocar

No es la solución más elegante, pero funciona y no requiere reiniciar SQL Server (no es una opción para mí, ya que el servidor DB alojó un montón de otras bases de datos)


Esto es una exageración total. Use el código KILL de arriba. Trabaja en cientos de trabajos de restauración para mí.
John Waclawski

La base de datos con la que estaba trabajando no MATARÍA todo, sin embargo, puede haber sido un problema con su configuración. Estoy de acuerdo que es mucho más fácil en general.
Brent Waggoner

0

Prefiero hacer así

alterar la base de datos establecida sin conexión con reversión inmediata

y luego restaure su base de datos. después de esto,

alterar la base de datos establecida en línea con reversión inmediata

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.