【问题标题】:How to automatically STOP SQL Server Agent when no jobs are running?没有作业运行时如何自动停止 SQL Server 代理?
【发布时间】:2016-12-05 17:53:14
【问题描述】:

我在一个实例中有大约 40 个不同的 sql server 作业。他们都有不同的时间表。有的每天跑一次,有的每两分钟跑一次,有的每五分钟跑一次。如果我需要停止 sql server 代理,我怎样才能找到没有作业运行的最佳时间,这样我就不会中断我的任何作业?

【问题讨论】:

    标签: sql-server jobs agent


    【解决方案1】:

    我怎样才能找到没有作业运行的最佳时间,这样我就不会打断我的任何作业?

    您基本上是想找到一个好的窗口来执行一些维护。 @MaxVernon 已经在博客上写了 here 并附有一个方便的脚本

    /*
          Shows gaps between agent jobs
    -- http://www.sqlserver.science/tools/gaps-between-sql-server-agent-jobs/
    -- requires SQL Server 2012+ since it uses the LAG aggregate.
     Note: On SQL Server 2005, SQL Server 2008, and SQL Server 2008 R2, you could replace the LastEndDateTime column definition with:
    
           LastEndDateTime = (SELECT TOP(1) s1a.EndDateTime FROM s1 s1a WHERE s1a.rn = s1.rn - 1)
    */
    DECLARE @EarliestStartDate DATETIME;
    DECLARE @LatestStopDate DATETIME;
    SET @EarliestStartDate = DATEADD(DAY, -1, GETDATE());
    SET @LatestStopDate = GETDATE();
    ;WITH s AS 
    (
        SELECT StartDateTime = msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time)
              , MaxDuration = MAX(sjh.run_duration)
        FROM msdb.dbo.sysjobs sj 
              INNER JOIN msdb.dbo.sysjobhistory sjh ON sj.job_id = sjh.job_id
        WHERE sjh.step_id = 0
            AND msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) >= @EarliestStartDate
            AND msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) < = @LatestStopDate
        GROUP BY msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time)
        UNION ALL
        SELECT StartDate = DATEADD(SECOND, -1, @EarliestStartDate)
            , MaxDuration = 1
        UNION ALL 
        SELECT StartDate = @LatestStopDate
            , MaxDuration = 1
    )
    , s1 AS 
    (
    SELECT s.StartDateTime
        , EndDateTime = DATEADD(SECOND, s.MaxDuration - ((s.MaxDuration / 100) * 100)
            + (((s.MaxDuration - ((s.MaxDuration / 10000) * 10000)) 
                        - (s.MaxDuration - ((s.MaxDuration / 100) * 100))) / 100) * 60
            + (((s.MaxDuration - ((s.MaxDuration / 1000000) * 1000000)) 
                        - (s.MaxDuration - ((s.MaxDuration / 10000) * 10000))) / 10000) * 3600, s.StartDateTime)
    FROM s
    )
    , s2 AS
    (
        SELECT s1.StartDateTime
            , s1.EndDateTime
            , LastEndDateTime = LAG(s1.EndDateTime) OVER (ORDER BY s1.StartDateTime)
        FROM s1 
    )
    SELECT GapStart = CONVERT(DATETIME2(0), s2.LastEndDateTime)
        , GapEnd = CONVERT(DATETIME2(0), s2.StartDateTime)
        , GapLength = CONVERT(TIME(0), DATEADD(SECOND, DATEDIFF(SECOND, s2.LastEndDateTime, s2.StartDateTime), 0))
    FROM s2 
    WHERE s2.StartDateTime > s2.LastEndDateTime
        ORDER BY s2.StartDateTime;
    

    【讨论】:

      【解决方案2】:

      问题标题让我有点害怕 - 我以为您想在没有作业运行的任何时候以编程方式关闭 SQL Server 代理。我对这个问题的回答是“为什么?”没必要。

      但是,如果您只是希望进行计划的重启或关闭,并且您没有像 Sentry One 的 SQL Sentry 事件管理器这样的第三方工具来进行可视化,我只会让 SQL Server Agent Job History 和作业活动监视器帮助在这里。作业活动监视器可以在状态列中显示当前正在运行的作业。您还可以查看上次执行和下次执行的日期和时间。

      在 SSMS 的对象浏览器中,连接到您的实例,然后展开 SQL Server 代理,然后您将看到 Jobs 并在其下方看到“Job Activity Monitor” - 此视图应显示您需要的内容。

      另外 - 不必担心在作业执行之前关闭。如果你这样做了,你要么让那个作业错过它的时间表,你可以让它在下一次运行时运行(取决于作业和它的目的),或者你可以手动右键单击并执行作业。

      有关作业活动监视器的更多信息,请参阅产品文档中的Monitor Job Activity

      【讨论】:

        【解决方案3】:

        我建议创建一个脚本来禁用您的作业。禁用的作业仍然存在,但不会按其计划自动启动。运行此脚本(基于 msdb 数据库中的过程 sp_update_job)以禁用作业,等待任何当前正在运行的作业完成执行,然后停止 SQL 代理。重新启用已禁用作业的类似脚本会很有用。您可能需要围绕已禁用且应保持禁用的作业进行规划。

        可以完全编写完整的“SQL 代理关闭”过程,但我质疑这样做是否明智。一些研究表明,没有 100% 可靠的方式以编程方式判断给定作业是否正在运行,并且虽然存在未记录(其中“未记录”表示“您真的不应该使用此”)系统使用 SQL Server 本身来停止和启动服务的过程似乎是一个非常糟糕的主意。

        【讨论】:

          【解决方案4】:

          您可以查询 Dattatrey Sindol 在 MSSQLTips.com 文章Querying SQL Server Agent Job Information 中显示的系统表:

          SELECT 
              [sJOB].[job_id] AS [JobID]
              , [sJOB].[name] AS [JobName]
              , [sDBP].[name] AS [JobOwner]
              , [sCAT].[name] AS [JobCategory]
              , [sJOB].[description] AS [JobDescription]
              , CASE [sJOB].[enabled]
                  WHEN 1 THEN 'Yes'
                  WHEN 0 THEN 'No'
                END AS [IsEnabled]
              , [sJOB].[date_created] AS [JobCreatedOn]
              , [sJOB].[date_modified] AS [JobLastModifiedOn]
              , [sSVR].[name] AS [OriginatingServerName]
              , [sJSTP].[step_id] AS [JobStartStepNo]
              , [sJSTP].[step_name] AS [JobStartStepName]
              , CASE
                  WHEN [sSCH].[schedule_uid] IS NULL THEN 'No'
                  ELSE 'Yes'
                END AS [IsScheduled]
              , [sSCH].[schedule_uid] AS [JobScheduleID]
              , [sSCH].[name] AS [JobScheduleName]
              , CASE [sJOB].[delete_level]
                  WHEN 0 THEN 'Never'
                  WHEN 1 THEN 'On Success'
                  WHEN 2 THEN 'On Failure'
                  WHEN 3 THEN 'On Completion'
                END AS [JobDeletionCriterion]
          FROM
              [msdb].[dbo].[sysjobs] AS [sJOB]
              LEFT JOIN [msdb].[sys].[servers] AS [sSVR]
                  ON [sJOB].[originating_server_id] = [sSVR].[server_id]
              LEFT JOIN [msdb].[dbo].[syscategories] AS [sCAT]
                  ON [sJOB].[category_id] = [sCAT].[category_id]
              LEFT JOIN [msdb].[dbo].[sysjobsteps] AS [sJSTP]
                  ON [sJOB].[job_id] = [sJSTP].[job_id]
                  AND [sJOB].[start_step_id] = [sJSTP].[step_id]
              LEFT JOIN [msdb].[sys].[database_principals] AS [sDBP]
                  ON [sJOB].[owner_sid] = [sDBP].[sid]
              LEFT JOIN [msdb].[dbo].[sysjobschedules] AS [sJOBSCH]
                  ON [sJOB].[job_id] = [sJOBSCH].[job_id]
              LEFT JOIN [msdb].[dbo].[sysschedules] AS [sSCH]
                  ON [sJOBSCH].[schedule_id] = [sSCH].[schedule_id]
          ORDER BY [JobName]
          

          【讨论】:

          • 我想查看 SQL Server 中正在运行的作业,如果没有作业运行则停止代理
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-27
          相关资源
          最近更新 更多