我有许多 SQLServer 代理计划作业,其中一个执行完整的数据库备份。我想在备份开始时禁用其他一些作业,并在备份完成后重新启用它们。这样做的正确方法是什么?我正在考虑将以下 tsql 命令之一添加到备份任务的第一步(以及相应的启用命令到最后一步),但我找不到哪个更好(或者可能有另一种方法)。
UPDATE MSDB.dbo.sysjobs
SET Enabled = 0
WHERE [Name] IN (....)
还是数EXEC dbo.sp_update_job?
谢谢。
我有许多 SQLServer 代理计划作业,其中一个执行完整的数据库备份。我想在备份开始时禁用其他一些作业,并在备份完成后重新启用它们。这样做的正确方法是什么?我正在考虑将以下 tsql 命令之一添加到备份任务的第一步(以及相应的启用命令到最后一步),但我找不到哪个更好(或者可能有另一种方法)。
UPDATE MSDB.dbo.sysjobs
SET Enabled = 0
WHERE [Name] IN (....)
还是数EXEC dbo.sp_update_job?
谢谢。
绝对使用 sp_update_job。如果作业已安排,那么直接操作 sysjobs 表不一定会导致重新计算缓存的调度。
它可能适用于 ENABLED 标志(尚未尝试过),但我知道它不适用于 start_step_id 之类的列。
你必须运行EXEC dbo.sp_update_job,因为你不能直接更新系统表(虽然我不确定 sysjobs 是否仍然算作系统表Mitch 说它可以更新)
我会考虑使用sp_getapplock 和 sp_releaseapplock来“锁定”其他作业而不实际更新作业。
我会使用 sp_update_job 因为它封装了支持的可重用逻辑。为什么要重新发明轮子。
我认为您建议的方法没有任何问题。您还可以通过工作类别进行操作:
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
将生成相同的代码,但内置的过程通常是要走的路。
SQL 代理缓存作业的启用状态。因此,如果您只是更新 sysjobs 表,它实际上不会阻止计划触发作业。存储过程确实会触发缓存更新,因此sp_update_job我建议您使用它。
如果您仍想手动设置 sysjobs 中的值,则必须运行sp_sqlagent_notify才能真正获取启用状态的 sql agent refresh is cache。只需查看sp_update_job您需要的确切参数的代码。
另一种方法是在其他作业的开头添加一个步骤,该步骤检查备份作业的状态,然后在备份正在运行时中止或休眠当前作业。
我们有时会以两种方式做到这一点,这取决于不同工作的可靠性/关键程度,哪个工作效果更好。