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

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.


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.

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

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í.


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


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

2

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


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

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.


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.


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;

0

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


0

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

tirar offline

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.