Подтвердить что ты не робот

Как узнать статус текущих рабочих мест

Мне нужно знать, выполняется ли данное задание на сервере Ms SQL 2008. Чтобы не повторять эту же работу снова, что может привести к проблемам concurrency.

4b9b3361

Ответ 1

Похоже, вы можете использовать msdb.dbo.sysjobactivity, проверяя запись с ненулевым start_execution_date и null stop_execution_date, что означает, что задание было запущено, но еще не завершено.

Это даст вам текущие рабочие задания:

SELECT sj.name
   , sja.*
FROM msdb.dbo.sysjobactivity AS sja
INNER JOIN msdb.dbo.sysjobs AS sj ON sja.job_id = sj.job_id
WHERE sja.start_execution_date IS NOT NULL
   AND sja.stop_execution_date IS NULL

Ответ 2

Учитывая задание (я полагаю, вы знаете его имя), вы можете использовать:

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

как предложено в Процедуре справки о работе MSDN. Он возвращает много информации о задании (владелец, сервер, статус и т.д.).

Ответ 3

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

проверить поле execute_status

0 - возвращает только те задания, которые не простаивают или приостановлены.
1 - Выполнение.
2 - Ожидание потока.
3 - Между попытками.
4 - Idle.
5 - Подвесной.
7 - Выполнение действий завершения.

Если вам нужен результат выполнения, проверьте поле last_run_outcome

0 = Ошибка 1 = Преемник
3 = Отменено
5 = Неизвестно

https://msdn.microsoft.com/en-us/library/ms186722.aspx

Ответ 4

Я получил лучший ответ здесь Kenneth Fisher https://dba.stackexchange.com/questions/58859/script-to-see-running-jobs-in-sql-server-with-job-start-time, после запроса возвращается только текущие рабочие задания.

SELECT
ja.job_id,
j.name AS job_name,
ja.start_execution_date,      
ISNULL(last_executed_step_id,0)+1 AS current_executed_step_id,
Js.step_name
FROM msdb.dbo.sysjobactivity ja 
LEFT JOIN msdb.dbo.sysjobhistory jh 
ON ja.job_history_id = jh.instance_id
JOIN msdb.dbo.sysjobs j 
ON ja.job_id = j.job_id
JOIN msdb.dbo.sysjobsteps js
ON ja.job_id = js.job_id
AND ISNULL(ja.last_executed_step_id,0)+1 = js.step_id
WHERE ja.session_id = (SELECT TOP 1 session_id FROM msdb.dbo.syssessions   ORDER BY agent_start_date DESC)
AND start_execution_date is not null
AND stop_execution_date is null

Вы можете получить дополнительную информацию о задании, добавив больше столбцов из таблицы msdb.dbo.sysjobactivity в предложении select.

Ответ 5

EXECUTE master.dbo.xp_sqlagent_enum_jobs 1,''

Обратите внимание на столбец Running, очевидно, 1 означает, что он в данный момент запущен, и [Текущий шаг]. Это возвращает job_id для вас, поэтому вам нужно будет просмотреть их, например:

SELECT top 100 *
 FROM   msdb..sysjobs
 WHERE  job_id IN (0x9DAD1B38EB345D449EAFA5C5BFDC0E45, 0xC00A0A67D109B14897DD3DFD25A50B80, 0xC92C66C66E391345AE7E731BFA68C668)

Ответ 6

DECLARE @StepCount INT
SELECT @StepCount = COUNT(1)
FROM msdb.dbo.sysjobsteps
WHERE job_id = '0523333-5C24-1526-8391-AA84749345666' --JobID


SELECT
         [JobName]
        ,[JobStepID]
        ,[JobStepName]
        ,[JobStepStatus]
        ,[RunDateTime]
        ,[RunDuration]
    FROM
    (
        SELECT 
                j.[name] AS [JobName]
            ,Jh.[step_id] AS [JobStepID]
            ,jh.[step_name] AS [JobStepName]
            ,CASE 
                WHEN jh.[run_status] = 0 THEN 'Failed'
                WHEN jh.[run_status] = 1 THEN 'Succeeded'
                WHEN jh.[run_status] = 2 THEN 'Retry (step only)'
                WHEN jh.[run_status] = 3 THEN 'Canceled'
                WHEN jh.[run_status] = 4 THEN 'In-progress message'
                WHEN jh.[run_status] = 5 THEN 'Unknown'
                ELSE 'N/A'
                END AS [JobStepStatus]
            ,msdb.dbo.agent_datetime(run_date, run_time) AS [RunDateTime]
            ,CAST(jh.[run_duration]/10000 AS VARCHAR)  + ':' + CAST(jh.[run_duration]/100%100 AS VARCHAR) + ':' + CAST(jh.[run_duration]%100 AS VARCHAR) AS [RunDuration]
            ,ROW_NUMBER() OVER 
            (
                PARTITION BY jh.[run_date]
                ORDER BY jh.[run_date] DESC, jh.[run_time] DESC
            ) AS [RowNumber]
        FROM 
            msdb.[dbo].[sysjobhistory] jh
            INNER JOIN msdb.[dbo].[sysjobs] j
                ON jh.[job_id] = j.[job_id]
        WHERE 
            j.[name] = 'ProcessCubes' --Job Name
            AND jh.[step_id] > 0
            AND CAST(RTRIM(run_date) AS DATE) = CAST(GETDATE() AS DATE) --Current Date
    ) A
    WHERE 
        [RowNumber] <= @StepCount
        AND [JobStepStatus] = 'Failed'

