SQL Server: banco de dados bloqueado no estado "Restaurando"

564

Eu fiz backup de um banco de dados:

BACKUP DATABASE MyDatabase
TO DISK = 'MyDatabase.bak'
WITH INIT --overwrite existing

E então tentou restaurá-lo:

RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE --force restore over specified database

E agora o banco de dados está preso no estado de restauração.

Algumas pessoas teorizaram que é porque não havia um arquivo de log no backup e ele precisava ser avançado usando:

RESTORE DATABASE MyDatabase
WITH RECOVERY 

Exceto que, é claro, falha:

Msg 4333, Level 16, State 1, Line 1
The database cannot be recovered because the log was not restored.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

E exatamente o que você deseja em uma situação catastrófica é uma restauração que não funcionará.


O backup contém um arquivo de dados e log:

RESTORE FILELISTONLY 
FROM DISK = 'MyDatabase.bak'

Logical Name    PhysicalName
=============   ===============
MyDatabase    C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase.mdf
MyDatabase_log  C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase_log.LDF
Ian Boyd
fonte
3
Eu tive exatamente o mesmo problema e todas as soluções falharam. Curiosamente, eu entrei no servidor SQL diretamente e emiti o DROP DATABASE dbcomando através do SSMS e funcionou (anteriormente eu estava usando o SSMS de outra máquina para emitir os comandos). Eu estou supondo que as outras soluções teriam funcionado também.
Salman A

Respostas:

437

Você precisa usar a WITH RECOVERYopção, com seu RESTOREcomando de banco de dados , para colocar seu banco de dados online como parte do processo de restauração.

Obviamente, isso é apenas se você não pretende restaurar nenhum backup de log de transações, ou seja, você deseja apenas restaurar um backup do banco de dados e depois poder acessar o banco de dados.

Seu comando deve ficar assim,

RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE,RECOVERY

Você pode ter mais sucesso usando o assistente de restauração do banco de dados no SQL Server Management Studio. Dessa forma, você pode selecionar os locais de arquivos específicos, a opção de substituição e a opção WITH Recovery.

John Sansom
fonte
3
Eu nunca tive que usar a declaração de recuperação ao fazer o que ele está fazendo. COM SUBSTITUIR deve ser suficiente.
Sam
8
Sim, eu estava usando o NORECOVERY, mas o processo de restauração trava. Usando COM RECUPERAÇÃO, substituí-lo não travar o processo mais
júnior Mayhé
Isso resolveu meu problema. Tivemos uma falha de SAN no meio de uma restauração e essa foi uma solução rápida e limpa.
Usuário registrado
Hoje tive um problema semelhante com um banco de dados do SQL Server 2005. No meu caso, tive que adicionar ', RESTART' à cláusula WITH para resolver o problema. Ele estava me dando uma mensagem de erro informando que a operação anterior não teve êxito.
XpiritO
3
@FistOfFury Se uma operação de restauração anterior no mesmo banco de dados estiver em estado de suspensão / suspensão, sim. Simplesmente parar / cancelar a restauração em processo deve ter o mesmo efeito.
John Sansom
692

Tive essa situação restaurando um banco de dados em uma instância do SQL Server 2005 Standard Edition usando o Symantec Backup Exec 11d. Após a conclusão da tarefa de restauração, o banco de dados permaneceu no estado "Restaurando". Não tive problemas de espaço em disco - o banco de dados simplesmente não saiu do estado "Restaurando".

Executei a seguinte consulta na instância do SQL Server e constatei que o banco de dados se tornou imediatamente utilizável:

