jueves, 11 de agosto de 2011

SQL2008: Entendiendo el Waitresource

Introduccion
Al ver los xml de bloqueos o deadlocks muchas veces aparecen números casi inentendibles, y uno de los importantes es el WAITRESOURCE. Este número codifica que objeto de la base de datos está participando en la pelea por el bloqueo. El recurso puede principalmente ser:
  • Una tabla
  • Una página
  • Una clave
Puede ser algunas cosas mas pero para simplificar el análisis nos enfocaremos en estos.
Manos a la obra
Lo primero que debemos hacer es identificar cual de las tres cosas es, lo cual es fácil leyendo el texto de wait resourse que puede ser:
“OBJECT: 19:1275867612:10”
“PAGE: 12:1:79868773”
“KEY: 12:397371816017920 (760119e06bff)”
En el primer caso es cuando se trata de una tabla. Para este caso (y para los siguientes) lo primero que debemos hacer es analizar el primer número antes del separador (:) . Este número en todos los casos indica el id de la base de datos, por lo tanto debo hacer la siguiente consulta para obtenerla:
SELECT * FROM sys.sysdatabases WHERE Dbid=19
Lo cual me da por resultado Mibase. Recordemos esto porque es común a los tres casos.
Ahora siguiendo con el análisis del primer caso la información brindada se debe analizar de la siguiente manera:

OBJECT: dbId:ObjectId:IndexId
Con la salvedad de que indexId vale 0 cuando se trata del heap y 1 cuando se trata de un índice cluster. En otro caso figurará el número del índice.
Para obtener esta información en un formato útil debería hacer las siguientes consultas:
-- Nota: debo estar situado en MiBase
SELECT OBJECT_NAME(1275867612) 
-- O bien
SELECT * FROM MiBase.sys.all_objects WHERE object_id = 1275867612
-- Y para buscar el índice en caso de ser mayor que 1:
SELECT * FROM MiBase.sys.indexes WHERE object_id=1275867612
De esta forma ya sabemos que table y que índice participaba en el bloqueo.
Para el caso 2 (página) comenzaremos averiguando la base de la misma forma y la siguiente información nos viene como:
PAGE: dbId:FileId:PageId
Si no tenemos nuestra base con varios archivos sino todo en uno del primary el segundo campo siempre será 1.
Para analizar el último debemos obtener la información de la página (79868773 en el ejemplo). Para esto tenemos dos formas:

DBCC TRACEON ( 3604 )
DBCC PAGE (12,1,79868773)
o
DBCC PAGE (12 , 1, 79868773) WITH TABLERESULTS,NO_INFOMSGS
En el primer caso es necesario el traceon porque sino no podemos ver la salida, la cual saldrá en modo texto. En el segundo no es necesario visto que la salida la veremos en modo tabla.
Sea cual fuera el caso que elegimos debemos buscar el renglon (o registro) que tenga la siguiente información:

m_objId (AllocUnitId.idObj) = 1051306955 m_indexId (AllocUnitId.idInd) = 7
y con esto obtengo el ObjectId para poder continuar mi análisis como en el caso anterior.
Por último nos queda el caso del índice (KEY: 12:397371816017920 (760119e06bff)). En este caso debemos leerlo como:

KEY: dbId:hObjecto (hash)
El hash puede ser ignorado, visto que no tenemos función para transformarlo (es la gracia de los hash!), así que nos quedaremos con el hObj. Este número se encuentra almacenado en la msdb así que lo podemos utilizar para calcular el objetcId:

SELECT * FROM MiBase.sys.partitions
WHERE hobt_id = 397371816017920
De esta consulta obtenemos el object_id y podemos hacer nuestro análisis de siempre.

No hay comentarios:

Publicar un comentario