Error: no se pudo obtener acceso exclusivo porque la base de datos está en uso

119

De hecho, estoy tratando de hacer un script (en Sql Server 2008) para restaurar una base de datos desde un archivo de respaldo. Hice el siguiente código y recibo un error:

Msg 3101, Level 16, State 1, Line 3
Exclusive access could not be obtained because 
the database is in use.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.

¿Cómo soluciono este problema?

IF DB_ID('AdventureWorksDW') IS NOT NULL 
BEGIN 
RESTORE DATABASE [AdventureWorksDW] 
FILE = N'AdventureWorksDW_Data' 
FROM  
DISK = N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\Backup\AdventureWorksDW.bak' 
WITH  FILE = 1, 
MOVE N'AdventureWorksDW_Data' 
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW.mdf', 
MOVE N'AdventureWorksDW_Log'  
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW_0.LDF', 
NOUNLOAD,  STATS = 10 
END
Vapor
fuente
Si puedo hacer que esto funcione, tal vez pueda crear un script confiable para restaurar múltiples bases de datos desde una carpeta. No pude encontrar ningún código confiable en la red. Mi código puede ser confiable porque lo genera el propio SS.
Steam

Respuestas:

106

Asumiré que si está restaurando una base de datos, no le importan las transacciones existentes en esa base de datos. ¿Correcto? Si es así, esto debería funcionar para usted:

USE master
GO

ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO

RESTORE DATABASE AdventureWorksDW
FROM ...
...
GO

Ahora, un elemento adicional a tener en cuenta. Después de configurar la base de datos en modo de usuario único, otra persona puede intentar conectarse a la base de datos. Si tienen éxito, no podrá continuar con la restauración. ¡Es una carrera! Mi sugerencia es ejecutar las tres declaraciones a la vez.

Dave Mason
fuente
los tres estados de cuenta en una transacción.
Steam
1
Mi SSMS entra en modo no responde cada vez que intento acceder a esa base de datos de Adventureworks.
Steam
2
Él realmente quiere decir USE master, no USER master.
async
7
Simplemente agregue ALTER DATABASE [AdventureWorksDW] SET MULTI_USERal final para asegurarse de que la base de datos vuelva al modo multiusuario normal.
gnaanaa
1
@gnaanaa: Si la base de datos respaldada estaba en SINGLE_USERmodo en el momento de la copia de seguridad, estará en SINGLE_USERmodo cuando se restaure la copia de seguridad. Si estaba en MULTI_USERmodo en el momento de la copia de seguridad, estará en MULTI_USERmodo cuando se restaure. Tiene un gran punto: definitivamente vale la pena verificarlo una vez finalizada la restauración. También puede ejecutar RESTORE HEADERONLY en el medio de respaldo y verificar IsSingleUsero hacer cálculos matemáticos bit a bit en la Flagscolumna.
Dave Mason
236
  1. Establezca la ruta para restaurar el archivo.
  2. Haga clic en "Opciones" en el lado izquierdo.
  3. Desmarque "Realizar copia de seguridad del registro final antes de restaurar"
  4. Marque la casilla de verificación - "Cerrar las conexiones existentes a la base de datos de destino". ingrese la descripción de la imagen aquí
  5. Haga clic en Aceptar.
Vinu M Shankar
fuente
16
En mi caso, esa casilla de verificación estaba atenuada. Sin embargo, comencé de nuevo y pude marcar la casilla antes de elegir la fuente desde la que restaurar. Después de elegir el archivo de respaldo, la opción estaba en gris nuevamente, pero la casilla aún estaba marcada y la restauración funcionó.
phansen
3
Felicitaciones por salvarme de escribir SQL. El único método GUI entre todas las respuestas.
Lionet Chen
Espero que esto me hubiera funcionado como a otros. Pero para mí, la casilla de verificación siempre permaneció en gris. La respuesta de Andrei Karchueuski a continuación a continuación, funcionó para mí.
Devraj Gadhavi
11
También tuve que desmarcar "Realizar copia de seguridad del registro final antes de restaurar" antes de poder restaurar.
Hylle
3
"Realizar copia de seguridad del registro de cola antes de restaurar" también debe desmarcarse. Gracias
jedu
50

ejecute esta consulta antes de restaurar la base de datos:

alter database [YourDBName] 
set offline with rollback immediate

y este después de restaurar:

  alter database [YourDBName] 
  set online
Andrei Karcheuski
fuente
Terminé cambiando a este método sobre SINGLE_USER después de que la conexión de la aplicación piloto superó la restauración de mi consulta y la posterior llamada MULTI_USER. La restauración no pudo obtener acceso exclusivo y la antigua base de datos se dejó en modo SINGLE_USER.
Smörgåsbord
3
esto funcionó para mí. y se conecta automáticamente una vez que lo restaura.
Dileep
3
Esto funciona y evita la condición de carrera en la respuesta aceptada.
Scott Whitlock
1
Gracias Andrei.
Erdogan
11

