Hoje eu estava tentando restaurar um banco de dados sobre um banco de dados já existente, simplesmente cliquei com o botão direito do mouse no banco de dados em SSMS -> Tarefas -> Desconectar para que eu pudesse restaurar o banco de dados.
Uma pequena janela pop-up apareceu e mostrou Query Executing.....
por algum tempo e depois lançou um erro dizendo Database is in use cannot take it offline
. Do qual eu reuni existem algumas conexões ativas para esse banco de dados, então tentei executar a seguinte consulta
USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
Novamente, neste ponto, o SSMS apareceu Query Executing.....
por algum tempo e depois lançou o seguinte erro:
Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
Depois disso, não consegui me conectar ao banco de dados por meio do SSMS. e quando tentei colocá-lo offline usando o SSMS, ele apresentou um erro dizendo:
Database is in Transition. Try later .....
Neste ponto, eu simplesmente não conseguia tocar no banco de dados, nada que tentei, retornou a mesma mensagem de erro Database is in Transition
.
Peguei no google e li algumas perguntas em que as pessoas enfrentaram problemas semelhantes e recomendaram fechar o SSMS e abri-lo novamente, assim como eu e como era apenas um servidor dev, acabei de excluir o banco de dados usando o SSMS e restaurá-lo em um novo banco de dados.
Minha pergunta é o que poderia ter causado isso ?? e como posso evitar que isso aconteça no futuro e se eu acabar na mesma situação no futuro, existe alguma outra maneira de corrigi-lo além de excluir todo o banco de dados ???
obrigada
Reprodução
Digite o seguinte em uma nova janela de consulta
<YourDatabase>
->Tasks
->Take Offline
Abra uma segunda nova janela de consulta e digite o seguinte:
Você será solicitado com a seguinte mensagem:
O motivo pelo qual isso está acontecendo pode ser encontrado em uma consulta de diagnóstico semelhante à abaixo:
Pelo que vale, você não precisa do Pesquisador de Objetos para reproduzir esse erro. Você só precisa de uma solicitação bloqueada que esteja tentando a mesma operação (neste caso, coloque o banco de dados offline). Veja a captura de tela abaixo para as três etapas no T-SQL:
O que você provavelmente verá é sua sessão do Pesquisador de Objetos sendo bloqueada por outra sessão (mostrada por
blocking_session_id
). Essa sessão do Pesquisador de Objetos estará tentando obter um bloqueio exclusivo (X
) no banco de dados. No caso do repro acima, a sessão do Pesquisador de Objetos recebeu um bloqueio de atualização (U
) e tentou converter em um bloqueio exclusivo (X
). Ele tinha um wait_type deLCK_M_X
, bloqueado por nossa sessão que foi representada pela primeira janela de consulta (ouse <YourDatabase>
pega um bloqueio compartilhado (S
) no banco de dados).E então esse erro surgiu de outra sessão tentando obter um bloqueio, e essa mensagem de erro resulta na negação de uma sessão para obter acesso a um banco de dados que está tentando fazer a transição para um estado diferente (neste caso, estado de online para a transição offline).
O que você deve fazer da próxima vez?
Primeiro, não entre em pânico e não comece a descartar bancos de dados . Você precisa adotar uma abordagem de solução de problemas (com uma consulta de diagnóstico semelhante à acima) para descobrir por que está vendo o que está vendo. Com uma mensagem como essa, ou quando algo parece "travado", você deve assumir automaticamente uma falta de simultaneidade e começar a investigar o bloqueio (
sys.dm_tran_locks
é um bom começo).Como uma nota lateral, eu realmente acredito que você é melhor descobrir a raiz de um problema antes de tomar qualquer ação aleatória. Não apenas com esta operação, mas isso vale para todos os comportamentos que você não espera. Sabendo o que realmente estava causando seu problema, é óbvio que realmente não era grande coisa. Você basicamente tinha uma cadeia de bloqueio, e o bloqueador pai era algo que você provavelmente poderia ter apenas emitido
KILL
, ou se fosse uma solicitação de sessão que você não queriaKILL
, você poderia esperar até que ela fosse concluída. De qualquer forma, você teria o conhecimento para tomar a decisão certa e prudente, considerando seu cenário específico (reversão ou espera por confirmação).Outra coisa que vale a pena notar, essa é uma das razões pelas quais sempre opto pela alternativa T-SQL em vez de uma GUI. Você sabe exatamente o que está executando com o T-SQL e o que o SQL Server está fazendo. Afinal, você emitiu o comando explícito. Quando você usa uma GUI, o T-SQL real será uma abstração. Nesse caso, observei a tentativa do Pesquisador de Objetos bloqueado de colocar o banco de dados offline e era
ALTER DATABASE <YourDatabase> SET OFFLINE
. Não houve tentativa de reversão, e é por isso que estava esperando indefinidamente. No seu caso, se você quisesse reverter as sessões que tinham bloqueios nesse banco de dados,ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATE
provavelmente seria suficiente se você tivesse feito a determinação inicial de que a reversão estava correta.Simplesmente fechar o SQL Server Management Studio (SSMS) e reabrir resolveu o problema para mim.
Não há necessidade de fazer nada, basta matar o processo
SqLWB.exe
do Gerenciador de Tarefas, abrir o SQL Server, clicar com o botão direito do mouse no banco de dados e colocá-lo offline. Se não funcionar, depois que a sessão for encerrada, digite o comandoe depois off-line. Vai funcionar como funcionou para mim também.