Как определить статус задания?
У меня есть хранимая процедура, которая планирует работу. Это задание занимает много времени, чтобы завершить работу (приблизительно 30-40 минут). Мне нужно узнать статус этого задания.
Ниже детали мне помогут
1) Как просмотреть список всех заданий, которые были запланированы на будущее и еще не запущены
2) Как просмотреть список выполняемых заданий и временной интервал с момента запуска
3) Как узнать, успешно ли выполнено задание или остановилось между ними из-за каких-либо ошибок.
Ответы
Ответ 1
Вы можете попробовать использовать системную хранимую процедуру sp_help_job. Это возвращает информацию о задании, его шагах, расписаниях и серверах. Например
EXEC msdb.dbo.sp_help_job @Job_name = 'Your Job Name'
Электронная книга по электронной почте должна содержать много информации о возвращаемых им записях.
Для возврата информации о нескольких заданиях вы можете попробовать выполнить следующие системные таблицы, в которых хранятся различные биты информации о работе
- msdb.dbo.SysJobs
- msdb.dbo.SysJobSteps
- msdb.dbo.SysJobSchedules
- msdb.dbo.SysJobServers
- msdb.dbo.SysJobHistory
Их имена достаточно понятны (кроме SysJobServers, которые содержат информацию о том, когда работа выполняется в последний раз и результат).
Опять же, информацию о полях можно найти в MSDN. Например, просмотрите страницу SysJobs
Ответ 2
Я хотел бы указать, что ни один из 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
Ответ 3
Это то, что я использую, чтобы получить выполняемые задания (в основном, чтобы я мог убить те, которые, вероятно, зависали):
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.
Ответ 4
-- 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.'
Ответ 5
мы можем запросить 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%'
Ответ 6
Вы не указали, как бы вы хотели видеть эти детали.
Для первого взгляда я предлагаю проверить Server Management Studio.
В разделе "Рабочие места" вы можете увидеть задания и текущие статусы в компоненте агента SQL Server. Если вы выбираете задание, на странице "Свойства" отображается ссылка на "История заданий", где вы можете увидеть время начала и окончания, если есть какие-либо ошибки, какой шаг вызвал ошибку и т.д.
Вы можете указать оповещения и уведомления для отправки по электронной почте или на странице, когда задание завершилось успешно или не удалось.
Существует Монитор активности работы, но на самом деле я никогда не использовал его. Вы можете попробовать.
Если вы хотите проверить его с помощью T-SQL, я не знаю, как вы можете это сделать.
Ответ 7
Один из эффективных и правильных способов получить задание "Отчет о выполнении работы" в SSRS для упрощения просмотра и мониторинга заданий, выполняемых на серверах. (прилагается файл .rdl.)
http://www.sqllion.com/2011/11/job-running-status-report-in-ssrs/
Ответ 8
Задачи выше работают, но я видел много записей в msdb.dbo.sysjobactivity
, где run_Requested_date не равно нулю
и stop_execution_date имеет значение null
---- и работа в данный момент не выполняется.
Я бы рекомендовал запустить следующий script, чтобы очистить все фиктивные записи (убедитесь, что в это время не выполняются задания).
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
Ответ 9
Это старый вопрос, но у меня была аналогичная ситуация, когда мне нужно было проверить статус заданий на SQL Server. Многие люди упомянули таблицу sysjobactivity и указали на документацию MSDN, которая великолепна. Тем не менее, я также хотел бы выделить Монитор активности работы, который обеспечивает статус всех заданий, определенных на вашем сервере.
Ответ 10
Самый простой способ, который я нашел, - создать хранимую процедуру. Введите "JobName" и нажмите "go".
/*-----------------------------------------------------------------------------------------------------------
Document Title: usp_getJobStatus
Purpose: Finds a Current Jobs Run Status
Input Example: EXECUTE usp_getJobStatus 'MyJobName'
-------------------------------------------------------------------------------------------------------------*/
IF OBJECT_ID ( 'usp_getJobStatus','P' ) IS NOT NULL
DROP PROCEDURE usp_getJobStatus;
GO
CREATE PROCEDURE usp_getJobStatus
@JobName NVARCHAR (1000)
AS
IF OBJECT_ID('TempDB..#JobResults','U') IS NOT NULL DROP TABLE #JobResults
CREATE TABLE #JobResults ( 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
COLLATE Database_Default NULL,
Running INT NOT NULL,
Current_Step INT NOT NULL,
Current_Retry_Attempt INT NOT NULL,
Job_State INT NOT NULL )
INSERT #JobResults
EXECUTE master.dbo.xp_sqlagent_enum_jobs 1, '';
SELECT job.name AS [Job_Name],
( SELECT MAX(CAST( STUFF(STUFF(CAST(jh.run_date AS VARCHAR),7,0,'-'),5,0,'-') + ' ' +
STUFF(STUFF(REPLACE(STR(jh.run_time,6,0),' ','0'),5,0,':'),3,0,':') AS DATETIME))
FROM msdb.dbo.sysjobs AS j
INNER JOIN msdb.dbo.sysjobhistory AS jh
ON jh.job_id = j.job_id AND jh.step_id = 0
WHERE j.[name] LIKE '%' + @JobName + '%'
GROUP BY j.[name] ) AS [Last_Completed_DateTime],
( SELECT TOP 1 start_execution_date
FROM msdb.dbo.sysjobactivity
WHERE job_id = r.job_id
ORDER BY start_execution_date DESC ) AS [Job_Start_DateTime],
CASE
WHEN r.running = 0 THEN
CASE
WHEN jobInfo.lASt_run_outcome = 0 THEN 'Failed'
WHEN jobInfo.lASt_run_outcome = 1 THEN 'Success'
WHEN jobInfo.lASt_run_outcome = 3 THEN 'Canceled'
ELSE 'Unknown'
END
WHEN r.job_state = 0 THEN 'Success'
WHEN r.job_state = 4 THEN 'Success'
WHEN r.job_state = 5 THEN 'Success'
WHEN r.job_state = 1 THEN 'In Progress'
WHEN r.job_state = 2 THEN 'In Progress'
WHEN r.job_state = 3 THEN 'In Progress'
WHEN r.job_state = 7 THEN 'In Progress'
ELSE 'Unknown' END AS [Run_Status_Description]
FROM #JobResults AS r
LEFT OUTER JOIN msdb.dbo.sysjobservers AS jobInfo
ON r.job_id = jobInfo.job_id
INNER JOIN msdb.dbo.sysjobs AS job
ON r.job_id = job.job_id
WHERE job.[enabled] = 1
AND job.name LIKE '%' + @JobName + '%'
Ответ 11
;WITH CTE_JobStatus
AS (
SELECT DISTINCT NAME AS [JobName]
,s.step_id
,s.step_name
,CASE
WHEN [Enabled] = 1
THEN 'Enabled'
ELSE 'Disabled'
END [JobStatus]
,CASE
WHEN SJH.run_status = 0
THEN 'Failed'
WHEN SJH.run_status = 1
THEN 'Succeeded'
WHEN SJH.run_status = 2
THEN 'Retry'
WHEN SJH.run_status = 3
THEN 'Cancelled'
WHEN SJH.run_status = 4
THEN 'In Progress'
ELSE 'Unknown'
END [JobOutcome]
,CONVERT(VARCHAR(8), sjh.run_date) [RunDate]
,CONVERT(VARCHAR(8), STUFF(STUFF(CONVERT(TIMESTAMP, RIGHT('000000' + CONVERT(VARCHAR(6), sjh.run_time), 6)), 3, 0, ':'), 6, 0, ':')) RunTime
,RANK() OVER (
PARTITION BY s.step_name ORDER BY sjh.run_date DESC
,sjh.run_time DESC
) AS rn
,SJH.run_status
FROM msdb..SYSJobs sj
INNER JOIN msdb..SYSJobHistory sjh ON sj.job_id = sjh.job_id
INNER JOIN msdb.dbo.sysjobsteps s ON sjh.job_id = s.job_id
AND sjh.step_id = s.step_id
WHERE (sj.NAME LIKE 'JOB NAME')
AND sjh.run_date = CONVERT(CHAR, getdate(), 112)
)
SELECT *
FROM CTE_JobStatus
WHERE rn = 1
AND run_status NOT IN (1,4)
Ответ 12
Я столкнулся с проблемами на одном из моих серверов, запрашивая таблицы MSDB (так называемый код, приведенный выше), поскольку один из моих заданий будет работать, но это не так. Существует системная хранимая процедура, которая возвращает статус выполнения, но нельзя выполнить инструкцию insert exec без ошибки. Внутри это еще одна системная хранимая процедура, которая может использоваться с инструкцией exec вставки.
INSERT INTO #Job
EXEC master.dbo.xp_sqlagent_enum_jobs 1,dbo
И таблица для загрузки:
CREATE TABLE #Job
(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, -- BOOL
request_source INT NOT NULL,
request_source_id sysname COLLATE database_default NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
Ответ 13
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'
Ответ 14
Это покажет статус/время последнего запуска или, если он запущен, отображает текущее время выполнения, номер шага /info и 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