RESTORE DATABASE <database name> WITH RECOVERY
Evan Anderson
fonte
4
Tivemos um banco de dados preso na restauração por 2 horas. Executamos esse comando de uma máquina diferente contra o master e ele nos consertou. Obrigado!
Pete
11
+1, com uma pegadinha. Ao executar isso, recebi uma mensagem de erro informando que o banco de dados já estava totalmente recuperado. Mas ele ainda aparecia como estado "Em recuperação". Então, cliquei com o botão direito do mouse no Management Studio, pressionei Atualizar e ele voltou ao normal.
dario_ramos
2
Eu restaurei usando o assistente do Mng Studio, digitei um novo nome de banco de dados, mas, por engano, deixei os nomes dos arquivos como os mesmos de um banco de dados existente. Eu recebi o erro "Falha na restauração, mas a cauda do log foi bem-sucedida" e o banco de dados anexado a esses arquivos ficou preso em um estado de restauração. Este comando parece ter restaurado o banco de dados ao seu estado anterior.
Chris
3
Isso funcionou. Eu estava tentando restaurar um backup em um banco de dados lateral, mas meu banco de dados principal entrou em estado de restauração por algum motivo. Isso realmente recuperou meu banco de dados. Muito obrigado!
Aravindh
2
Alguns padrões do assistente de restauração do SSMS deixarão o banco de dados de origem no estado de restauração, para que você possa continuar restaurando vários backups ou logs sem medo de usuários, e esse comando é uma maneira adequada de retornar o banco de dados ao normal assim que terminar.
precisa
102

Aqui está como você faz isso:

  1. Pare o serviço (MSSQLSERVER);
  2. Renomeie ou exclua os arquivos de Banco de Dados e Log (C: \ Arquivos de Programas \ Microsoft SQL Server \ MSSQL.1 \ MSSQL \ Data ...) ou onde quer que você tenha os arquivos;
  3. Iniciar o serviço (MSSQLSERVER);
  4. Exclua o banco de dados com problema;
  5. Restaure o banco de dados novamente.
Tipu Delacablu
fonte
Tipu, obrigado por isso. Eu tive um problema semelhante ao pôster original, mas foi causado pelo servidor ficar sem espaço em disco durante a restauração e, portanto, causou um estado de restauração permanente.
214 Pauk
8
Por que não simplesmente largar o banco de dados? Dessa forma, você não precisa interromper o serviço.
ErikE
8
@ErikE Para mim, servidor SQL disse que não pode deixar cair um banco de dados no meio de uma restauração, mesmo que ele não estava realmente restaurar ....
Erik Philips
@ErikPhilips Nesse caso, suponho que esteja de volta a interromper o serviço. Gostaria de saber se isso acontece sempre ou apenas em certos casos do problema de restauração travada.
ErikE
5
No meu caso, foi suficiente descartar o banco de dados que estava pendurado no estado "Restaurando ..." com o comando SQL drop database <dbname>em uma janela de consulta. Em seguida, cliquei com o botão direito do mouse em Bancos de dados e selecione Atualizar, que removeu a entrada no Management Studio. Depois, fiz uma nova restauração que funcionou bem ( observe que colocá-la offline não funcionou, a reinicialização do serviço SQL não funcionou, a reinicialização do servidor também não funcionou).
Matt
84

Tive um incidente semelhante ao interromper um servidor secundário de envio de logs. Após o comando para remover o servidor do envio de logs e interromper o envio do servidor primário, o banco de dados no servidor secundário ficou paralisado ao restaurar o status após o comando

RESTORE DATABASE <database name> WITH RECOVERY

As mensagens do banco de dados:

RESTORE DATABASE processou 0 páginas com êxito em 18.530 segundos (0.000 MB / s).

O banco de dados foi utilizável novamente após esses 18 segundos.

Hans
fonte
6
Especialmente útil quando você já restaurado o banco de dados, mas esqueceu a opção de recuperação ...
JBickford
2
Era tudo o que eu precisava para deixar o estado "Restaurando" depois de restaurar um backup desse banco de dados para um nome de banco de dados diferente. Muito obrigado.
26515 Sean
81

Eu tive um problema semelhante ao restaurar usando o SQL Management Studio. Tentei restaurar um backup do banco de dados para um novo com um nome diferente. No início, isso falhou e, depois de corrigir os nomes de arquivo do novo banco de dados, ele foi executado com êxito - em qualquer caso, o problema que estou descrevendo ocorreu novamente, mesmo que eu tenha acertado desde a primeira vez. Portanto, após a restauração, o banco de dados original permaneceu com um (Restaurando ...) ao lado do nome. Considerando as respostas do fórum acima (Bhusan), tentei executar no editor de consultas ao lado o seguinte:

