Как я могу определить статус работы? - PullRequest
42 голосов
/ 14 октября 2008

У меня есть хранимая процедура, которая планирует работу. Выполнение этой работы занимает много времени (от 30 до 40 минут). Мне нужно узнать статус этой работы. Ниже детали помогут мне

1) Как просмотреть список всех заданий, которые запланированы на будущее и которые еще не запущены

2) Как просмотреть список запущенных заданий и промежуток времени с момента их запуска

3) Как узнать, успешно ли выполнено задание или оно было остановлено в промежутке из-за какой-либо ошибки.

Ответы [ 13 ]

74 голосов
/ 05 августа 2013

Я хотел бы отметить, что ни один из T-SQL на этой странице не будет работать именно потому, что ни один из них не присоединяется к таблице syssessions , чтобы получить только текущий сеанс и, следовательно, может включать ложные срабатывания.

См. Это для справки: Что значит иметь задания с нулевой датой окончания?

Вы также можете проверить это, проанализировав процедуру sp_help_jobactivity в msdb .

Я понимаю, что это старое сообщение в SO, но я нашел это сообщение только частично полезным из-за проблемы.

SELECT
    job.name, 
    job.job_id, 
    job.originating_server, 
    activity.run_requested_date, 
    DATEDIFF( SECOND, activity.run_requested_date, GETDATE() ) as Elapsed
FROM 
    msdb.dbo.sysjobs_view job
JOIN
    msdb.dbo.sysjobactivity activity
ON 
    job.job_id = activity.job_id
JOIN
    msdb.dbo.syssessions sess
ON
    sess.session_id = activity.session_id
JOIN
(
    SELECT
        MAX( agent_start_date ) AS max_agent_start_date
    FROM
        msdb.dbo.syssessions
) sess_max
ON
    sess.agent_start_date = sess_max.max_agent_start_date
WHERE 
    run_requested_date IS NOT NULL AND stop_execution_date IS NULL
44 голосов
/ 14 октября 2008

Вы можете попробовать использовать системную хранимую процедуру sp_help_job. Это возвращает информацию о работе, ее шагах, расписаниях и серверах. Например

EXEC msdb.dbo.sp_help_job @Job_name = 'Your Job Name'

Электронная документация по SQL должна содержать много информации о возвращаемых записях.

Для возврата информации о нескольких заданиях вы можете попробовать запросить следующие системные таблицы, которые содержат различные биты информации о задании

  • msdb.dbo.SysJobs
  • msdb.dbo.SysJobSteps
  • msdb.dbo.SysJobSchedules
  • msdb.dbo.SysJobServers
  • msdb.dbo.SysJobHistory

Их имена не требуют пояснений (кроме SysJobServers, которые содержат информацию о том, когда задание выполнялось в последний раз и о результате).

Опять же, информацию о полях можно найти на MSDN. Например, проверьте страницу для SysJobs

27 голосов
/ 26 октября 2008

Это то, что я использую для получения запущенных заданий (главным образом, чтобы я мог убить те, которые, вероятно, зависли):

SELECT
    job.Name, job.job_ID
    ,job.Originating_Server
    ,activity.run_requested_Date
    ,datediff(minute, activity.run_requested_Date, getdate()) AS Elapsed
FROM
    msdb.dbo.sysjobs_view job 
        INNER JOIN msdb.dbo.sysjobactivity activity
        ON (job.job_id = activity.job_id)
WHERE
    run_Requested_date is not null 
    AND stop_execution_date is null
    AND job.name like 'Your Job Prefix%'

Как сказал Тим, документация MSDN / BOL достаточно хороша для содержимого таблиц sysjobsX. Просто помните, что это таблицы в MSDB.

10 голосов
/ 03 апреля 2012
-- Microsoft SQL Server 2008 Standard Edition:
IF EXISTS(SELECT 1 
          FROM msdb.dbo.sysjobs J 
          JOIN msdb.dbo.sysjobactivity A 
              ON A.job_id=J.job_id 
          WHERE J.name=N'Your Job Name' 
          AND A.run_requested_date IS NOT NULL 
          AND A.stop_execution_date IS NULL
         )
    PRINT 'The job is running!'
ELSE
    PRINT 'The job is not running.'
3 голосов
/ 11 ноября 2011

мы можем запросить msdb разными способами, чтобы получить подробности.

немногие из них

select job.Name, job.job_ID, job.Originating_Server,activity.run_requested_Date,
datediff(minute, activity.run_requested_Date, getdate()) as Elapsed 
from msdb.dbo.sysjobs_view job 
inner join msdb.dbo.sysjobactivity activity on (job.job_id = activity.job_id) 
where run_Requested_date is not null 
and stop_execution_date is null 
and job.name like 'Your Job Prefix%'
2 голосов
/ 29 июня 2017

Это старый вопрос, но у меня просто была похожая ситуация, когда мне нужно было проверить состояние заданий на SQL Server. Многие люди упоминали таблицу sysjobactivity и указывали на документацию MSDN, которая великолепна. Однако я также хотел бы выделить Монитор активности заданий , который отображает состояние всех заданий, определенных на вашем сервере.

2 голосов
/ 14 октября 2008

Вы не указали, как бы вы хотели видеть эти детали.

Для первого взгляда я бы предложил проверить Server Management Studio .

Задания и текущие статусы можно увидеть в части агента SQL Server в разделе «Задания». Если вы выбираете задание, на странице свойств отображается ссылка на историю заданий, где вы можете увидеть время начала и окончания, если есть какие-либо ошибки, какой шаг вызвал ошибку и т. Д.

