짧은 답변
20 분마다 (또는 호출되지 않았으며 그 동안 작업이 실행되지 않은 경우 덜 빈번한) msdb.dbo.sysjobschedules
SQL 에이전트의 백그라운드 스레드에 의해 데이터 가 업데이트되는 것처럼 보입니다 .SQLAgent - Schedule Saver
xp_sqlagent_notify
보다 정확한 정보를 봐 위해 next_scheduled_run_date
에서 msdb.dbo.sysjobactivity
. 작업이 변경되거나 작업이 실행될 때마다 실시간으로 업데이트됩니다. 또한 보너스 sysjobactivity
는 데이터를 올바른 방식으로 (날짜 / 시간 열) 저장하므로 어리석은 INT보다 작업하기가 훨씬 쉽습니다.
그것은 짧은 대답입니다.
sysjobschedules 가 진실을 반영 하기까지 최대 20 분이 소요될 수 있습니다 . 그러나 sysjobactivity 는 항상 최신 상태입니다. 이것에 대해 더 많은 세부 사항을 원하거나 내가 어떻게 알아 냈는지 ...
긴 답변
토끼를 따라 가려면을 호출 sp_add_jobschedule
하면이 이벤트 체인이 작동합니다.
msdb.dbo.sp_add_jobschedule == calls ==> msdb.dbo.sp_add_schedule
msdb.dbo.sp_attach_schedule
msdb.dbo.sp_attach_schedule == calls ==> msdb.dbo.sp_sqlagent_notify
msdb.dbo.sp_sqlagent_notify == calls ==> msdb.dbo.xp_sqlagent_notify
이제는 더 이상 토끼를 쫓을 수 없습니다. 왜냐하면 실제로 무엇을 엿볼 수 없기 때문 xp_sqlagent_notify
입니다. 그러나이 확장 프로 시저가 에이전트 서비스와 상호 작용하고이 특정 작업 및 일정이 변경되었다고 가정 할 수 있습니다. 서버 측 추적을 실행하면 SQL 에이전트가 다음 동적 SQL을 즉시 호출 할 수 있습니다.
exec sp_executesql N'DECLARE @nextScheduledRunDate DATETIME
SET @nextScheduledRunDate = msdb.dbo.agent_datetime(@P1, @P2)
UPDATE msdb.dbo.sysjobactivity
SET next_scheduled_run_date = @nextScheduledRunDate
WHERE session_id = @P3 AND job_id = @P4',
N'@P1 int,@P2 int,@P3 int,@P4 uniqueidentifier',
20120819,181600,5,'36924B24-9706-4FD7-8B3A-1F9F0BECB52C'
sysjobactivity
즉시 sysjobschedules
업데이트되고 일정에 따라 업데이트되는 것 같습니다 . 새 일정을 하루에 한 번으로 변경하면
@freq_type=4,
@freq_interval=1,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
sysjobactivity
위와 같이 즉시 업데이트 된 다음 작업이 완료된 후 다른 업데이트가 계속 표시 됩니다. 다양한 업데이트는 SQL 에이전트 내의 백그라운드 및 기타 스레드에서 제공됩니다. 예 :
SQLAgent - Job Manager
SQLAgent - Update job activity
SQLAgent - Job invocation engine
SQLAgent - Schedule Saver
백그라운드 스레드 ( "Schedule Saver"스레드)가 결국 나타나고 업데이트됩니다 sysjobschedules
. 내 초기 조사에서 이것은 20 분마다 나타나고 xp_sqlagent_notify
마지막으로 실행 한 이후 작업 변경으로 인해 호출 된 경우에만 발생합니다 (하나의 작업이 발생한 경우 어떻게되는지 확인하기 위해 추가 테스트를 수행하지 않았습니다) "Schedule Saver"스레드가 둘 다를 업데이트하는 경우 다른 하나가 변경되고 실행 된 것입니다. 꼭 필요한 것으로 생각하지만 독자에게 연습으로 남겨 두십시오.)
20 분주기가 SQL 에이전트가 시작될 때, 자정 또는 컴퓨터 관련 항목에서 오프셋되는지 확실하지 않습니다. 동일한 물리적 서버에있는 두 개의 서로 다른 인스턴스에서 "Schedule Saver"스레드 sysjobschedules
가 두 인스턴스에서 거의 동시에 정확히 하나의 시간에 18:31:37 및 18:51:37, 18:31:39 및 다른쪽에 18시 51 분 39 초. 이 서버에서 SQL Server 에이전트를 동시에 시작하지 않았지만 시작 시간이 20 분 오프셋 될 수있는 원격 가능성이 있습니다. 의심 스럽지만 지금은 에이전트 중 하나에서 에이전트를 다시 시작하고 더 많은 업데이트가 발생할 때까지 기다리는 것으로 확인할 시간이 없습니다.
트레이스에서 트리거를 찾을 수 없거나 실수로 필터링하지 않은 경우 트리거를 배치하고 캡처했기 때문에 누가 그랬는지, 언제 발생했는지 알고 있습니다.
CREATE TABLE dbo.JobAudit
(
[action] CHAR(1),
[table] CHAR(1),
hostname SYSNAME NOT NULL DEFAULT HOST_NAME(),
appname SYSNAME NOT NULL DEFAULT PROGRAM_NAME(),
dt DATETIME2 NOT NULL DEFAULT SYSDATETIME()
);
CREATE TRIGGER dbo.schedule1 ON dbo.sysjobactivity FOR INSERT
AS
INSERT dbo.JobAudit([action], [table] SELECT 'I', 'A';
GO
CREATE TRIGGER dbo.schedule2 ON dbo.sysjobactivity FOR UPDATE
AS
INSERT dbo.JobAudit([action], [table] SELECT 'U', 'A';
GO
CREATE TRIGGER dbo.schedule3 ON dbo.sysjobschedules FOR INSERT
AS
INSERT dbo.JobAudit([action], [table] SELECT 'I', 'S';
GO
CREATE TRIGGER dbo.schedule4 ON dbo.sysjobschedules FOR UPDATE
AS
INSERT dbo.JobAudit([action], [table] SELECT 'U', 'S';
GO
즉, 표준 트레이스를 잡기가 어렵지 않습니다. 이것은 비 동적 DML로도 제공됩니다.
UPDATE msdb.dbo.sysjobschedules
SET next_run_date = 20120817,
next_run_time = 20000
WHERE (job_id = 0xB87B329BFBF7BA40B30D9B27E0B120DE
and schedule_id = 8)
시간이 지남에 따라이 동작을 추적하기 위해 더 필터링 된 추적을 실행하려는 경우 (예 : 주문형 대신 SQL 에이전트 다시 시작을 통해 지속) appname = 'SQLAgent - Schedule Saver'
...
난 당신이 바로 봐 다음 실행 시간을 알고 싶다면 생각 그래서 sysjobactivity
하지를 sysjobschedules
. 이 테이블은 활동이 발생하거나로 통지 될 때 에이전트 또는 백그라운드 스레드 ( "작업 작업 업데이트", "작업 관리자"및 "작업 호출 엔진")에 의해 직접 업데이트됩니다 xp_sqlagent_notify
.
그러나 이러한 테이블에서 데이터를 삭제하는 것에 대한 보호 기능이 없으므로 두 테이블을 모두 정리하는 것이 매우 쉽습니다. (예를 들어 정리하기로 결정한 경우 활동 테이블에서 해당 작업의 모든 행을 쉽게 제거 할 수 있습니다.)이 경우 SQL Server 에이전트가 다음 실행 날짜를 가져 오거나 저장하는 방법을 정확히 알 수 없습니다. 아마도 자유 시간이있을 때 나중에 더 많은 조사를 할만한 가치가있을 것입니다 ...