Para mi la solución es:

  1. Marque Sobrescribir la base de datos existente (CON REEMPLAZAR) en la pestaña de opciones en el lado izquierdo.

  2. Desmarque todas las demás opciones.

  3. Seleccione la base de datos de origen y destino.

  4. Haga clic en Aceptar.

Eso es.

Aayush Verma
fuente
1
Me funcionó a mi también. También tuve que desmarcar "Realizar copia de seguridad del registro de cola antes de restaurar".
Yuva
7

Utilice el siguiente script para buscar y eliminar todas las conexiones abiertas a la base de datos antes de restaurar la base de datos.

declare @sql as varchar(20), @spid as int

select @spid = min(spid)  from master..sysprocesses  where dbid = db_id('<database_name>') 
and spid != @@spid    

while (@spid is not null)
begin
    print 'Killing process ' + cast(@spid as varchar) + ' ...'
    set @sql = 'kill ' + cast(@spid as varchar)
    exec (@sql)

    select 
        @spid = min(spid)  
    from 
        master..sysprocesses  
    where 
        dbid = db_id('<database_name>') 
        and spid != @@spid
end 

print 'Process completed...'

Espero que esto ayude ...

Aqeel Haider
fuente
3

Creo que solo necesita configurar la base de datos en modo de usuario único antes de intentar restaurar, como se muestra a continuación, solo asegúrese de estar usando master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
Jason
fuente
2

Acabo de reiniciar el servicio sqlexpress y luego la restauración se completó bien

BabaNuevo
fuente
¿Qué puedo decir sobre el voto negativo ... para mí funcionó!
BabaNew
1
OP tuvo un problema con su script de restauración porque no tuvo en cuenta el hecho de que su base de datos podría estar ya en uso. La solución fue actualizar su script con los comandos adecuados que le permitieran tener acceso exclusivo a la base de datos. Si bien reiniciar el servicio podría haber funcionado para usted, esa no era la solución adecuada a su problema.
PL
1
Use Master
alter database databasename set offline with rollback immediate;

--Do Actual Restore
RESTORE DATABASE databasename
FROM DISK = 'path of bak file'
WITH MOVE 'datafile_data' TO 'D:\newDATA\data.mdf',
MOVE 'logfile_Log' TO 'D:\newDATA\DATA_log.ldf',replace

alter database databasename set online with rollback immediate;
GO
Puneeth
fuente
1

Solución 1: reinicie los servicios SQL e intente restaurar la base de datos Solución 2: reinicie el sistema / servidor e intente restaurar la base de datos Solución 3: recupere la base de datos actual, elimine la base de datos actual / de destino e intente restaurar la base de datos.

Joseph Joy
fuente
1

Configurar la base de datos en modo de usuario único no funcionó para mí, pero desconectarlo y luego volverlo a conectar sí funcionó. Está en el menú contextual de la base de datos, en Tareas.

Asegúrese de marcar la opción 'Eliminar todas las conexiones activas' en el cuadro de diálogo.

Jeffrey Harmon
fuente
0

He aquí una forma en que estoy restaurando la base de datos desde la producción hasta el desarrollo:

NOTA: Lo estoy haciendo a través del trabajo SSAS para impulsar la base de datos de producción al desarrollo a diario:

Paso 1: eliminar la copia de seguridad del día anterior en desarrollo:

declare @sql varchar(1024);

set @sql = 'DEL C:\ProdAEandAEXdataBACKUP\AE11.bak'
exec master..xp_cmdshell @sql

Paso 2: copiar la base de datos de producción al desarrollo:

declare @cmdstring varchar(1000)
set @cmdstring = 'copy \\Share\SQLDBBackup\AE11.bak C:\ProdAEandAEXdataBACKUP'
exec master..xp_cmdshell @cmdstring 

Paso 3: Restaurar ejecutando .sql script

SQLCMD -E -S dev-erpdata1 -b -i "C:\ProdAEandAEXdataBACKUP\AE11_Restore.sql"

Código que se encuentra dentro del archivo AE11_Restore.sql:

RESTORE DATABASE AE11
FROM DISK = N'C:\ProdAEandAEXdataBACKUP\AE11.bak'
WITH MOVE 'AE11' TO 'E:\SQL_DATA\AE11.mdf',
MOVE 'AE11_log' TO 'D:\SQL_LOGS\AE11.ldf',
RECOVERY;
No programador
fuente
0

Recibí este error cuando no había suficiente espacio en disco para restaurar Db. Limpiar algo de espacio lo solucionó.

usuario3790083
fuente
0

llevar la base de datos original a fuera de línea funcionó para mí

desconectar

Ali Karaca
fuente