【问题标题】:How can I set specific step in a job restart if take more than 7 minutes running? SSMS如果运行时间超过 7 分钟,如何设置作业重新启动的特定步骤? SSMS
【发布时间】:2018-02-20 14:39:47
【问题描述】:

我已经在 SSMS 中设置了一个作业,其中包含基于 SSIS 包 (ETL) 的 3 个步骤,但每隔一段时间,第二个步骤花费的时间都比预期的要长。

我正在尝试在第二步中实现这一目标:

但每一次,我都会得到:

【问题讨论】:

  • 我不是专家,但工作可以开始其他工作吗?如果是这样,他们可以异步执行吗?
  • 问题不清楚你想要达到的目标,请添加sn-p of jobs和你想要达到的目标
  • 好吧,我只是贴一些图片让你理解。
  • 是SSIS包中的三个步骤吗?或者它是三个工作步骤,每个步骤都执行不同的 SSIS 包?问题有点混乱
  • 只有 3 个 ssis 步骤的 1 个作业。

标签: sql-server ssis ssms


【解决方案1】:
  • 任何时候只能有一个 SQL 代理作业实例处于活动状态。

  • sp_start_job 将是一个异步调用 - 触发后忘记

  • sp_stop_job 将终止现有代理作业

  • 代理作业信息存储在 msdb.dbo.sysjobs 中,当前运行的任务在 msdb.dbo.sysjobactivity 中

把所有这些放在一起,你会想要

  1. 创建一个名为 JobKiller 的新 SQL 代理作业
  2. 修改现有作业以在 SSIS 包开始之前立即启动 JobKiller(因此您想要在 7 分钟后终止的第 2 步实际上是第 3 步,我们应该相应地计划)

JobKiller 定义如下

-- Wait for 7 minutes
WAITFOR DELAY '00:07:00';

-- Is our job still running 
-- verify that last completed step was JobKiller (2)
IF EXISTS
(
SELECT
    *
FROM
    msdb.dbo.sysjobs AS S
    INNER JOIN
        msdb.dbo.sysjobactivity AS S2
        ON S2.job_id = S.job_id
WHERE
    S.name = 'LongRunningJob'
    AND S2.last_executed_step_id = 2
    AND DATEDIFF(MINUTE, S2.start_execution_date, CURRENT_TIMESTAMP) > 7
)
BEGIN
    EXECUTE msdb.dbo.sp_stop_job
        @job_name = 'LongRunningJob';
END

类似于 ElementZero 的方法,但没有 tempdb 对象。

【讨论】:

  • 如何修改现有作业以从作业杀手开始,因为没有可以调用作业的步骤...
  • 当您说要添加定义时,它必须是正确的 T-sql 脚本?
  • 正确,添加一个TSQL类型的新步骤开始另一个工作
【解决方案2】:

如果我这样做,我可能会开始另一项检查锁定或表条目或其他内容的工作。这可能看起来有点 hacky,但它应该可以工作......

作业 1(名为“ETL”)

第 2 步(名为“启动监视器”) - 这是一个新步骤

-- Since we'll use this for locking, make sure only one exists
if OBJECT_ID('tempdb..SSISPackageRunnerLock') is not null then 
   drop table SSISPackageRunnerLock

-- Create a global temp table that will exist till this step is done
CREATE TABLE tempdb..SSISPackageRunnerLock(id int)

-- Start our monitor job
sp_start_job @job_name = 'ETL Monitor'

步骤 3 - 这是您现有的步骤(当前为“步骤 2”的步骤)

启动 SSIS 包步骤

第 4 步 -- 这是一个新的步骤

if OBJECT_ID('tempdb..SSISPackageRunnerLock') is not null then 
       drop table tempdb..SSISPackageRunnerLock

作业 2(名为“ETL 监视器”)

第 1 步

WAITFOR DELAY '00:07:00' - Wait for seven minutes

/***
Does the table that we made in step 2 of the other job still exist?  
If so the step must be still running
***/
if OBJECT_ID('tempdb..SSISPackageRunnerLock') is not null  
BEGIN
   -- Kill the other job
   sp_stop_job @job_name = 'ETL'

   WAITFOR DELAY '00:01:00' -- wait a minute for it to stop

   -- Start it back up on that step to "restart" it
   sp_start_job @job_name = 'ETL', @step_name = 'Start Monitor'
END

我应该注意,如果它从未在七分钟内完成,这基本上会创建作业 1 的第 2 步的无限循环。您可能想在 sp_start_job 之后添加发送电子邮件或其他内容,这样您就知道必须使用监控作业(如果不断使用它,您会收到无穷无尽的电子邮件)。

【讨论】:

  • 我应该基于 T-sql 脚本再创建 2 个作业,还是如何使用我当前的作业来完成?
  • 有点,但假设我当前的工作名为 ETL,有问题的步骤名为“step2”我如何用你的代码实现它?,因为我可以看到我必须再创造 2 个工作岗位?还是使用该代码再创建 2 个步骤??
  • 好的,再次编辑(实际上只是名称更改)。您不必再创建两个作业,只需在现有作业中再添加两个步骤,然后创建另一个作业来监控第一个作业步骤。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
相关资源
最近更新 更多