Error "La base de datos está en transición"


12

Hoy estaba tratando de restaurar una base de datos sobre una base de datos ya existente, simplemente hice clic derecho en la base de datos en SSMS -> Tareas -> Desconectar para poder restaurar la base de datos.

Apareció una pequeña ventana emergente que se mostró Query Executing.....por algún tiempo y luego arrojó un error que decía Database is in use cannot take it offline. De lo que deduje que hay algunas conexiones activas a esa base de datos, intenté ejecutar la siguiente consulta

USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

De nuevo en este punto, el SSMS se mostró Query Executing.....por algún tiempo y luego arrojó el siguiente error:

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.

Después de esto, no pude conectarme a la base de datos a través de SSMS. y cuando traté de desconectarlo usando SSMS arrojó un error que decía:

Database is in Transition. Try later .....

En este punto, simplemente no podía tocar la base de datos, cualquier cosa que probé devolvió el mismo mensaje de error Database is in Transition.

Entré en google y leí algunas preguntas en las que la gente se había enfrentado a un problema similar y me recomendaron cerrar el SSMS y volver a abrirlo, así que lo hice y como era solo un servidor de desarrollo, simplemente eliminé la base de datos usando SSMS y la restauré en una nueva base de datos.

Mi pregunta es, ¿qué pudo haber causado esto? y cómo puedo evitar que esto suceda en el futuro y si alguna vez termino en la misma situación en el futuro, ¿hay alguna otra forma de solucionarlo y luego eliminar toda la base de datos?

Gracias

Respuestas:


23

Repro

  1. Abrir SSMS
  2. Escriba lo siguiente en una nueva ventana de consulta

    use <YourDatabase>;
    go
  3. Vaya al Explorador de objetos (SSMS) y haga clic derecho en <YourDatabase>-> Tasks->Take Offline
  4. Abra una segunda ventana de consulta nueva y escriba lo siguiente:

    use <YourDatabase>;
    go

Se le solicitará el siguiente mensaje:

Msg 952, Nivel 16, Estado 1, Línea 1 La
base de datos 'TestDb1' está en transición. Prueba la declaración más tarde.

La razón por la que esto sucede puede encontrarse en una consulta de diagnóstico similar a la siguiente:

select
    l.resource_type,
    l.request_mode,
    l.request_status,
    l.request_session_id,
    r.command,
    r.status,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    request_sql_text = st.text,
    s.program_name,
    most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;

Para lo que vale, no necesita el Explorador de objetos para reproducir este error. Solo necesita una solicitud bloqueada que intente la misma operación (en este caso, desconecte la base de datos). Vea la captura de pantalla siguiente para los tres pasos en T-SQL:

ingrese la descripción de la imagen aquí

Lo más probable es que veas que tu sesión de Object Explorer está bloqueada por otra sesión (mostrada por blocking_session_id). Esa sesión de Object Explorer intentará obtener un bloqueo exclusivo ( X) en la base de datos. En el caso de la reproducción anterior, a la sesión del Explorador de objetos se le otorgó un bloqueo de actualización ( U) e intentó convertir a un bloqueo exclusivo ( X). Tenía un wait_type de LCK_M_X, bloqueado por nuestra sesión que estaba representada por la primera ventana de consulta ( use <YourDatabase>toma un bloqueo compartido ( S) en la base de datos).

Y luego, este error surgió de otra sesión que intentaba obtener un bloqueo, y este mensaje de error resulta en la denegación de una sesión para obtener acceso a una base de datos que está intentando realizar la transición a un estado diferente (en este caso, estado de conexión en línea a la transición fuera de línea).

¿Qué deberías hacer la próxima vez?

En primer lugar, no entre en pánico y no comience a soltar bases de datos . Debe adoptar un enfoque de solución de problemas (con una consulta de diagnóstico similar a la anterior) para averiguar por qué está viendo lo que está viendo. Con un mensaje como ese, o cuando algo parece "colgado", debe asumir automáticamente la falta de concurrencia y comenzar a cavar en el bloqueo ( sys.dm_tran_lockses un buen comienzo).

Como nota al margen, realmente creo que es mejor averiguar la raíz de un problema antes de tomar cualquier acción aleatoria. No solo con esta operación, sino que se aplica a todos los comportamientos que no esperas. Sabiendo lo que realmente estaba causando su problema, es obvio que realmente no era gran cosa. Básicamente tenía una cadena de bloqueo, y el bloqueador principal era algo que probablemente podría haber emitido KILL, o si era una solicitud de sesión que no deseaba KILL, podría haber esperado hasta que se completara. De cualquier manera, habría tenido el conocimiento para tomar la decisión correcta y prudente dado su escenario particular (revertir o esperar para confirmar).

Otra cosa que vale la pena señalar, esta es una de las razones por las que siempre opto por la alternativa T-SQL en lugar de una GUI. Sabe exactamente lo que está ejecutando con T-SQL y qué está haciendo SQL Server. Después de todo, emitió el comando explícito. Cuando usa una GUI, el T-SQL real será una abstracción. En este caso, miré el intento del Explorador de objetos bloqueado de desconectar la base de datos y así fue ALTER DATABASE <YourDatabase> SET OFFLINE. No hubo intentos de retroceder, por lo que estaba esperando indefinidamente. En su caso, si quisiera revertir las sesiones que tenían bloqueos en esa base de datos, ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEprobablemente habría sido suficiente si hubiera tomado la determinación inicial de que la reversión estaba bien.


3

Simplemente cerrando SQL Server Management Studio (SSMS) y reabriendo solucionó el problema para mí.


0

No es necesario hacer nada, simplemente elimine el proceso SqLWB.exedesde el Administrador de tareas, abra SQL Server, haga clic derecho en la base de datos y desconéctelo. Si no funciona, luego de finalizar la sesión, escriba el comando

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

y luego fuera de línea. Funcionará como funcionó para mí también.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.