RESTORE DATABASE "[NAME_OF_DATABASE_STUCK_IN_RESTORING_STATE]"

que corrigiu o problema. No começo, eu estava tendo problemas por causa do nome do banco de dados que continha caracteres especiais. Resolvi isso adicionando aspas duplas - aspas simples não funcionariam, fornecendo o erro "Sintaxe incorreta perto de ...".

Esta foi a solução mínima que tentei resolver esse problema (banco de dados bloqueado na restauração do estado) e espero que possa ser aplicado a mais casos.

Demetris Leptos
fonte
2
Funcionou perfeitamente - sem precisar derrubá-lo e levantá-lo novamente. 3 Dbs de 80+ Gb cada um leva um tempo! Obrigado!
Christer
1
Eu quase fiz isso no ambiente de produção. Eu tentei primeiro no local, acabei nessa mesma situação e encontrei seu comentário. Lição aprendida: use scripts e não confie no SSMS em situações importantes.
Mariusz
1
Recebi esse problema ao restaurar um backup de arquivo somente cópia de um banco de dados para um novo banco de dados. O banco de dados original mostrou o erro. Essa solução funcionou e a resposta que obtive foi "RESTORE DATABASE processou 0 páginas com êxito em 0,263 segundos (0,000 MB / s)". , parece que o SQL Server estava confuso sobre o estado do banco de dados.
R. Schreurs
1
Funcionou para mim, mas somente quando removi as aspas duplas - eu tinha apenas [MY_DB_NAME] como parâmetro.
StackOverflowUser
34

OK, tenho um problema semelhante e, exatamente como no caso de Pauk, foi causado pelo servidor ficar sem espaço em disco durante a restauração e, portanto, causou um estado de restauração permanente. Como finalizar esse estado sem interromper os serviços do SQL Server?

Eu encontrei uma solução :)

Drop database *dbname*
ErikE
fonte
29

A opção WITH RECOVERY é usada por padrão quando os comandos RESTORE DATABASE / RESTORE LOG são executados. Se você estiver preso no processo de "restauração", poderá retornar um banco de dados ao estado online executando:

RESTORE DATABASE YourDB WITH RECOVERY
GO

Se houver necessidade de restauração de vários arquivos, os comandos da CLI exigirão WITH NORECOVERY e WITH RECOVERY respectivamente - somente o último arquivo no comando deve ter WITH RECOVERY para recuperar o banco de dados on-line:

RESTORE DATABASE YourDB FROM DISK = 'Z:\YourDB.bak'
WITH NORECOVERY
GO
RESTORE LOG YourDB FROM DISK = 'Z:\YourDB.trn'
WITH RECOVERY
GO

Você também pode usar o assistente do SQL Server Management Studio:

insira a descrição da imagem aqui

Há também um processo de restauração virtual, mas você precisará usar soluções de terceiros. Geralmente, você pode usar um backup de banco de dados como banco de dados on-line ao vivo. ApexSQL e Idera têm suas próprias soluções. Revisão por SQL Hammer sobre o ApexSQL Restore . A restauração virtual é uma boa solução se você estiver lidando com um grande número de backups. O processo de restauração é muito mais rápido e também pode economizar muito espaço na unidade de disco. Você pode dar uma olhada no infográfico aqui para fazer uma comparação.

Marko Krstic
fonte
23

Isso pode ser bastante óbvio, mas isso me fez tropeçar agora:

Se você estiver executando um backup de log de cauda, ​​esse problema também pode ser causado pela opção verificada no assistente de restauração do SSMS - "Deixe o banco de dados de origem no estado de restauração (WITH NORECOVERY)"

insira a descrição da imagem aqui

TrailJon
fonte
7
Se você estiver nesse estado, sua melhor aposta é: 1. Clique com o botão direito do mouse no banco de dados, vá em Tarefas-> Restaurar-> Logs de Transações 2. Localize o arquivo de backup que foi usado para o backup do Tail Tail. o backup A restauração deve ser bem-sucedida e colocar o banco de dados novamente online.
Ryan Gross
16

Eu descobri o porquê.