Ответ 7

Мы нашли и использовали этот код для хорошего решения. Этот код запускает задание и контролирует его, автоматически убивая задание, если оно превышает ограничение по времени.

/****************************************************************
--This SQL will take a list of SQL Agent jobs (names must match),
--start them so they're all running together, and then
--monitor them, not quitting until all jobs have completed.
--
--In essence, it an SQL "watchdog" loop to start and monitor SQL Agent Jobs
--
--Code from http://cc.davelozinski.com/code/sql-watchdog-loop-start-monitor-sql-agent-jobs
--
****************************************************************/
SET NOCOUNT ON 

-------- BEGIN ITEMS THAT NEED TO BE CONFIGURED --------

--The amount of time to wait before checking again 
--to see if the jobs are still running.
--Should be in hh:mm:ss format. 
DECLARE @WaitDelay VARCHAR(8) = '00:00:20'

--Job timeout. Eg, if the jobs are running longer than this, kill them.
DECLARE @TimeoutMinutes INT = 240

DECLARE @JobsToRunTable TABLE
(
    JobName NVARCHAR(128) NOT NULL,
    JobID UNIQUEIDENTIFIER NULL,
    Running INT NULL
)

--Insert the names of the SQL jobs here. Last two values should always be NULL at this point.
--Names need to match exactly, so best to copy/paste from the SQL Server Agent job name.
INSERT INTO @JobsToRunTable (JobName, JobID, Running) VALUES ('NameOfFirstSQLAgentJobToRun',NULL,NULL)
INSERT INTO @JobsToRunTable (JobName, JobID, Running) VALUES ('NameOfSecondSQLAgentJobToRun',NULL,NULL)
INSERT INTO @JobsToRunTable (JobName, JobID, Running) VALUES ('NameOfXSQLAgentJobToRun',NULL,NULL)

-------- NOTHING FROM HERE DOWN SHOULD NEED TO BE CONFIGURED --------

DECLARE @ExecutionStatusTable TABLE
(
    JobID UNIQUEIDENTIFIER PRIMARY KEY, -- Job ID which will be a guid
    LastRunDate INT, LastRunTime INT, -- Last run date and time
    NextRunDate INT, NextRunTime INT, -- Next run date and time
    NextRunScheduleID INT, -- an internal schedule id
    RequestedToRun INT, RequestSource INT, RequestSourceID VARCHAR(128),
    Running INT,    -- 0 or 1, 1 means the job is executing
    CurrentStep INT, -- which step is running
    CurrentRetryAttempt INT, -- retry attempt
    JobState INT -- 0 = Not idle or suspended, 1 = Executing, 2 = Waiting For Thread,
                     -- 3 = Between Retries, 4 = Idle, 5 = Suspended, 
                     -- 6 = WaitingForStepToFinish, 7 = PerformingCompletionActions
)

DECLARE @JobNameToRun NVARCHAR(128) = NULL
DECLARE @IsJobRunning BIT = 1
DECLARE @AreJobsRunning BIT = 1
DECLARE @job_owner sysname = SUSER_SNAME()
DECLARE @JobID UNIQUEIDENTIFIER = null
DECLARE @StartDateTime DATETIME = GETDATE()
DECLARE @CurrentDateTime DATETIME = null
DECLARE @ExecutionStatus INT = 0
DECLARE @MaxTimeExceeded BIT = 0

--Loop through and start every job
DECLARE dbCursor CURSOR FOR SELECT JobName FROM @JobsToRunTable
OPEN dbCursor FETCH NEXT FROM dbCursor INTO @JobNameToRun
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC [msdb].[dbo].sp_start_job @JobNameToRun
    FETCH NEXT FROM dbCursor INTO @JobNameToRun
END
CLOSE dbCursor
DEALLOCATE dbCursor

print '*****************************************************************'
print 'Jobs started. ' + CAST(@StartDateTime as varchar)
print '*****************************************************************'

