संक्षिप्त जवाब
ऐसा लगता है कि msdb.dbo.sysjobschedules
SQL एजेंट में पृष्ठभूमि थ्रेड द्वारा अद्यतन किया गया डेटा SQLAgent - Schedule Saver
, प्रत्येक 20 मिनट (या कम बार, यदि xp_sqlagent_notify
कॉल नहीं किया गया है और इस बीच कोई नौकरी नहीं चली है) के रूप में पहचाना जाता है ।
अधिक सटीक जानकारी के लिए, next_scheduled_run_date
में देखें msdb.dbo.sysjobactivity
। यह वास्तविक समय में किसी भी समय नौकरी बदलने या नौकरी चले जाने पर अद्यतन किया जाता है। एक अतिरिक्त बोनस के रूप में, sysjobactivity
डेटा को सही तरीके से (डेटाइम कॉलम के रूप में) संग्रहीत करता है, जिससे उन लोगों के साथ काम करना बहुत आसान हो जाता है।
इसका संक्षिप्त उत्तर है:
यह 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 को 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
एक बैकग्राउंड थ्रेड ("शेड्यूल सेवर" थ्रेड) अंततः चारों ओर आता है और अपडेट करता है sysjobschedules
; मेरी प्रारंभिक जांच से ऐसा प्रतीत होता है कि यह हर 20 मिनट में होता है, और केवल तब होता है xp_sqlagent_notify
जब पिछली बार इसे चलाने के बाद नौकरी में किए गए बदलाव के कारण बुलाया गया हो (मैंने यह देखने के लिए आगे कोई परीक्षण नहीं किया कि क्या होता है यदि एक नौकरी हो गई है बदल गया है और एक और चलाया गया है, यदि "शेड्यूल सेवर" थ्रेड दोनों को अपडेट करता है - मुझे संदेह है कि यह अवश्य होगा, लेकिन पाठक को एक अभ्यास के रूप में छोड़ देगा)।
मुझे यकीन नहीं है कि जब एसक्यूएल एजेंट शुरू होता है, या आधी रात से, या कुछ मशीन-विशिष्ट से ऑफसेट होता है। एक ही भौतिक सर्वर पर दो अलग-अलग उदाहरणों पर, "शेड्यूल सेवर" थ्रेड अद्यतन sysjobschedules
, दोनों उदाहरणों पर, लगभग एक ही समय में - 18:31:37 और 18:51:37 एक पर, और 18:31:39 और 18:51:39 दूसरे पर। मैंने इन सर्वरों पर एक ही समय में SQL सर्वर एजेंट शुरू नहीं किया था, लेकिन एक दूरस्थ संभावना है कि प्रारंभ समय 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
कहा कि, एक मानक ट्रेस के साथ पकड़ना मुश्किल नहीं है, यह एक गैर-गतिशील डीएमएल के रूप में भी आता है:
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 सर्वर एजेंट कैसे प्राप्त करता है या अगले रन दिनांक को बचाता है। शायद बाद की तारीख में अधिक जांच के योग्य जब मेरे पास कुछ खाली समय हो ...