Se o cliente que emitiu o RESTORE DATABASEcomando for desconectado durante a restauração, a restauração será interrompida.

É estranho que o servidor, quando solicitado a restaurar um banco de dados por uma conexão do cliente, não conclua a restauração, a menos que o cliente permaneça conectado o tempo todo.

Ian Boyd
fonte
10
Todos os comandos SQL exigem que o cliente fique conectado o tempo todo.
mrdenny
2
@ Mrdenny: eu teria assumido que as alterações são desfeitas quando um cliente se desconecta.
3105 Ian Boyd
Eu tenho o mesmo problema ao executar este comando com o driver PHP PDO da microsoft. no entanto, quando executado com o Microsoft SQL Server Management Studio, funciona perfeitamente. Gostaria de saber como fazer meu aplicativo php conectado o tempo todo?
Channa ly 29/01
Aconteceu aqui também, o DB travou na restauração / usuário único após uma possível quebra de conexão. Matou todos os outros SPIDs da nova sessão, mas ainda está travado. Foi capaz de descartar o banco de dados como solução.
crokusek
10

este funcionou:

http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/8dd1b91d-3e14-4486-abe6-e3a550bfe457

Eu tive uma situação em que meu banco de dados mostrava o estado de restauração e não conseguia executar nenhuma consulta e não consegui me conectar ao nosso software.

O que eu fiz para sair dessa situação é:

  1. Pare todos os serviços relacionados ao SQL dos serviços do Windows.

  2. Abri a pasta DATA onde os arquivos Ldf e Mdf residem no diretório SQL, normalmente como: "C: \ Arquivos de Programas *********** \ MSSQL \ DATA

  3. Depois copiei os arquivos Ldf e Mdf do banco de dados: [nome do banco de dados] .mdf e [nome do banco de dados] _log.ldf

Copiei esses dois arquivos para outra pasta.

  1. Em seguida, iniciei todos os serviços relacionados ao SQL (na etapa 1) novamente a partir dos serviços do Windows.

  2. Iniciei meu estúdio de gerenciamento do MS SQL com login normal.

  3. Clique com o botão direito do mouse no banco de dados responsável e pressione DELETE (para excluir o banco de dados).

  4. Todos os arquivos LDF e MDF relacionados a esse banco de dados foram da pasta DATA (mencionados na etapa 2).

  5. Criou um novo banco de dados com o mesmo nome (o mesmo nome que eu excluí na etapa 6 - o banco de dados responsável).

  6. Em seguida, [nome do banco de dados] -> clique com o botão direito do mouse -> tarefas -> Desligar.

  7. Copiei os dois arquivos (da etapa 3) de volta para a pasta DATA (etapa 2).

  8. [nome do banco de dados] -> clique com o botão direito do mouse -> tarefas -> Colocar Online.

Ameen Abuhilal
fonte
Isso funcionou para mim também. Na etapa 10, eu escolhi substituir os arquivos existentes.
Divi perdomo
8

Eu tive um . no nome do meu banco de dados e a consulta não funcionou por causa disso (dizendo sintaxe incorreta perto de '.'). Então percebi que precisava de um colchete para o nome:

RESTORE DATABASE [My.DB.Name] WITH RECOVERY
Ashkan Sirous
fonte
5

No meu caso, foi suficiente descartar o banco de dados que estava pendurado no estado "Restaurando ..." com o comando SQL

 drop database <dbname> 

em uma janela de consulta.

Em seguida, cliquei com o botão direito do mouse em Bancos de dados e selecione Atualizar, que removeu a entrada no Management Studio. Depois, fiz uma nova restauração que funcionou bem (observe que colocá-la offline não funcionou, a reinicialização do serviço SQL não funcionou, a reinicialização do servidor também não funcionou).

Matt
fonte
3

Eu tive esse problema quando também recebi um erro TCP no log de eventos ...

Solte o banco de dados com sql ou clique com o botão direito no gerenciador "delete" e restaure novamente.

Na verdade, eu comecei a fazer isso por padrão. Faça o script da queda do banco de dados, recrie e restaure.

ZeusT
fonte
3

