Search code examples
sqlsql-serversql-server-2008sql-agent-job

SQL Agent Job: Determine how long it has been running


The Scenario

There are certain SQL Agent Jobs that are scheduled to run every few minutes throughout the day.

There are legitimate times when it will miss its next schedule because it's still running from the previous schedule.

Every once and a while, a job might 'hang'. This doesn't produce a failure (since the job hasn't stopped yet). When this happens, the job can be manually stopped and works fine the next time it runs. It's designed to pick back up where it left off.

What's the most efficient way...?

I'd like a way to determine how long (in seconds) a SQL Agent Job named 'JobX' is currently running. If it isn't currently running, we can just return zero.

This way, I can stop the job if it has been running for an amount of time beyond a certain threshold.

I assume that a combination of xp_sqlagent_enum_jobs and sysjobhistory could be used, but I'm curious if there are better solutions out there... and can hopefully benefit from the obstacles the rest of you have already run into and worked around.


Solution

  • This solution would work:

    SELECT DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds
    FROM msdb..sysjobactivity aj
    JOIN msdb..sysjobs sj on sj.job_id = aj.job_id
    WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running
    AND aj.start_execution_date IS NOT NULL -- job is currently running
    AND sj.name = 'JobX'
    and not exists( -- make sure this is the most recent run
        select 1
        from msdb..sysjobactivity new
        where new.job_id = aj.job_id
        and new.start_execution_date > aj.start_execution_date
    )
    

    This a more general check dependent on system tables. If you'd prefer a custom route, you could have the job insert into a job log table you created instead.