Aproximadamente una vez a la semana tengo que resolver una cadena de bloqueo en una base de datos SQL Server 2005, causada por un bloqueo de lectura de larga duración desde un front-end de Access 2003. El bloqueo se elimina cada vez que un usuario abre un formulario determinado y se libera una vez que el usuario ha terminado de desplazarse por el formulario o lo cierra. Dado que muchos de nuestros usuarios abren este formulario como referencia, estos bloqueos permanecen por un tiempo. Cualquier actualización de la tabla provoca el bloqueo, y de repente nadie puede seleccionar de esta tabla, ya que todos están esperando el primer bloqueo. Esto es un gran problema para nosotros, ya que muchas aplicaciones dependen de estos datos. Entiendo que este comportamiento de bloqueo es parte de cómo funciona Access con tablas vinculadas.
He estado resolviendo el problema desde Activity Monitor, eliminando el proceso SELECT que sea el Head Blocker cada vez que me entero de ello. Este es un problema no solo porque me lleva tiempo hacerlo manualmente, sino también porque es reactivo. Para cuando me enteré, ya ha sido un problema para mucha gente.
Me gustaría saber si hay una forma automática de verificar estas cadenas de bloqueo duraderas, y si se envía por correo electrónico o si el problema se resuelve automáticamente. La lógica parece bastante sencilla ("si algún proceso que coincide con esta consulta SELECT ha estado bloqueando durante más de un minuto, notifíqueme / elimínelo") pero no sé cómo implementar esto con SQL Server.
Por lo que vale, creo que la solución adecuada es arreglar o reescribir la aplicación. Sin embargo, debido a la política departamental, esta no es una opción para los próximos meses, por lo que estoy buscando una solución provisional.
fuente
Respuestas:
¿Has considerado usar el aislamiento de instantáneas ? Habilitar read_committed_snapshot en la base de datos hará que todas las lecturas (selecciones) estén libres de bloqueo:
No hay cambios en la aplicación. Algunas semánticas cambian bajo la instantánea y su aplicación puede reaccionar de manera extraña, pero esa es la excepción, no la norma. La gran mayoría de las aplicaciones no notan ninguna diferencia, solo obtienen un aumento de rendimiento gratuito.
De todos modos, pensé responder también a la pregunta original : cómo detectar (y posiblemente matar) una consulta de larga duración. En realidad, el motor ya lo hace por ti. Se genera un evento cuando se supera un umbral: Clase de evento de informe de proceso bloqueado . El umbral se configura a través de la Opción de umbral de proceso bloqueado . Cualquier evento de rastreo se puede convertir en una Notificación de evento y las notificaciones de eventos pueden activar los procedimientos . Conecte los puntos y tendrá un código activado a pedido que se ejecutará cuando el motor detecte una consulta que haya cruzado un umbral de tiempo de ejecución. Sin encuestas, sin monitoreo. Tenga en cuenta que la notificación es asincrónica, para cuando la procese, la consulta puede haberse completado, por lo que debe tenerse en cuenta.
Aquí hay un ejemplo:
Ahora, en una nueva consulta, configure una
WAITFOR
espera de una notificación:Y sigue adelante y causa un bloqueo. Utilicé un proceso que creó una tabla y no se confirmó, y desde otra ventana de consulta intenté seleccionar de la tabla. En 20 segundos (mi umbral configurado arriba) recibí el informe de bloqueo:
Dejaré la tarea de concluir esto en un proceso automatizado como ejercicio para el lector. Y sí, el procedimiento de cola / servicio / activado debe estar en
[msdb]
.fuente
Puede crear su propia herramienta de monitoreo o buscar una solución de terceros que pueda proporcionarle una. Si está interesado en crear el suyo, depende de la versión de SQL Server con la que esté trabajando. Si es 2005, puede usar el evento de rastreo Informe de proceso bloqueado . Si está ejecutando 2008 o superior, sugeriría usar el evento extendido equivalente, bloqueado_proceso_informe. Jonathan Kehayias tiene una buena redacción sobre cómo usarlo.
Si está buscando productos de terceros, el Monitor SQL del software Red Gate ha integrado el proceso de bloqueo y las alertas de proceso de larga ejecución.
fuente
Aunque esto no aborda cómo notificarle el problema, este procedimiento le mostrará cómo consultar para ver si existe un bloqueo. También generará comandos kill para usted, si pasa el parámetro correcto.
Espero que esto te dé algunas ideas.
fuente
Sugeriría leer el siguiente tema del foro de MSDN . Se trata del bloqueo causado por el acceso a una base de datos de SQL Server. La sugerencia es principalmente acceder a las tablas mediante consultas utilizando la sugerencia NOLOCK, para que no cause ningún problema de bloqueo. NOLOCK no es la mejor solución, ya que puede causar otros problemas, pero reducirá la mayoría de sus problemas de bloqueo.
La mejor solución sería implementar la idea de Remus, configurar el aislamiento de la instantánea en su base de datos. O implemente el nivel de aislamiento de instantáneas solo para ciertas conexiones que encuentre que causan bloqueo.
Para monitorear adecuadamente su servidor en busca de problemas de bloqueo, sugiero:
Si desea una respuesta proactiva a este problema, en lugar de tener un trabajo cada hora para monitorear los rastros, haga que se ejecute cada minuto y elimine cualquier sesión de acceso de bloqueo líder.
fuente
Siguiendo la excelente respuesta de @Remus Rusanu, he realizado la tarea del lector para conectar el evento a un procedimiento almacenado.
En mi caso, el sp escribirá el xml del evento de bloqueo en una tabla, pero eres libre de hacer lo que quieras en esa posición.
Entonces, siga el código de Remus y cree el
queue
, elservice
y elnotification
con una simple copia / pegar desde arriba. Agregue lassp_configure
opciones y básicamente está configurado.Lo único que queda por hacer son
queue
Tan pronto como active el SP, los eventos comenzarán a fluir a su mesa.
Descubrí que la cola se desactiva automáticamente si el SP tiene un error. En ese caso, debe ir a Server Studio y activarlo nuevamente en el menú contextual de la entrada de cola (
[msdb]->Service Broker->Warteschlangen
en versión alemana).Me llevó bastante tiempo hacer que esto funcionara y encontrar los lugares correctos en la documentación, por lo que supongo que esto también es útil para otros. Estoy usando SQLServer 2005.
Crea el SP sin argumentos
Crear la
pdix_lock_events
tablaActive el SP en el
queue
fuente