Cómo analizar deadlocktrace en SQLServer
1. La lista de procesos muestra que hay un punto muerto entre dos procesos: proceso60fb88 y proceso 11902 c8.
2.visim-list muestra que el proceso 60fb88 está seleccionado como víctima.
2. La siguiente lista de recursos muestra los recursos por los que dos procesos compiten y provocan un punto muerto.
[html]Ver texto sin formato
& ltdeadlock& gt
& ltvictim list& gt
& ltvictim id de proceso = " proceso 60 FB 88 "/& gt;
& lt/lista de víctimas& gt
& ltlista de procesos& gt
& ltproceso id = " proceso 60 FB 88 " tarea prioridad = " 0 " logused = " 0 " recurso de espera = " KEY:9:72057597664231424(7506 ff 9 b 7 b 0d)" tiempo de espera = " 4376 " OwnerId = " 2656658629 " nombre de transacción = " SELECT " última trans iniciada = " 2014-04-09t 23:065433Net SqlClient Data Provider" nombre de host = " bodcprodvsql 128 " hostpid = " 10088 " nombre de inicio de sesión = " PROD \ s-propdata " nivel de aislamiento = " lectura confirmada (2 )" xactid = " 2656658629 " base de datos actual = " 9 " tiempo de espera de bloqueo = " 4294967295 " opción de cliente 1 = " 67108866
& ltexecutionStack & gt
& ltframe proc name = " " line = " 9 " stmt start = " 336 " STM tend = " 874 " SQL handle = " 0x 030009003 d00 da 3a 6087 c 0182 a 200000010000000000 "/>
& ltframe proc name = " " line = " 20 " stmt start = " 1022 " STM tend = " 1206 " SQL handle = " 0x 03000900941f 284 ed 5929 e 00 ABA 2000000010000000000 "/>
& ltframe proc name = " " line = " 9 " stmt start = " 464 " STM tend = " 642 " identificador SQL = " 0x 03000 a 006502 e 0715 df 5 af 00 ABA 200000010000000000 "/>
& ltframe proc name = " " line = " 4 " stmt start = " 224 " STM tend = " 420 " Identificador SQL = " 0x 01000 a 00 b 6 FCA 934509742900 b 00000000000000000 "/>
& lt/pila de ejecución & gt;
& ltinputbuf & gt
DECLARE @logText NVARCHAR(MAX)
Servicio integrado EXEC _ ProcessLatestCommand @ texto de registro
SALIDA
SELECT @ logText</input buf>
</process>
<process id = "proceso 11902 c8" prioridad de tarea = " 0 " logused = " 232 " recurso de espera = " CLAVE: 9:72057596808265728(ed 2e 944 antes de F9) " tiempo de espera = " 4379 " OwnerId = " 2656658630 " nombre de transacción = " ACTUALIZAR " lastranstarted = " 2014-04 -09t 2Net SqlClient Data Provider " nombre de host = " bodcprodvsql 128 " hostpid = " 1 0088 " nombre de inicio de sesión = " PROD\s-propdata " nivel de aislamiento = " lectura comprometida(2)" xactid = " 2656658630 " base de datos actual = " 9 " lockTimeout = " 4294967295 " opción de cliente 1 = " 67108866
& ltexecutionStack & gt
& ltframe proc name = " " line = " 22 " stmt start = " 1230 " STM tend = " 1496 " SQL handle = " 0x 030009003d 00 da 3a 3fa 6087 c 0182 a 2000000010000000000 "/>
& ltframe proc name = " " line = " 20 " stmt start = " 1022 " STM tend = " 1206 " SQL handle = " 0x 03000900941f 284 ed 5929 e 00 ABA 2000000010000000000 "/>
& ltframe proc name = " " line = " 9 " stmt start = " 464 " STM tend = " 642 " SQL handle = " 0x 03000 a 006502 e 0715 df 5 af 00 ABA 200000010000000000 "/>
& ltframe proc name = " " line = " 4 " stmt start = " 224 " STM tend = " 420 " SQL handle = " 0x 01000 a 00 b 6 FCA 934509742900 b 00000000000000000 "/>
& lt/execution stack & gt;
& ltinputbuf & gt
DECLARAR @logText NVARCHAR(MAX)
Servicio integrado EXEC _ ProcessLatestCommand @ log text OUTPUT
Seleccione @ logText & lt/input buf & gt;
& lt/ proceso>
& lt/pro
cess-list>
& ltresource list>
& ltkey lock Hob tid = " 72057597664231424 " dbid = " 9 " nombre de objeto = " " nombre de índice = " " id = " lockc 99859500 " mode = " " FB 88 " mode = " S " tipo de solicitud = " esperar "/& gt;
& lt/waiter-list >>p>
& lt/bloqueo de teclas & gt;
& ltkey lock vitrocerámica tid = " 72057596808265728 " dbid = " 9 " nombre de objeto = " " nombre de índice = " " id = " bloqueo 2f 4de 2d 00 " modo = " S " ID de objeto asociado = " 72057596808265728 " >;
& lista de propietarios& gt
& ltowner id = " proceso 60 FB 88 " modo = " S "/& gt.
& lt/owner-list>
& ltwaiter-list>
& ltwaiter id = " proceso 11902 c8 " modo = " X " tipo de solicitud = " esperar "/& gt;
& lt/waiter-list >>p>
& lt/bloqueo de teclas & gt;
& lt/resource -list>
& lt/deadlock>
El siguiente es un análisis detallado.
1. La lista de víctimas no es nada que analizar.
2. La información detallada de cada proceso en la lista de procesos es muy importante.
espera recurso = " KEY:9:72057597664231424(7506 ff 9 b 7 b 0d)"
El recurso que está esperando el proceso actual. Normalmente podemos ver la misma información en la lista de recursos. Utilice la siguiente consulta SQL para averiguar qué recursos están esperando:
El Hobtid utilizado a continuación es la abreviatura de heap o b-tree id. Consulte la descripción de sys.partotions para obtener más detalles.
[sql]Ver copia ordinaria
Seleccione o.name, i.name
De la partición del sistema p
En p.object_id = o.object_id en sys.objects o
Únete a sys.indexes en p.object_id = i.object_id i
y p.index_id = i.index_id
Donde p.hobt_id = 72057597664231
Nombre nombre
-
ID principal del key_matcher del servicio de coincidencia
De los resultados podemos saber que el recurso que se esperará es la clave principal PK_Matcher_ID de una tabla MatchService. Al observar el recurso de espera de otro proceso, podemos saber que el recurso de espera es otro índice de la misma tabla. Hasta ahora, hemos encontrado los recursos que causaron directamente el punto muerto.
Puedes ver dos procesos al mismo tiempo, uno con bloqueo x y otro con bloqueo s. Por lo tanto, se puede determinar que se produce un punto muerto entre la declaración de modificación y la declaración de consulta en la tabla.
Además, el punto muerto causado por el bloqueo de teclas se puede ver claramente en el ejemplo anterior, por lo que el objeto correspondiente (sys.partitions contiene una fila para cada partición en todas las particiones) se puede encontrar consultando las particiones.
Tablas y mayoría de tipos de índices en una base de datos. ). Pero a veces otros tipos de recursos también pueden bloquearse, como bloqueo de página, espera recurso = " página:9:1:28440841 ". 9 es dbid1 es fileid28440841 es pageid. En este caso, utilice la siguiente declaración para consultar el recurso correspondiente:
[sql]Ver copia ordinaria
DBCC Teresian (3604)
Ir
Página DBCC (9, 1, 28440841)
Ir
Trazabilidad DBCC (3604)
Ir
Encontrar el correspondiente objectId:objectId de los metadatos devueltos.
3. Mire el inputbuf en el proceso. Esta etiqueta representa la declaración de que el proceso se está ejecutando y, por lo tanto, es importante para localizar puntos muertos. Pero hay un problema aquí, por ejemplo
En el ejemplo anterior, inputbuf es un procedimiento almacenado con muchos otros procedimientos almacenados anidados en él, pero inputbuf es el sql enviado directamente por el usuario. fuera de lo cual directo resultando en muerte.
Bloquee declaraciones y optimícelas para resolver o reducir puntos muertos. De ahora en adelante, tenemos la información de que la declaración que causó el punto muerto fue llamada por la declaración en inputbuf. La declaración que causó el punto muerto debe ser una tabla.
Declaración de modificación de MatchService. Si el procedimiento almacenado es simple, el DBA puede encontrar el SQL que causa directamente el punto muerto y el proceso de análisis termina aquí. Si el procedimiento almacenado es complejo, entonces
se requiere un análisis más detallado.
4. Ahora echemos un vistazo más de cerca a la etiqueta ejecuciónStack. ExecutionStack muestra la serie de llamadas realizadas por inputbuf cuando se produce un punto muerto.
sql.Hay 4 sql en el ejemplo anterior. Al mismo tiempo, si observa atentamente el ejemplo anterior, puede encontrar que la pila de ejecución de los dos procesos es exactamente la misma, por lo que basta con examinar uno. Además,
Si procname no está vacío, el sql se obtiene directamente, pero la etiqueta en el ejemplo anterior está vacía.
Después de esto, queremos mostrar todos los SQL en la pila de ejecución. Utilice el siguiente sql para encontrar el sql correspondiente a sqlhandle en la memoria. Cabe señalar que
Pero si el punto muerto ha pasado por un período de tiempo, es posible que el sqlhandle se haya borrado de la memoria y no se pueda encontrar en este momento. El identificador sql es
Varbinaryd, por lo que no se pueden utilizar comillas al realizar consultas.
Hay otro punto interesante: al igual que otros lenguajes de programación, la parte superior de la pila es el error más directo, y los errores detrás son los errores en el siguiente nivel del error (esta explicación puede ser un poco
Es confuso, los estudiantes que han escrito código pueden entenderlo. Entonces, cuando el procedimiento almacenado llama al procedimiento almacenado mencionado anteriormente, el primer elemento en la pila de ejecución es el SQL que causa directamente el punto muerto.
Agregue el sql de este sql, y así sucesivamente. El último es teóricamente el sql en inputbuf.
[sql] Ver copia ordinaria
Seleccione sql_handle como identificador.
SUBSTRING(st.text, (QS . declaración _ inicio _ offset/2)+1,
((CASE qs.statement_end_offset
cuando -1 cuando, entonces DATALENGTH(st.text)
De lo contrario qs.statement_end_offset
END-QS declaración _ start _ offset)/2)+1) como texto
Desde sys.dm_exec_query_stats AS qs
Aplicación cruzada sys.DM_exec_SQL_text(QS.SQL_handle) AS st
donde SQL_handle = 0x 030009003 d00 da 3 fa 6087 c 0182 a 20000010000000000 p>
Ordenar por sql_handle
- -
0x 030009003d 00 da 3a fa 6087 c 0182 a 20000001000000000000 select
TOP 1 @matcherQueueID = lhs. MatcherService_MatcherQueue_ID,
@Root UID de operación = Root_Operation_UID FROM
MatcherService_MatcherQueue lhs donde lhs Processing_State = 'MATCHED' o lhs Processing_State = 'MATCHED' Ordenar por
Fecha de última ejecución
0x 030009003d 00 da 3 fa 6087 c 0182 a 20000001000000000000
Seleccione Top 1 de GEDemo.dbo.OperationLog @ ticket ID = registro de operación _ ID
Donde @Root Operación UID = Raíz _ Operación _ UID, Estado = 0
Ordenar por proceso Log_ID ASC
0x 030009003d 00 da 3 fa 6087 c 0182 a 20000001000000000000
ACTUALIZAR servicio de comparación _ cola de comparación SET Última _ Ejecución _ Fecha =
GETDATE(), donde servicio de comparación _ cola de comparación _ ID = @ ID de cola de comparación
Tenga en cuenta que Parece que un sql_handle tiene tres declaraciones, porque estos tres sql pertenecen al mismo procedimiento almacenado.
Si un sql_handle contiene muchas declaraciones, como un procedimiento almacenado largo, entonces también podemos usar un mensaje poderoso: la etiqueta
line
. Esta declaración muestra qué SQL causó directamente el punto muerto. Si una declaración contiene muchas tablas, se necesita una combinación de recursos de interbloqueo para determinar qué tabla o.
Los datos indexados están bloqueados.