--Debug (if needed)
--SELECT * FROM @JobsToRunTable

WHILE 1=1 AND @AreJobsRunning = 1
BEGIN

    --This has to be first with the delay to make sure the jobs
    --have time to actually start up and are recognized as 'running'
    WAITFOR DELAY @WaitDelay 

    --Reset for each loop iteration
    SET @AreJobsRunning = 0

    --Get the currently executing jobs by our user name
    INSERT INTO @ExecutionStatusTable
    EXECUTE [master].[dbo].xp_sqlagent_enum_jobs 1, @job_owner

    --Debug (if needed)
    --SELECT 'ExecutionStatusTable', * FROM @ExecutionStatusTable

    --select every job to see if it running
    DECLARE dbCursor CURSOR FOR 
        SELECT x.[Running], x.[JobID], sj.name 
        FROM @ExecutionStatusTable x 
        INNER JOIN [msdb].[dbo].sysjobs sj ON sj.job_id = x.JobID
        INNER JOIN @JobsToRunTable jtr on sj.name = jtr.JobName
    OPEN dbCursor FETCH NEXT FROM dbCursor INTO @IsJobRunning, @JobID, @JobNameToRun

    --Debug (if needed)
    --SELECT x.[Running], x.[JobID], sj.name 
    --  FROM @ExecutionStatusTable x 
    --  INNER JOIN msdb.dbo.sysjobs sj ON sj.job_id = x.JobID
    --  INNER JOIN @JobsToRunTable jtr on sj.name = jtr.JobName

    WHILE @@FETCH_STATUS = 0
    BEGIN
        --bitwise operation to see if the loop should continue
        SET @AreJobsRunning = @AreJobsRunning | @IsJobRunning

        UPDATE @JobsToRunTable
        SET Running = @IsJobRunning, JobID = @JobID
        WHERE JobName = @JobNameToRun

        --Debug (if needed)
        --SELECT 'JobsToRun', * FROM @JobsToRunTable

        SET @CurrentDateTime=GETDATE()

        IF @IsJobRunning = 1
        BEGIN -- Job is running or finishing (not idle)

            IF DATEDIFF(mi, @StartDateTime, @CurrentDateTime) > @TimeoutMinutes
            BEGIN     
                print '*****************************************************************'
                print @JobNameToRun + ' exceeded timeout limit of ' + @TimeoutMinutes + ' minutes. Stopping.'
                --Stop the job
                EXEC [msdb].[dbo].sp_stop_job @job_name = @JobNameToRun
            END
            ELSE
            BEGIN
                print @JobNameToRun + ' running for ' + CONVERT(VARCHAR(25),DATEDIFF(mi, @StartDateTime, @CurrentDateTime)) + ' minute(s).'
            END
        END

        IF @IsJobRunning = 0 
        BEGIN
            --Job isn't running
            print '*****************************************************************'
            print @JobNameToRun + ' completed or did not run. ' + CAST(@CurrentDateTime as VARCHAR)
        END

        FETCH NEXT FROM dbCursor INTO @IsJobRunning, @JobID, @JobNameToRun

    END -- WHILE @@FETCH_STATUS = 0
    CLOSE dbCursor
    DEALLOCATE dbCursor

    --Clear out the table for the next loop iteration
    DELETE FROM @ExecutionStatusTable

    print '*****************************************************************'

END -- WHILE 1=1 AND @AreJobsRunning = 1

SET @CurrentDateTime = GETDATE()
print 'Finished at ' + CAST(@CurrentDateTime as varchar)
print CONVERT(VARCHAR(25),DATEDIFF(mi, @StartDateTime, @CurrentDateTime)) + ' minutes total run time.'

Ответ 8

Вы можете запросить таблицу msdb.dbo.sysjobactivity, чтобы определить, выполняется ли задание в настоящий момент.

Ответ 9

проверить этот запрос

select so.name,so.description,so.enabled,CASE 
            WHEN sh.[run_status] = 0 THEN 'Failed'
            WHEN sh.[run_status] = 1 THEN 'Succeeded'
            WHEN sh.[run_status] = 2 THEN 'Retry (step only)'
            WHEN sh.[run_status] = 3 THEN 'Canceled'
            WHEN sh.[run_status] = 4 THEN 'In-progress message'
            WHEN sh.[run_status] = 5 THEN 'Unknown'
            ELSE 'N/A' END as Run_Status,sh.* from msdb.dbo.sysjobhistory sh
 LEFT JOIN msdb.dbo.sysjobs so on sh.job_id = so.job_id
 where sh.run_status = 0
 and sh.run_date = CONVERT(VARCHAR(10), GETDATE(), 112)
 order by sh.instance_id desc