【问题标题】:The proper way to disable/enable SQLServer Agent Jobs禁用/启用 SQL Server 代理作业的正确方法
【发布时间】:2011-03-23 15:41:58
【问题描述】:

我有许多 SQLServer 代理计划作业,其中一个执行完整的数据库备份。我想在备份开始时禁用其他一些作业,并在备份完成后重新启用它们。这样做的正确方法是什么?我正在考虑将以下 tsql 命令之一添加到备份任务的第一步(以及相应的启用命令到最后一步),但我找不到哪个更好(或者可能有另一种方法)。

UPDATE MSDB.dbo.sysjobs
SET Enabled = 0
WHERE [Name] IN (....)

或多个EXEC dbo.sp_update_job?
谢谢。

【问题讨论】:

  • 我认为您建议的方法没有任何问题。
  • 那么你觉得哪一个更好呢?直接UPDATE sysojobs 或使用sp_update_job ?
  • 如果/当备份失败时,您将如何处理已禁用的作业?
  • @DForck42:我倾向于 gbn 的 applocks 解决方案,但有一些陷阱 - 在第 1 步获得的锁似乎在第 2 步没有持有。

标签: sql-server sql-server-agent


【解决方案1】:

一定要使用 sp_update_job。如果作业已经调度,那么直接操作 sysjobs 表不一定会导致重新计算缓存的调度。

它可能适用于 ENABLED 标志(尚未尝试过),但我知道它不适用于 start_step_id 之类的列。

【讨论】:

  • 正确 - 直接更新 sysjobs 表会破坏现有计划
【解决方案2】:

你必须运行EXEC dbo.sp_update_job,因为你不能直接更新系统表(虽然我不确定 sysjobs 是否仍然算作系统表 Mitch 说它可以更新)

我会考虑使用sp_getapplock and sp_releaseapplock 来“锁定”其他工作,但实际上不更新工作。

【讨论】:

  • @Mitch Wheat:好几年没试过了,在我目前的环境下也做不到
  • 感谢锁提示。 sysjobs 似乎是可更新的,我刚刚尝试将 tsql 脚本添加到作业步骤中并且它起作用了。
  • 我尝试使用锁,但我遇到了以下问题:代理作业第一步获得的锁似乎在第一步完成后被释放(我做了EXEC @result = sp_getapplock @Resource = 'TestLock', @LockOwner='Session',@LockTimeout =5000, @LockMode = 'Exclusive';)。有解决办法吗?
  • @a1ex07:我会把它放到主要工作步骤中,或者将主要调用包装在存储过程中。每个步骤将在单独的连接上单独执行,因此会话锁定超出范围。
  • @gbn:谢谢,我想也许我错过了什么。
【解决方案3】:

我会使用 sp_update_job,因为它封装了支持的可重用逻辑。为什么要重新发明轮子。

http://msdn.microsoft.com/en-us/library/ms188745.aspx

【讨论】:

    【解决方案4】:

    我认为您建议的方法没有任何问题。您还可以通过作业类别进行操作:

    UPDATE j
    SET j.Enabled = 0
    FROM MSDB.dbo.sysjobs j
    INNER JOIN MSDB.dbo.syscategories c ON j.category_id = c.category_id
    WHERE c.[Name] = 'Database Maintenance';
    

    我没有对其进行分析,但我怀疑

    USE msdb ;
    GO
    
    EXEC dbo.sp_update_job
        @job_name = N'SomeJob',
        @enabled = 0;
    GO
    

    将生成相同的代码,但内置 procs 通常是要走的路。

    【讨论】:

    • 不建议直接更新 sysjobs 表,因为缓存的计划不会正确更新。看我的回答。
    【解决方案5】:

    SQL 代理缓存作业的启用状态。因此,如果您只是更新 sysjobs 表,它实际上不会阻止计划触发作业。 sp_update_job 存储过程确实会触发缓存更新,所以我建议你使用它。

    如果您仍想手动设置 sysjobs 中的值,则必须运行 sp_sqlagent_notify 才能真正获取启用状态的 sql agent refresh is cache。只需查看sp_update_job 的代码即可了解您需要的确切参数。

    【讨论】:

      【解决方案6】:

      另一种方法是在其他作业的开头添加一个步骤,检查备份作业的状态,然后在备份运行时中止或休眠当前作业。

      我们有时会采用两种方式,这取决于不同工作的可靠性/关键程度,哪个工作效果更好。

      【讨论】:

        猜你喜欢
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-07
        • 2017-11-11
        相关资源
        最近更新 更多