Jefferson Elias

¿Cuáles son los interbloqueos de SQL Server y cómo ellos se pueden monitorear?

November 6, 2019 by

Introducción

Como administradores de bases de datos, frecuentemente me he enfrentado más que nada con problemas de rendimiento. A veces, el código mal escrito o la falta de índices generarán las condiciones de bloqueo a las que nos referimos como un “interbloqueo “. En razón a que debido a su naturaleza y al igual que cualquier situación de bloqueo similar, los interbloqueos pueden tener un impacto directo en la experiencia del usuario y cuanto más ocurran, mayor será efecto y consecuencia de dicho impacto.

Este artículo es el primero de una serie que se centrará en problemas e informes de interbloqueo. Después de leer este artículo, usted estará en condiciones de poder explicar cómo puede ocurrir un interbloqueo y cómo podemos obtener información ampliada sobre este interbloqueo de tal forma que las podamos diagnosticar y tomar las medidas apropiadas. Estas acciones conducirían ya sea a una menor frecuencia de ocurrencia o una desaparición total de las condiciones de interbloqueo.

Entonces, en las siguientes secciones, trataremos de comprender, básicamente, en que consiste el tener un interbloqueo y cómo ocurre con un ejemplo práctico en T-SQL. Posteriormente veremos que SQL Server realmente dispone de algunas herramientas para ayudar a detectar la aparición de dichos interbloqueos y sus ocurrencias y obtener todo lo que necesitamos para encontrarlo y solucionarlo, aunque podríamos también ver que la solución podría ser más simple de decirlo que de hacerlo.

Comprensión básica

Comprensión intuitiva

Entonces, definiremos ¿qué es un “interbloqueo”? Etimológicamente, se puede entender como que se puede dividir en dos palabras raíz: “inter” (muerto en inglés) y “bloqueo”. Podríamos entenderlo intuitivamente como un bloqueo que conduce a un callejón sin salida

Vale la pena indicar que, en los sistemas de gestión de bases de datos relacionales, el mencionar bloqueo es un mecanismo que ocurre recurrentemente cada vez. En realidad, podemos adquirir un bloqueo en diferentes tipos de recursos (identificador de fila, clave, página, tabla …) y que además se podrá utilizar diferentes modos (compartido, exclusivo …). Elegir un modo en lugar de otro para acceder a un recurso determinado en una sesión permitirá que otras sesiones (o transacciones) accedan al mismo recurso o hará que otras sesiones esperen a que se desbloquee ese recurso. Por esta razón es que podemos observar que no todos los modos de bloqueo son compatibles. Por esa razón, Microsoft proporcionó una página de documentación sobre lo que llaman compatibilidad de bloqueo.

Aun así, de esta manera, intuitivamente, podríamos decir que un interbloqueo cae en el segundo caso, que es el que les dice a otras sesiones que esperen a un recurso, pero esta espera podría nunca terminar. En este segundo caso es que se conoce comúnmente como “bloqueo”. Para tal fin nosotros deberemos tomarnos un tiempo para comprender el bloqueo antes de hablar de interbloqueos, ya que parecen ser el peor caso de bloqueo.

Comprender el bloqueo

Una situación de bloqueo se puede entender con el siguiente ejemplo.

Supongamos que tenemos dos de bases de datos usuarios ya conectados a SQL Server usando una aplicación: UsuarioA y UsuarioB.

El usuario A está editando actualmente una factura, lo que implica una instrucción UPDATE contra una tabla Invoice con una cláusula WHERE que restringe a un valor particular de la columna InvoiceId de esa tabla. En consecuencia, para poder realizar esta operación, el hilo conector asociado a esa sesión dentro del motor de base de datos de SQL Server tiene que adquirir y retener:

  • Un bloqueo de intención exclusiva (IX) en la tabla Facturay en la página, que contiene la fila que el usuarioA está editando. Este bloqueo se utiliza para establecer una jerarquía de bloqueo para realizar modificaciones de datos.
  • Se está editando un bloqueo Exclusivo (X) en la fila UsuarioA. Esto significa que la sesión será la única que podrá modificar esa fila hasta que libere este bloqueo