Por padrão, todos RESTORE DATABASEvêm com a RECOVERYconfiguração. As opções 'NORECOVERY', basicamente informa ao SQL Server que o banco de dados está aguardando mais arquivos de restauração (pode ser um arquivo DIFF e um arquivo LOG e, pode incluir um arquivo de backup de log de cauda, ​​se possível). As opções 'RECUPERAÇÃO', finalizam todas as transações e deixam o banco de dados pronto para realizar as transações.

Assim:

  1. se o seu banco de dados estiver configurado com o modelo de recuperação SIMPLE , você poderá executar uma restauração COMPLETA somente com a NORECOVERYopção quando tiver um backup DIFF . Nenhum backup de LOG é permitido no banco de dados do modelo de recuperação SIMPLE .
  2. Caso contrário, se o seu banco de dados estiver configurado com o modelo de recuperação COMPLETO ou BULK-LOGGED , você poderá executar uma restauração COMPLETA seguida pela NORECOVERYopção, executar um DIFF seguido por NORECOVERYe, finalmente, executar a restauração LOG com a RECOVERYopção

Lembre-se de que a última consulta de restauração deve ter RECOVERYopção . Poderia ser uma maneira explícita ou não. Em termos de T-SQL, a situação:

1

 USE [master]
    GO
    RESTORE DATABASE Database_name 
    FROM DISK = N'\\path_of_backup_file.bak WITH FILE = 1, [REPLACE],NOUNLOAD, 
    RECOVERY -- This option could be omitted.
    GO

A opção WITH REPLACE deve ser usada com cautela, pois pode levar à perda de dados

Ou, se você executar um backup COMPLETO e DIFF, poderá usar este

   USE [master]
    GO
    RESTORE DATABASE Database_name
      FROM DISK = N'\\path_of_backup_file.bak' WITH FILE = 1, 
       NOUNLOAD,NORECOVERY
    GO
    RESTORE DATABASE Database_name
      FROM DISK =N'\\path_of_**diff**backup_file.bak' WITH FILE = 1, 
     NOUNLOAD, RECOVERY
    GO

 2. USE [master]
    GO
   -- Perform a Tail-Log backup, if possible. 
   BACKUP LOG Database_name
   GO
   -- Restoring a FULL backup
   RESTORE DATABASE Database_name
    FROM DISK = N'\\path_of_backup_file.bak' WITH FILE = 1, 
     NOUNLOAD,NORECOVERY
  GO 
  -- Restore the last DIFF backup
  RESTORE DATABASE Database_name
    FROM DISK = N'\\path_of_DIFF_backup_file.bak' WITH FILE = 1,
     NORECOVERY,NOUNLOAD
  GO
  -- Restore a Log backup
  RESTORE LOG Database_name
    FROM DISK = N'path_of_LOG_backup_file.trn' WITH FILE = 2,
    RECOVERY, NOUNLOAD
  GO

Obviamente, você pode executar uma restauração com a opção STATS = 10 que instrui o SQL Server a relatar a cada 10% concluído.

Se preferir, você pode observar o processo ou restaurar em consultas baseadas em tempo real. Como se segue:

USE[master]
GO
SELECT session_id AS SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time 
    FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
        WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE')
GO

Espero que esta ajuda.

BMDaemon
fonte
2

Também pode haver problemas ao excluir um banco de dados bloqueado se a captura instantânea estiver ativada. Para mim, isso funcionou:

  1. Primeiro, segui as etapas de Tipu Delacablu (leia algumas postagens)
  2. comando run: drop database [seu banco de dados], que fornecerá um erro informando o nome do banco de dados de captura instantânea
  3. comando de execução: solte o banco de dados [banco de dados de captura instantânea] e execute o comando na etapa 2 novamente.
Comunidade
fonte
1

Eu tenho o caso MyDbName (Restaurando ...) devido ao limite licenciado do SQL Express.

No arquivo de log, encontrei o seguinte:

CREATE DATABASE ou ALTER DATABASE falhou porque o tamanho cumulativo do banco de dados resultante excederia o limite licenciado de 10240 MB por banco de dados.

