Erro - acesso exclusivo não pôde ser obtido porque o banco de dados está em uso

119

Na verdade, estou tentando fazer um script (no Sql Server 2008) para restaurar um banco de dados de um arquivo de backup. Fiz o seguinte código e estou recebendo um erro -

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.

Como faço para corrigir esse 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
fonte
Se eu conseguir fazer isso funcionar, talvez eu possa fazer um script confiável para restaurar vários bancos de dados de uma pasta. Não consegui encontrar nenhum código confiável na rede. Meu código pode ser confiável porque é gerado pelo próprio SS.
Steam

Respostas:

106

Vou supor que se você está restaurando um banco de dados, não se preocupa com as transações existentes nesse banco de dados. Certo? Em caso afirmativo, isso deve funcionar para você:

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

Agora, um item adicional para ficar atento. Depois de definir o db no modo de usuário único, outra pessoa pode tentar se conectar ao db. Se eles forem bem-sucedidos, você não poderá prosseguir com a restauração. É uma corrida! Minha sugestão é executar todas as três declarações de uma vez.

Dave Mason
fonte
todas as três instruções em uma transação.
Steam
1
Meu SSMS entra no modo sem resposta sempre que tento acessar o banco de dados do AdventureWorks.
Steam
2
Ele realmente quer dizer USE master, não USER master.
assíncrono
7
Basta adicionar ALTER DATABASE [AdventureWorksDW] SET MULTI_USERno final para garantir que o banco de dados volte ao modo multiusuário normal.
gnaanaa,
1
@gnaanaa: Se o banco de dados do backup estava no SINGLE_USERmodo no momento do backup, ele estará no SINGLE_USERmodo quando o backup for restaurado. Se estava no MULTI_USERmodo no momento do backup, estará no MULTI_USERmodo quando for restaurado. Você acertou em cheio: definitivamente vale a pena verificar depois que a restauração for concluída. Você também pode executar RESTORE HEADERONLY na mídia de backup e verificar IsSingleUserou fazer cálculos bit a bit na Flagscoluna.
Dave Mason
236
  1. Defina o caminho para restaurar o arquivo.
  2. Clique em “Opções” no lado esquerdo.
  3. Desmarque a opção "Fazer backup do log final antes de restaurar"
  4. Marque a caixa de seleção - "Fechar conexões existentes ao banco de dados de destino". insira a descrição da imagem aqui
  5. Clique OK.
Vinu M Shankar
fonte
16
No meu caso, essa caixa de seleção estava esmaecida. No entanto, recomecei e consegui marcar a caixa antes de escolher a fonte a partir da qual restaurar. Depois de escolher o arquivo de backup, a opção estava esmaecida novamente, mas a caixa ainda estava marcada e a restauração funcionou.
phansen de
3
Parabéns por me salvar de digitar SQL. O único método GUI entre todas as respostas.
Lionet Chen
Espero que isso tenha funcionado para mim como para os outros. Mas, para mim, a caixa de seleção sempre permaneceu esmaecida. A resposta de Andrei Karchueuski abaixo, abaixo, funcionou para mim.
Devraj Gadhavi
11
Eu também tive que desmarcar "Fazer backup do tail-log antes de restaurar" antes de poder restaurar.
Hylle
3
"Fazer backup do final do log antes de restaurar" também precisa ser desmarcado. Obrigado
jedu de
50

execute esta consulta antes de restaurar o banco de dados:

alter database [YourDBName] 
set offline with rollback immediate

e este depois de restaurar:

  alter database [YourDBName] 
  set online
Andrei Karcheuski
fonte
Acabei mudando para este método por SINGLE_USER depois que a conexão do aplicativo piloto bateu a restauração da minha consulta e a chamada MULTI_USER subsequente. A restauração falhou ao obter acesso exclusivo e o banco de dados antigo foi deixado no modo SINGLE_USER.
Smörgåsbord
3
isso funcionou para mim. e fica online automaticamente assim que você o restaura.
Dileep
3
Isso funciona, e evita a condição de corrida na resposta aceita.
Scott Whitlock
1
Obrigada Andrei.
Erdogan
11

Para mim, a solução é:

  1. Marque Substituir o banco de dados existente (COM REPLACE) na guia optoins do lado esquerdo.

  2. Desmarque todas as outras opções.

  3. Selecione o banco de dados de origem e destino.

  4. Clique OK.

É isso aí.

Aayush Verma
fonte
1
Funcionou para mim também. Tive que desmarcar "Fazer backup do tail-log antes de restaurar" também.
yuva de
7

Use o seguinte script para localizar e eliminar todas as conexões abertas com o banco de dados antes de restaurá-lo.

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 isso ajude ...

Aqeel Haider
fonte
3

Acho que você só precisa definir o db para o modo de usuário único antes de tentar restaurar, como abaixo, apenas certifique-se de que está usando master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
Jason
fonte
2

Acabei de reiniciar o serviço sqlexpress e a restauração foi concluída sem problemas

BabaNew
fonte
o que posso dizer sobre o downvote ... para mim funcionou!
BabaNew
1
OP teve um problema com seu script de restauração porque não levou em consideração o fato de que seu banco de dados já poderia estar em uso. A solução foi atualizar seu script com os comandos adequados, permitindo acesso exclusivo ao BD. Embora reiniciar o serviço possa ter funcionado para você, essa não era a solução apropriada para o problema dele.
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
fonte
1

Solução 1: reinicie os serviços SQL e tente restaurar o banco de dados. Solução 2: reinicie o sistema / servidor e tente restaurar o banco de dados.

Joseph joy
fonte
1

Configurar o banco de dados para o modo de usuário único não funcionou para mim, mas colocá-lo offline e, em seguida, colocá-lo online novamente funcionou. Está no menu do botão direito do banco de dados, em Tarefas.

Certifique-se de marcar a opção 'Eliminar todas as conexões ativas' na caixa de diálogo.

Jeffrey Harmon
fonte
0

Esta é uma maneira de fazer a restauração do banco de dados da produção para o desenvolvimento:

NOTA: Estou fazendo isso por meio do trabalho SSAS para enviar o banco de dados de produção para o desenvolvimento diariamente:

Passo 1: Exclua o backup do dia anterior em desenvolvimento:

declare @sql varchar(1024);

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

Passo 2: Copie o banco de dados de produção para o desenvolvimento:

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

Etapa 3: restaurar executando o script .sql

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

Código que está dentro do arquivo 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;
Não programador
fonte
0

Recebi este erro quando não havia espaço em disco suficiente para restaurar o Db. Limpar um pouco de espaço resolveu.

user3790083
fonte
0

colocar o banco de dados original off-line funcionou para mim

tirar offline

Ali Karaca
fonte