Al mismo tiempo, el usuario de UserB quiere obtener una lista de las facturas para el presente mes actual y, desafortunadamente, la factura que UserA está editando se encuentra en esa lista. En consecuencia, el UserB‘s hilo conductor efectuara las siguientes acciones:

  • Usted debe adquirir un bloqueo de intención compartida (IS) en la tabla Factura. Este bloqueo se utiliza para establecer una jerarquía de bloqueo para realizar operaciones de solo lectura. Esto funcionará ya que IX e IS en una tabla son compatibles.
  • Usted debe intentar un bloqueo compartido (S) en las páginas necesarias para mostrar la lista. Entre ellos, la página con un candado X adquirido por UserA. Vale la pena mencionar, sin embargo, que los bloqueos compartidos y exclusivos son incompatibles (incluso semánticamente). Por esta razón es que esto significa que el hilo cuidando de UserB’s sesión tiene que esperar a que la sesión del UserA’s pueda liberar este bloqueo X. Hasta que eso suceda, podemos decir que la sesión de UserB está bloqueada por la sesión de

La situación se puede resumir gráficamente de la siguiente manera:

Esta situación terminará tan pronto como se haya completado la consulta ACTUALIZACIÓN y el UserA haya confirmado su transacción

Como se puede esperar, podemos encontrar situaciones mucho más complejas, que involucran sesiones con múltiples bloqueos en el uso de múltiples recursos. Sin embargo, cuando se produce el bloqueo, y utilizando la consulta adecuada, podremos obtener una vista general del bloqueo como la siguiente:

En este ejemplo, señalaríamos con precisión tres sesiones de bloqueo (59, 79, 145) pero como la sesión con id 145 está bloqueada por la sesión con id 59, en realidad hay dos “sesiones de bloqueo superiores” (59 y 79). Estos se llaman “encabezadores de bloqueadores ” mientras que las otras sesiones se llaman ” en espera “.

Entendiendo los interbloqueos

Pese a que en circunstancias tales como esta, Aunque se basa en los mismos principios, los interbloqueos son diferentes del bloqueo. En realidad, cuando ocurre una situación de interbloqueo, no hay un encabezador de bloqueo identificable ya que ambas sesiones implican bloqueos incompatibles en los objetos a los que la otra sesión necesita acceder. Este es un proceso de Es una cadena de bloqueo circular.

Para una mejor comprensión de este tema debemos volver a, la situación que usamos para bloquear la presentación y agregaremos adicionalmente algo de complejidad a esa situación.

Supongamos que para modificar una fila en la tabla Factura es importante para el Usuario que también debe leer una tabla InvoiceDetails de tal forma que pueda obtener el total que se factura al cliente. Digamos que, sin importar la razón, UserBya ha adquirido un bloqueo exclusivo en una página que contiene una fila de la tabla InvoiceDetails que UserA necesita leer.

En tal caso, nos hallamos en una situación tal que la misma está representada en la siguiente figura. (Como recordatorio, el verde se usa para referirse al Usuario A y el naranja para el Usuario B)

Tal como se indica a continuación se puede apreciar en la figura anterior, que ambos subprocesos esperan un bloqueo que nunca se liberará, ya que la actividad de uno se suspende hasta que el otro libera sus bloqueos adquiridos. En esta situación, puede ser más complicado en la vida real y yo me permitiría sugerir a los interesados en el tema que busquen en la web recursos como el escrito por Minette Steynberg en 2016 titulado ¿Qué es un interbloqueo de SQL Server?

Afortunadamente, el motor de base de datos de SQL Server viene con un subproceso de monitor de interbloqueo que verificará periódicamente las situaciones de interbloqueo, para tal fin usted deberá elegir uno de los procesos implicados como víctima para la terminación. Si bien este es un buen punto para una de las sesiones, no es para la otra. La “víctima” en realidad termina con un error y debe ejecutarse nuevamente.

Aquí hay más información adicional sobre el hilo conductor para el monitor de interbloqueo:

  • Se ejecuta cada 5 segundos por defecto
  • Cuando detecta un interbloqueo, este intervalo cae de 5 segundos a tan solo 100 milisegundos en función de la frecuencia de los interbloqueos.
  • Cuando finalmente no encuentra un interbloqueo, pone el intervalo a su valor predeterminado de 5 segundos
  • • Una vez que se elige la víctima de interbloqueo, revertirá la transacción de esta víctima y devolverá un mensaje de error 1205 al usuario. El error de mensaje se ve como sigue

    La transacción (ID de proceso 89) se bloqueó en los recursos con otro proceso y se ha elegido como víctima del bloqueo. Vuelva a ejecutar la transacción

  • Por defecto, la víctima de interbloqueo es elegida en función de la cantidad estimada de consumo de recursos para la ejecución en reversa o sea se debe retroceder. Esta opción que se elige es la de menor costo. Podemos usar la declaración SET DEADLOCK_PRIORITY <Value> para influir en la elección de la víctima de interbloqueo.