Portanto, se você estiver tentando restaurar um banco de dados maior, precisará mudar o servidor SQL Express para Developer Edition, por exemplo.

Dmitry Pavlov
fonte
Era o banco de dados TFS e o cliente TFS já me disse: Banco de dados cheio.
cskwg
1

Ocorreu um problema semelhante ao restaurar o banco de dados usando o SQL Server Management Studio e ele ficou preso no modo de restauração. Após várias horas de rastreamento de problemas, a consulta a seguir funcionou para mim. A consulta a seguir restaura o banco de dados de um backup existente para um estado anterior. Eu acredito que o problema é o de ter o arquivo .mdf e .log no mesmo diretório.

RESTORE DATABASE aqua_lc_availability
FROM DISK = 'path to .bak file'
WITH RECOVERY
Ujjwal
fonte
0
  1. Vamos verificar e executar o SQL Agent Service primeiro.
  2. Usando o seguinte T-SQL:

    SELECT nome do arquivo FROM master.sys.sysaltfiles WHERE dbid = DB_ID ('db_name');

  3. Usando o T-SQL continuamente:

    RESTORE DATABASE FROM DISK = 'DB_path' COM REINICIAR, SUBSTITUIR;

Espero que esta ajuda!

Trung Nguyen
fonte
0

Todas as opções baseadas no WITH RECOVERY não funcionaram para mim.

O que fez foi a restauração completa do Management Studio.

USE [master]
RESTORE DATABASE Sales_SSD
FROM  DISK = N'D:\databaseBackups02\Daily_Sales_20150309_0941.bak' 
WITH  FILE = 1,  
MOVE N'Sales_Data' TO N'C:\Data\SSD\Sales.mdf',  
MOVE N'Sales_Log' TO N'C:\Data\SSD\Sales_1.ldf',  
NOUNLOAD,  REPLACE,  STATS = 5
earthling42
fonte
0

Eu tive o mesmo problema ... embora eu não saiba por que meu banco de dados teve esse problema, pois minha unidade não estava cheia ... É como se estivesse corrompida ou algo assim. Eu tentei todas as opções acima, nenhuma delas funcionou totalmente, pensei especialmente na sugestão de interromper o serviço e excluir os arquivos mdf e ldf funcionaria ... mas ainda congelou na restauração?

Acabei resolvendo isso excluindo os arquivos conforme mencionado, mas em vez de tentar restaurar o banco de dados novamente, copiei os arquivos .mdf e .ldf frescos e os anexei usando o assistente de Front End Attachment. Alívio, funcionou !!

Sempre foi necessário copiar os novos arquivos, pois estou usando uma máquina virtual ... então, copiar e colar usando a área de transferência levou uma hora, então eu recomendaria isso apenas como uma última tentativa.

Anthony Griggs
fonte
0

O que foi corrigido para mim foi

  1. parando a instância
  2. criando um backup dos arquivos .mdf e .ldf na pasta de dados
  3. Reinicie a instância
  4. excluir o banco de dados preso restauração
  5. coloque os arquivos .mdf e.ldf novamente na pasta de dados
  6. Anexe a instância aos arquivos .mdf e .ldf
ChadJPetersen
fonte
0
RESTORE DATABASE {DatabaseName}
   FROM DISK = '{databasename}.bak'
   WITH REPLACE, RECOVERY
Rony Barua
fonte
Aponte os insights adicionais que esta resposta fornece quando comparada à resposta mais antiga, aceita e altamente votada. Isso ajudaria a evitar a impressão de ter copiado na esperança de obter reputação. Além disso, as respostas só de código (que é a principal diferença visível) não são apreciados aqui, porque eles dão a impressão errada de que StackOverflow é um serviço de escrita de código livre,
Yunnosch
Corrigi a formatação, apenas para tornar a semelhança com a resposta mais antiga mais óbvia. Mas você pode aprender a fazer isso aqui stackoverflow.com/editing-help , caso tente criar respostas mais facilmente legíveis no futuro.
Yunnosch
0

Use o seguinte comando para resolver esse problema

RESTORE DATABASE [DatabaseName] WITH RECOVERY
Sumant Singh
fonte