Identificare i Jobs di Sql Server troppo lenti

Di quando in quando succede che un job di Sql Server resti “appeso” durante la sua esecuzione; la cosa di per sé potrebbe anche essere insignificante (cosa sarà mai un misero processo in confronto all’universo?) se non fosse che, come conseguenza di ciò, ne derive il blocco sicuramente di quel processo aziendale e probabilmente anche di qualche altro che si ritrova delle risorse bloccate. Dal momento che i nostri stipendi sono comunque composti di poche misere componenti, che danno come risultato anche poveri, miseri, tristi totali ); abbiamo pensato di creare un script che ci permettesse di identificare il job caduto in letargo.

Lo script si base su una nostra vecchia (si fa per dire) conoscenza, la dbo.SysJobsSteps, ed una nuova, la dbo.SysJobHistory, che riporta la data, la durata e soprattutto lo stato dell’ultima esecuzione. Quest’ultimo è un enumerativo che ho descritto nel corpo dello script stesso; in particolare a noi interessa individuare i record che identificano gli step che abbiano una durata che abbiamo arbitrariamente definito come “eccessiva” (nello script riportato sotto sono 300 secondi o se preferite 5 minuti) e siano ancora in stato 4 "In progress".

DISCLAIMER (o se preferite in italiano: UNA PRECISAZIONE MOLTO IMPORTANTE): questo script vi AIUTA ad indentificare i processi SOSPETTI, ma NON identifica CON ASSOLUTA CERTEZZA i processi bloccati. Starà al vostro buon senso analizzare i risultati della query per escludere i falsi positivi (sì, ce ne possono essere: anzi, nella nostra realtà aziendale ce ne sono diversi) e identificare i processi realmente bloccati, se ce ne sono. Purtroppo per voi (fortunatamente per noi) al momento non posso fornirvi un esempio di risultato in presenza di processi bloccati per il semplice motivo che … non ce ne sono.

/* --- Identificazione processi troppo lunghi
    --- v. 1.0
    --- 2013.01.17
    --- Marco Turrini
    --- Visualizza i processi di Sql Server (Jobs) in esecuzione da troppi secondi
*/
DECLARE @threshold int;
SET @threshold = 300; -- numero di secondi limite per l'identificazione dei jobs

SELECT [Job] = [Jobs].[name]
      , [Id] = [Steps].[step_id]
     , [Step] = [Steps].[step_name]
     , [Status] = CASE [History].[run_status]
                  WHEN 0 THEN '*** FAILED ***'
                  WHEN 1 THEN 'Succeeded'
                  WHEN 2 THEN 'Retry'
                  WHEN 3 THEN 'Canceled'
                  WHEN 4 THEN 'In progress'
                  ELSE 'Unknown'
                  END
     , [Ultima Esecuzione] = Convert( datetime, RTrim( [History].[run_date] ) )
                             + ( [History].[run_time] * 9
                             + [History].[run_time] % 10000 * 6
                             + [History].[run_time] % 100 * 10
                             ) / 216e4
     , [Durata] = Left( Right( '000000' + Convert( varchar(6), [History].[run_duration] ), 6 ), 2) + ':'
                + SubString( Right( '000000' + Convert( varchar(6), [History].[run_duration] ), 6 ), 3, 2 ) + ':'
                + Right( Right( '000000' + Convert( varchar(6), [History].[run_duration] ), 6 ), 2)
     , [Risultato] = CASE [Steps].[last_run_outcome]
                     WHEN 0 THEN 'Failed'
                     WHEN 1 THEN 'Succeeded'
                     WHEN 2 THEN 'Retry'
                     WHEN 3 THEN 'Canceled'
                     ELSE 'Unknown'
                     END
     , [Tentativi] = [Steps].[last_run_retries]
 FROM [msdb].[dbo[.[SysJobSteps] [Steps]
 INNER JOIN [msdb].[dbo].[sysjobs] [Jobs]
    ON [Jobs].[job_id] = [Steps].[job_id]
 INNER JOIN msdb.dbo.SysJobHistory [History]
    ON [History].[job_id] = [Steps].[job_id]
   AND [History].[step_id] = [Steps].[step_id]
 WHERE [last_run_duration] > @threshold
   AND [run_status] = 4

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*