Interbloqueo en acción

En esta sección, implementaremos el ejemplo explicado anteriormente en T-SQL y comprobaremos que la explicación corresponde a lo que realmente sucede en el mundo real.

En este ejemplo, tenemos 2 tablas: Las facturas y InvoiceDetails. Construiremos estas tablas basadas en la base de datos AdventureWorks.

En la actualidad, la primera sesión, que representa al UserA en el ejemplo, se ejecutará a continuación de la instrucción correspondiente. Tenga en cuenta que no hay previsto ningún compromiso.

Podemos verificar que la transacción aún esté abierta, por lo que no se revierte ni se confirma mediante la siguiente consulta:

Ahora, usted debe verificar que ejecutemos la siguiente instrucción en otra sesión la que desempeñará el papel de UserBen nuestro ejemplo.

Si ahora, ejecutamos la siguiente declaración en la primera sesión (UserA):

Luego, cualquiera de las sesiones (UserA o UserB)) se marcará como interbloqueo. En mi caso, fue la sesión del usuario.

En el Caso de que, Si retrocedemos, nada debería haber cambiado para SalesOrderId #43659.

¿Cómo hacer un seguimiento solamente de las apariciones de interbloqueos?

Bueno, ahora sabemos qué es un interbloqueo y el error 1205 es provocado por el hilo conductor del monitor Deadlock. Si solo necesitamos obtener una descripción general de las apariciones u ocurrencias de interbloqueo durante un intervalo temporizado, podríamos ejecutar la siguiente instrucción en una instancia de SQL Server:

Esta instrucción le indicará a SQL Server que registre cualquier mensaje de error 1205 en el registro de errores de SQL Server. Usando el procedimiento almacenado xp_readerrorlog entonces nosotros podremos leer este registro y recuperar solo los registros de error 1205

Cómo realizar un seguimiento de los detalles de interbloqueos

Opción 1: Banderas de seguimiento 1204 y 1222

Es importante mencionar que los administradores de bases de datos pueden indicarle a SQL Server que cambie (temporalmente) su comportamiento al especificar un indicador de rastreo. En este caso, estas marcas de rastreo se habilitan y deshabilitan utilizando las siguientes instrucciones:

Una forma alternativa de habilitar las marcas de seguimiento es definiéndolas como parámetros de inicio para el servicio SQL Server:

Tenga en cuenta que esto requiere un reinicio de los servicios de SQL Server.

Hay dos indicadores de seguimiento o interés para el monitoreo de interbloqueo: 1204 y 1222.

Es importante mencionar que, según la documentación en el sitio web de Microsoft, en este caso el primero le indicará a SQL Server que devuelva los recursos y los tipos de bloqueo que participan en un interbloqueo y también el comando actual afectado, y posteriormente mientras que el segundo devuelve los recursos y tipos de bloqueo que participan en un interbloqueo y también el comando actual afectado en un formato XML..

Vale la pena mencionar que básicamente, ambos hacen el mismo trabajo y recomendaría usar el indicador de rastreo 1222 con preferencia al primero, ya que generará un XML que es más fácil de analizar e integrar.

La salida de datos de ambos indicadores de seguimiento será visible en el registro de errores de SQL Server.

Como se podrá observar, ésta es una forma antigua de obtener información de interbloqueo y solo es factible recomendar en el caso de que se lo utilice cuando los otros métodos no estén disponibles. Además, necesitaremos construir un analizador específico para extraer datos para un análisis posterior.

Opción 2: SQL Server Profiler y SQL Server Trace

Esta también es una forma antigua de obtener información detallada sobre las situaciones de apariciones de interbloqueo introducidas en SQL Server 2005. Esta parece ser la más utilizada por los desarrolladores y los administradores de bases de datos.

Abrimos SQL Server Profiler y creamos una nueva traza de seguimiento con el elemento seleccionado Gráfico de bloqueo/interbloqueo:

