คำตอบสั้น ๆ
ดูเหมือนว่าข้อมูลในmsdb.dbo.sysjobschedules
จะได้รับการอัปเดตโดยเธรดพื้นหลังใน SQL Agent ซึ่งระบุว่าเป็นSQLAgent - Schedule Saver
ทุก ๆ 20 นาที (หรือน้อยกว่านี้หากxp_sqlagent_notify
ไม่ได้รับการโทรและไม่มีงานใดทำงานในระหว่างนี้)
สำหรับข้อมูลที่ถูกต้องมากขึ้นดูที่ในnext_scheduled_run_date
msdb.dbo.sysjobactivity
สิ่งนี้ได้รับการปรับปรุงแบบเรียลไทม์ทุกครั้งที่มีการเปลี่ยนแปลงงานหรืองานที่ทำ ในฐานะโบนัสที่เพิ่มเข้ามานั้นจะsysjobactivity
เก็บข้อมูลอย่างถูกต้อง (เป็นคอลัมน์วันที่) ทำให้การทำงานง่ายขึ้นกว่า INT ที่โง่
นั่นเป็นคำตอบสั้น ๆ :
อาจถึง 20 นาทีก่อนที่sysjobschedulesจะสะท้อนความจริง อย่างไรก็ตาม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 Agent ต่อไปนี้ถูกเรียกโดย SQL Agent:
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 Agent เช่น:
SQLAgent - Job Manager
SQLAgent - Update job activity
SQLAgent - Job invocation engine
SQLAgent - Schedule Saver
ด้ายพื้นหลัง (ที่ "กำหนดการ 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 Agent พร้อมกันบนเซิร์ฟเวอร์เหล่านี้ แต่มีความเป็นไปได้ระยะไกลที่เวลาเริ่มต้นเกิดขึ้นเพื่อชดเชย 20 นาที ฉันสงสัย แต่ตอนนี้ฉันไม่มีเวลายืนยันโดยการรีสตาร์ท Agent ที่หนึ่งในนั้นและรอการอัปเดตเพิ่มเติมที่จะเกิดขึ้น
ฉันรู้ว่าใครทำและเมื่อมันเกิดขึ้นเพราะฉันวางไกที่นั่นและจับมันในกรณีที่ฉันไม่สามารถหามันได้ในร่องรอยหรือไม่ได้กรองออกโดยไม่ได้ตั้งใจ
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 Agent แทนที่จะเป็นแบบออนดีมานด์) คุณสามารถเรียกใช้งานที่มี appname = 'SQLAgent - Schedule Saver'
...
ดังนั้นผมคิดว่าถ้าคุณต้องการที่จะรู้ว่าเวลาทำงานต่อไปทันทีดูที่ไม่sysjobactivity
sysjobschedules
ตารางนี้จะมีการปรับปรุงโดยตรงจากตัวแทนหรือหัวข้อพื้นหลัง ( "กิจกรรมงานปรับปรุง", "ผู้จัดการ" และ "เครื่องมือภาวนางาน") xp_sqlagent_notify
เป็นกิจกรรมที่เกิดขึ้นหรือที่จะได้รับแจ้งจาก
อย่างไรก็ตามโปรดทราบว่ามันง่ายมากที่จะโคลนตารางทั้งสอง - เนื่องจากไม่มีการป้องกันการลบข้อมูลจากตารางเหล่านี้ (ดังนั้นหากคุณตัดสินใจที่จะล้างข้อมูลตัวอย่างเช่นคุณสามารถลบแถวทั้งหมดสำหรับงานนั้นออกจากตารางกิจกรรมได้อย่างง่ายดาย) ในกรณีนี้ฉันไม่แน่ใจว่า SQL Server Agent รับหรือบันทึกวันที่ทำงานถัดไปได้อย่างไร บางทีน่าจะมีการสอบสวนเพิ่มเติมในภายหลังเมื่อฉันมีเวลาว่าง ...