ALTER DATABASE falló porque no se pudo colocar un bloqueo en la base de datos

124

Necesito reiniciar una base de datos porque algunos procesos no funcionan. Mi plan es desconectarlo y volver a conectarlo nuevamente.

Estoy tratando de hacer esto en Sql Server Management Studio 2008:

use master;
go
alter database qcvalues
set single_user
with rollback immediate;
alter database qcvalues
set multi_user;
go

Recibo estos errores:

Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
Msg 5061, Level 16, State 1, Line 4
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 4
ALTER DATABASE statement failed.

¿Qué estoy haciendo mal?

JOE SKEET
fuente
¿Cuál es el problema que causó esta necesidad en primer lugar? ¿Tiene algunas transacciones de reversión en este momento? ¿También ha ejecutado este comando en otra ventana de SSMS que aún podría estar abierta? Me pregunto (pura especulación) si eso podría tomar un bloqueo que bloquea otros intentos, pero todavía está esperando antes de que la base de datos pueda ponerse en modo de usuario único.
Martin Smith
1
@ Martin - bastante justo. Debo pensar en otra cosa o perder la cabeza. cualquiera de los dos es bastante posible
codingbadger
@ Muchas gracias a todos, reinicié SSMS y pude matar a todos
JOE SKEET
Podría ser inteligente. Eliminé una consulta incompleta que tenía líneas onduladas tratando de acceder a la base de datos y luego funcionó.
Faahmed

Respuestas:

293

Después de recibir el error, ejecute

EXEC sp_who2

Busque la base de datos en la lista. Es posible que una conexión no haya finalizado. Si encuentra alguna conexión a la base de datos, ejecute

KILL <SPID>

donde <SPID>está el SPID para las sesiones que están conectadas a la base de datos.

Pruebe su secuencia de comandos después de eliminar todas las conexiones a la base de datos.

Desafortunadamente, no tengo una razón por la que está viendo el problema, pero aquí hay un enlace que muestra que el problema ha ocurrido en otro lugar.

http://www.geakeit.co.uk/2010/12/11/sql-take-offline-fails-alter-database-failed-because-a-lock-could-not-error-5061/

bobs
fuente
¿Puede proporcionar alguna explicación de por qué una conexión no sería terminada por el comando? La única razón por la que puedo pensar es que todavía está en proceso de retroceso o es un set single_userintento que aún está pendiente.
Martin Smith
@ Martin, me temo que no tengo una razón para esto. Pero, agregaré un enlace que indica que otros han visto el problema. Estoy de acuerdo en que una reversión de transacción podría ser el problema, pero KILLtampoco lo resolvería.
Bobs
Sea amable de entender por qué sucede esto, ¡pero los comentarios en su enlace parecen indicar que funcionaría! (+1)
Martin Smith
KILL (87) resultados en Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '('.erm ....
Tim Abell
2
@MartinSmith Creo que sé por qué: acabo de tener el mismo problema, una conexión persistente que aparece debajo de sp_who2 provocando que se desconecte la desconexión. Resultó ser una ventana abierta de edición de filas en ssms. Creo que lo que sucede aquí es que la ventana de edición de filas es una consulta abierta con un conjunto de resultados editable. SQL Server tiene una función como alternativa a las declaraciones de actualización. Al cerrar esta ventana de ssms en particular, el bloqueo que se desconecta se completa inmediatamente.
John
5

Logré reproducir este error haciendo lo siguiente.

Conexión 1 (dejar en funcionamiento durante un par de minutos)

CREATE DATABASE TESTING123
GO

USE TESTING123;

SELECT NEWID() AS X INTO FOO
FROM sys.objects s1,sys.objects s2,sys.objects s3,sys.objects s4 ,sys.objects s5 ,sys.objects s6

Conexiones 2 y 3

set lock_timeout 5;

ALTER DATABASE TESTING123 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
Martin Smith
fuente
2

Prueba esto si está "en transición" ...

http://learnmysql.blogspot.com/2012/05/database-is-in-transition-try-statement.html

USE master
GO

ALTER DATABASE <db_name>