Вы можете указать оповещения и уведомления для отправки вам по электронной почте или на странице, когда работа успешно завершена или не удалась.

Есть Монитор Деятельности Работы, но фактически я никогда не использовал его. Вы можете попробовать.

Если вы хотите проверить это с помощью T-SQL, то я не знаю, как вы можете это сделать.

1 голос
/ 18 апреля 2017

Показывает состояние / время последнего запуска или, если выполняется, показывает текущее время выполнения, номер шага / информацию и SPID (если с ним связан SPID). Он также показывает, включен / отключен и пользователь задания, где он преобразует в формат NT SID для неразрешенных учетных записей пользователей.

CREATE TABLE #list_running_SQL_jobs
(
    job_id UNIQUEIDENTIFIER NOT NULL
  , last_run_date INT NOT NULL
  , last_run_time INT NOT NULL
  , next_run_date INT NOT NULL
  , next_run_time INT NOT NULL
  , next_run_schedule_id INT NOT NULL
  , requested_to_run INT NOT NULL
  , request_source INT NOT NULL
  , request_source_id sysname NULL
  , running INT NOT NULL
  , current_step INT NOT NULL
  , current_retry_attempt INT NOT NULL
  , job_state INT NOT NULL
);

DECLARE @sqluser NVARCHAR(128)
      , @is_sysadmin INT;

SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0);

DECLARE read_sysjobs_for_running CURSOR FOR
    SELECT DISTINCT SUSER_SNAME(owner_sid)FROM msdb.dbo.sysjobs;
OPEN read_sysjobs_for_running;
FETCH NEXT FROM read_sysjobs_for_running
INTO @sqluser;

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO #list_running_SQL_jobs
    EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @sqluser;
    FETCH NEXT FROM read_sysjobs_for_running
    INTO @sqluser;
END;

CLOSE read_sysjobs_for_running;
DEALLOCATE read_sysjobs_for_running;

SELECT j.name
     , 'Enbld' = CASE j.enabled
                     WHEN 0
                         THEN 'no'
                     ELSE 'YES'
                 END
     , '#Min' = DATEDIFF(MINUTE, a.start_execution_date, ISNULL(a.stop_execution_date, GETDATE()))
     , 'Status' = CASE
                      WHEN a.start_execution_date IS NOT NULL
                          AND a.stop_execution_date IS NULL
                          THEN 'Executing'
                      WHEN h.run_status = 0
                          THEN 'FAILED'
                      WHEN h.run_status = 2
                          THEN 'Retry'
                      WHEN h.run_status = 3
                          THEN 'Canceled'
                      WHEN h.run_status = 4
                          THEN 'InProg'
                      WHEN h.run_status = 1
                          THEN 'Success'
                      ELSE 'Idle'
                  END
     , r.current_step
     , spid = p.session_id
     , owner = ISNULL(SUSER_SNAME(j.owner_sid), 'S-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1))) - CONVERT(BIGINT, 256) * CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256)) + '-' + CONVERT(NVARCHAR(12), UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 4), 1)) / 256 + CONVERT(BIGINT, NULLIF(UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256, 0)) - CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256)) + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 5), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 6), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 6), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 7), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 8), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 8), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 9), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 10), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 10), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 11), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 12), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 12), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 13), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 14), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 14), -1)) * 0), '')) --SHOW as NT SID when unresolved
     , a.start_execution_date
     , a.stop_execution_date
     , t.subsystem
     , t.step_name
FROM msdb.dbo.sysjobs j
    LEFT OUTER JOIN (SELECT DISTINCT * FROM #list_running_SQL_jobs) r
        ON j.job_id = r.job_id
    LEFT OUTER JOIN msdb.dbo.sysjobactivity a
        ON j.job_id = a.job_id
            AND a.start_execution_date IS NOT NULL
            --AND a.stop_execution_date IS NULL
            AND NOT EXISTS
            (
                SELECT *
                FROM msdb.dbo.sysjobactivity at
                WHERE at.job_id = a.job_id
                    AND at.start_execution_date > a.start_execution_date
            )
    LEFT OUTER JOIN sys.dm_exec_sessions p
        ON p.program_name LIKE 'SQLAgent%0x%'
            AND j.job_id = SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 7, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 5, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 3, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 1, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 11, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 9, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 15, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 13, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 17, 4) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 21, 12)
    LEFT OUTER JOIN msdb.dbo.sysjobhistory h
        ON j.job_id = h.job_id
            AND h.instance_id = a.job_history_id
    LEFT OUTER JOIN msdb.dbo.sysjobsteps t
        ON t.job_id = j.job_id
            AND t.step_id = r.current_step
ORDER BY 1;

DROP TABLE #list_running_SQL_jobs;
1 голос
/ 17 июня 2015

Задачи выше работают, но я видел много записей в msdb.dbo.sysjobactivity , где run_Requested_date не является нулевым и stop_execution_date имеет значение null ---- и работа в данный момент не выполняется.

Я бы порекомендовал запустить следующий скрипт, чтобы очистить все фиктивные записи (убедитесь, что в данный момент не выполняются никакие задания).

SQL2008:

    delete activity
    from msdb.dbo.sysjobs_view job  
    inner join msdb.dbo.sysjobactivity activity on job.job_id = activity.job_id 
    where  
        activity.run_Requested_date is not null  
    and activity.stop_execution_date is null  
0 голосов
/ 04 апреля 2017
SELECT sj.name
  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 = '<your Job Name>'
   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 ) )
print 'running'
...