Cuando se selecciona este elemento, podemos ir a la tercera pestaña y especificar ya sea si guardar los eventos XML de interbloqueo en un archivo de resultados separado. Así mismo tendríamos que analizar este archivo con un script o realizar la ejecución de otra cosa.

Este método es simple y proporciona resultados que podemos usar con bastante facilidad para investigar interbloqueos. También podemos ejecutar el código equivalente de T-SQL para generar el seguimiento.

Nota: Esta solución puede afectar el rendimiento, debido a que deberá utilizar recursos adicionales para recopilar y proporcionar información de interbloqueo al usuario. Como tal, esta no es la solución opcional.

Opción 3: Eventos extendidos y sesión system_health

En SQL Server 2008, se introdujeron los eventos extendidos y se definió una sesión predeterminada de eventos extendidos llamadasystem_health Claramente se puede observar que esta sesión comienza automáticamente con el Motor de base de datos de SQL Server y recopila datos del sistema para ayudar a los administradores de bases de datos a resolver problemas de rendimiento.

En realidad, usted debe ver que al recopilar información sobre cualquier interbloqueo detectado en archivos XEL. nosotros podremos extraer información de estos archivos, ya sea:

  • usando vistas y funciones de Dynamic Management;
  • utilizando la función proporcionada por Microsoft para leer datos de un archivo de sesión de eventos extendidos:

Esta recolección de datos está totalmente integrada y no daña el rendimiento.

A continuación, encontrará un ejemplo de consulta para obtener un interbloqueo XML de la sesión system_health.

Este script también puede ejecutarse contra otra sesión de eventos extendidos como la de la siguiente subsección.

Opción 4: Sesión de eventos extendidos personalizados

Extended Events es un comando de mucha importancia ya que es una gran característica en la que definimos los eventos y la información asociada que queremos recopilar.

A partir de SQL Server 2012, SQL Server Management Studio (SSMS) nos proporcionara de una interfaz gráfica de usuario para trabajar con eventos extendidos. Por tal motivo, revisaremos los pasos para crear un evento extendido personalizado que hará un seguimiento del gráfico de interbloqueo con información extendida. Es importante mencionar que para los usuarios que aman T-SQL, también se les proporcionará el código generado.

Es importante mencionar que desafortunadamente, esta solución no funcionará en versiones anteriores a SQL Server 2012 sin adaptaciones al script así generado.

En el retorno del manejo y la administración de SSMS se tiene que tener una visión global o en la vista de árbol de una conexión de SQL Server. Para tal fin, usted deberá expandir la siguiente vista y luego haga clic derecho en “Sesiones” para abrir un menú.

Haga clic en “Nueva sesión”

Se mostrarán las siguientes ventanas. Rellene la información que desee. Usted deberá observar que marqué dos casillas de verificación en “Programar:”.

Ahora establecemos parámetros generales, seleccionemos eventos. Hay un filtro en la vista de eventos que nos ayudará a obtener solo la lista de eventos relacionados con interbloqueos.

Solo deberíamos necesitar el evento xml_deadlock_report y podemos hacer doble clic en él o hacer clic en el signo ” >“. Una vez hecho, este evento aparecerá en la lista de “Eventos seleccionados”. Lo que sucede en la realidad, un elemento de esta lista se puede personalizar haciendo doble clic en él. Entonces, si hacemos doble clic en xml_deadlock_report o si seleccionamos un elemento y hacemos clic en el botón “Configurar” en la esquina superior derecha, la interfaz cambiará a un panel de edición de eventos de la siguiente manera:

Observe que, si vamos a la pestaña “Campos globales”, entonces podremos agregar acciones y, por lo tanto, información a nuestra colección de eventos.

Una vez que hayamos terminado con esta sección, nosotros podremos ir a la página de almacenamiento de datos y decirle a SQL Server dónde puede almacenar los resultados. En general, tomaremos un archivo como producto de salida.

Finalmente, podemos revisar la configuración avanzada para esta sesión de eventos extendidos.

Luego, haga clic en Aceptar.

Aquí está el script T-SQL equivalente para crear el evento Collect-Deadlock:

Es importante mencionar que para que esta solución funcione en versiones de SQL Server anteriores a SQL Server 2012, nosotros deberemos necesitar cambiar

By