SET OFFLINE WITH ROLLBACK IMMEDIATE
...
...
ALTER DATABASE <db_name> SET ONLINE
Watki02
fuente
No funcionará cuando la base de datos esté en transición, obtendrá el mismo error con la SET OFFLINEdeclaración mencionada por el OP (tal vez hay escenarios en los que funciona, pero no lo hizo para mí)
Abel
1

Agregaré esto aquí en caso de que alguien tenga tanta suerte como yo.

Al revisar la lista de procesos sp_who2 , tenga en cuenta los procesos que se ejecutan no solo para la base de datos afectada sino también para el maestro . En mi caso, el problema que estaba bloqueando la base de datos estaba relacionado con un procedimiento almacenado que inició un xp_cmdshell.

Compruebe si tiene algún proceso en estado KILL / RollBack para la base de datos maestra

SELECT *
FROM sys.sysprocesses
WHERE cmd = 'KILLED/ROLLBACK'

Si tiene el mismo problema, solo el comando KILL probablemente no ayudará. Puede reiniciar el servidor SQL, o una mejor manera es encontrar el cmd.exe en los procesos de Windows en el sistema operativo del servidor SQL y matarlo.

Alina
fuente
0

En SQL Management Studio, vaya a Seguridad -> Inicios de sesión y haga doble clic en su Inicio de sesión. Elija Roles de servidor en la columna izquierda y verifique que sysadmin esté marcado.

En mi caso, inicié sesión en una cuenta sin ese privilegio.

HTH!

Marty
fuente
1
El error en la pregunta original también ocurre cuando eres SA, no tiene nada que ver con tus derechos. Si no tiene suficientes derechos, no podrá ejecutar el comando fuera de línea.
Abel
0

Matar la ID del proceso funcionó muy bien para mí. Al ejecutar el comando "EXEC sp_who2" sobre una nueva ventana de consulta ... y filtrar los resultados para la base de datos "ocupada", matar los procesos con el comando "KILL" logró hacer el truco. Después de eso, todo volvió a funcionar.

usuario3749524
fuente
0

Solo para agregar mis dos centavos. Me puse en la misma situación, mientras buscaba los privilegios mínimos requeridos de un inicio de sesión de db para ejecutar con éxito la declaración:

ALTER DATABASE ... SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Parece que la instrucción ALTER se completa con éxito , cuando se ejecuta con un inicio de sesión de sysadmin , pero requiere la parte de limpieza de conexiones, cuando se ejecuta bajo un inicio de sesión que tiene "solo" permisos limitados como:

ALTER ANY DATABASE

PD: He pasado horas tratando de descubrir por qué la "ALTER DATABASE .." no funciona cuando se ejecuta bajo un inicio de sesión que tiene el rol dbcreator + ALTER CUALQUIER privilegio de DATABASE . Aquí está mi hilo de MSDN !

Veselin Z.
fuente
0

Sé que esta es una publicación antigua, pero recientemente me encontré con un problema muy similar. Desafortunadamente, no pude usar ninguno de los comandos de alterar la base de datos porque no se pudo colocar un bloqueo exclusivo. Pero nunca pude encontrar una conexión abierta a la base de datos. Eventualmente tuve que eliminar forzosamente el estado de salud de la base de datos para forzarla a un estado de restauración en lugar de recuperarla.

Geoff Dawdy
fuente
0

En casos raros (p. Ej., Después de que se haya comprometido una transacción pesada), un proceso del sistema CHECKPOINT en ejecución que mantiene un bloqueo de ARCHIVO en el archivo de la base de datos evita la transición al modo MULTI_USER.

mitix
fuente
0

En mi escenario, no hubo ningún proceso que bloqueara la base de datos bajo sp_who2. Sin embargo, descubrimos que debido a que la base de datos es mucho más grande que nuestras otras bases de datos, los procesos pendientes todavía se estaban ejecutando, por lo que la base de datos bajo el grupo de disponibilidad todavía se mostraba como roja / fuera de línea después de que intentamos 'reanudar los datos' haciendo clic derecho en la base de datos en pausa.

Para verificar si todavía tiene procesos en ejecución, simplemente ejecute este comando: seleccione el porcentaje completado de sys.dm_exec_requests donde percent_complete> 0

usuario123456789
fuente