lunes, 26 de julio de 2010

Jobs Matusalén (Procesos colgados)

Un tema interesante que se me presentó hace unos meses fue encontrar un job que llevaba corriendo una semana y como ningún usuario reclamó nada pasó desapercibido. Ahí fue que decidí tomar una acción preventiva para estos casos. Cuando configuramos nuestras tareas de mantenimiento o control lo mas normal es que utilicemos jobs. Los jobs si ejecutan de forma correcta podemos configurar que nos mande un mail, o lo que es mas habitual, podemos configurar que nos envíe mail cuando falla (a nosotros o cualquier operador del SQL). El problema es que pasa cuando el proceso queda colgado, por lo tanto no recibimos ni mail de ok, ni mensaje de error y es muy probable que no nos demos cuenta.
Con la intención de alertar esta situación generé un job que se ejecute cada 15 minutos y controle todos los jobs que se encuentran vivos hace cuanto tiempo lo están. La forma de implementarlo fue hacer un procedimiento que para cada job que se encuentra corriendo hace mucho genere una excepción, y en caso contrario no haga nada, de esta forma puedo en mi job de control programar la alerta de mail y que la reciban todos los administradores.
Para obtener los jobs vivos utilicé "xp_sqlagent_enum_jobs", que es medio tramposa así que tengan en cuenta que deben pasarle como primer parámetro 0 y el segundo parametro no interesa pero debe ser algún texto (no importa cual). Esto se debe a que el primer parámetro hace que se ignore el segundo pero igual lo exije.
El resultado de esa consulta nos retorna jobs_id así que deberemos cruzarla con "msdb.dbo.sysjobs" y "msdb.dbo.sysjobactivity" para transoformala en algo humanamente entendible.
La pregunta interesante es la siguiente: cuando consideramos que un job está tardando? La mejor solución asumí que es basarnos en el historial. Por suerte contamos con la tabla msdb.dbo.sysjobhistory. Un error común podría ser querer promediar el tiempo que ahí se encuentra y generar una alerta cada vez que el job tarda mas que ese promedio. ERROR. ¿por que es esto incorrecto? porque si un job a veces tarda 58min y a veces 1hs 2min, no suena razonable que pasada una hora alerte que ocurrió un error, sino la mitad de las veces recibiría el mail, y bien sabemos que un mail que llega seguido termina siendo ignorado con las posibles consecuencías que esto trae. Por eso es necesario basarnos en la matemática y averiguar el desvio estandar de nuestra muestra, y calcular cual es el tiempo esperado tal que un 90% de los casos alcanza a terminar, asumiendo que el tiempo esperado suele ser de la forma valor esperado + error, teniendo el error una distrinución Gaussiana.
En la impementación me pareció bueno meter esto en otra tabla y actualizarla períodicamente con otro job que se encargue de calcular los tiempos (una vez por semana por ejemplo) y el job de control consulte estos tiempos. Una de las partes mas molestas de implementar esto es que la job_history no tiene un formato muy amigable para los tiempos, les recomiendo que lo calculen con una función y la tengan a mano porque sirve para muchas cosas y es muy molesta de rehacer.
Espero haber sido claro, si alguién desea el código puede enviarme un mensaje privado.

No hay comentarios:

Publicar un comentario