En algunas versiones de SQL Server, la función sys.fn_xe_file_target_read_file llamador para proporcionar el valor no nulo para el segundo parámetro. Este parámetro hace referencia a la ruta a un archivo de descripción con una extensión XEM. De hecho, en esta circunstancia podremos modificar la definición de destino para que se vea así:

Lo que permite su funcionamiento para SQL Server 2008 y 2008 R2:

Ahora, pasaremos a revisar algunas operaciones en este evento.

Para evitar que se ejecute un evento extendido, ejecute las siguientes consultas:

Para restablecerlo a un estado de ejecución, ejecute la siguiente consulta:

Y para abandonar por completo la sesión del evento:

Yo me permitiría recomendar el usar esta opción por sobre la opción #3 debido a que toma mucho menos tiempo obtener información simple usando la consulta previa. Podemos mencionar que, como ejemplo, en mi servidor de prueba, para obtener una fila de system_health, me llevó más de 15 segundos mientras que esta solución me llevó menos de un segundo.

Adicionalmente, además, una cosa realmente importante y genial de esta opción es que cuando creé esta sesión, la misma sesión retiró los interbloqueos que ocurrieron antes de su creación.

Palabras adicionales sobre colecciones de eventos extendidos

Presta atención a los formatos de hora.

Como resultado de todos mis experimentos, debemos tener cuidado cuando queramos recopilar datos de eventos extendidos basados en ring_buffer y adicionalmente queremos filtrar (o simplemente mostrar) información de tiempo.

En realidad, esta información se almacena en formato UTC de la hora internacional y debemos convertirla a la hora local antes de usarla.

Adicionalmente yo traté de transformar este formato usando el siguiente código:

O

Pero no logre obtener el tiempo real como verán en la siguiente captura de pantalla. En el lado izquierdo, están los resultados de DateStamp ordenados de la consulta presentada anteriormente para recuperar la información de interbloqueo. En el lado derecho, los resultados de la opción 1 (Indicadores de seguimiento).

Nota: Hay un error abierto en Microsoft Connect respecto a las diferencias de fecha y hora.

Vale la pena mencionar que existe un método simple de recopilación de información y el mismo está disponible en SQLShack.

No importa si toma información de interbloqueo de system_health o de una sesión de evento casera, usted puede consultar el artículo de Musab Umair titulado Supervisión de interbloqueos de SQL Server: la manera fácil. Esta situación se define en un método simple para extraer alguna información de interbloqueo de archivos de eventos extendidos.

Resumen

Como se podrá observar en esta sección analizada, Hasta ahora, hemos visto qué es un interbloqueo y cómo recopilar información sobre ellos utilizando múltiples enfoques. Por consiguiente, La siguiente tabla resume lo que podríamos esperar de cada una de estas formas.

Opción# Nombre de opción Funciona desde antes de 2008 Funciona desde antes de 2012 Automatizado Requiere activación Impacto de Performance Salida de
análisis útil
1 Trace flags X X X X
2 SQL Server Profiler and SQL Trace X X X X X
3 Default Extended Events Session (system_health) X X X
4 Custom Extended Events Session X X

En el próximo artículo, , veremos más de cerca qué tipo de informes podemos realizar para iniciar una búsqueda para lograr encontrar y ejecutar soluciones contra las situaciones de bloqueo. También veremos de cerca el procedimiento almacenado utilizado para obtener esos informes.

Próximos artículos de esta serie:

Jefferson Elias
Interbloqueos, Monitoreo

Acerca de Jefferson Elias

Viviendo en Bélgica, obtuve un grado de maestría en Ciencias de la Computación en 2001 en la Universidad de Lieja. Soy uno de los raros tipos que empezó a trabajar como DBA inmediatamente después de su graduación. Así que, trabajo en el hospital de la universidad de Lieja desde 2011. Inicialmente involucrado en la administración de Bases de Datos Oracle (las cuales aún están bajo mi cargo), tuve la oportunidad de aprender y manejar instancias de SQL Server en 2013. Desde 2013, he aprendido mucho acerca de SQL Server en administración y desarrollo. Me gusta el trabajo de DBA porque uno necesita tener un conocimiento general en cada campo de IT. Esa es la razón por la que no pararé de aprender (y compartir) los productos de mis aprendizajes. Ver todas las entradas de Jefferson Elias

168 Views