SQL एजेंट अगले_run_date / next_run_time मूल्यों को कैसे और कब अपडेट करता है?


13

मैं टी-एसक्यूएल में कोड पर काम कर रहा हूं कि एमएसड डेटाबेस में sp_add_jobschedule प्रॉप का उपयोग करके एसक्यूएल एजेंट नौकरी में नए शेड्यूल को जोड़ दूं। जब मैं एक नया शेड्यूल जोड़ता हूं (आम तौर पर एक विशेष तिथि / समय पर एक रन-वे) और तुरंत sysjobschedules और sysschedules में मूल्यों को देखता हूं, तो मैं देख सकता हूं कि नया शेड्यूल जोड़ा गया है और मेरे SQL एजेंट के लिए job_id से बंधा हुआ है काम। हालाँकि, next_run_date और next_run_time के मान उनमें 0 हैं। जब मैं वापस आता हूं और 2 या 3 मिनट में उन्हें फिर से देखता हूं, तब भी वे उनमें 0 दिखाते हैं। हालांकि जब मैं एक और 5 या 10 मिनट बाद वापस आता हूं, तो यह अब सही ढंग से अगले निर्धारित रन के अनुसार दिनांक और समय मान दिखाता है।

तो मेरे सवाल हैं:

  • ये मान कितनी बार अपडेट होते हैं?
  • यह क्या प्रक्रिया है जो इन मूल्यों को अपडेट करती है?
  • अगर मुझे एक शेड्यूल जोड़ना था, तो कहो, भविष्य में 1 मिनट, क्या इसका मतलब यह है कि नौकरी अगले_रुन_डेट / समय से नहीं चलेगी / अभी तक अपडेट नहीं की गई है?

कोड का उदाहरण मैं एक नई अनुसूची जोड़ने के लिए उपयोग करता हूं:

exec msdb.dbo.sp_add_jobschedule @job_id = @jobID
                    , @name = @JobName
                    , @enabled = 1
                    , @freq_type = 1
                    , @freq_interval = 0
                    , @freq_subday_type = 0
                    , @freq_subday_interval = 0
                    , @freq_relative_interval = 0
                    , @freq_recurrence_factor = 0
                    , @active_start_date = @ScheduleRunDate
                    , @active_end_date = 99991231
                    , @active_start_time = @ScheduleRunTime
                    , @active_end_time = 235959

जहाँ @jobID द्विआधारी (16) है जो नौकरी के job_id को सवाल में रखती है, @ScheduleRunDate और @ScheduleRunTime क्रमशः तारीख और समय के साथ INT हैं।


3
यह SQL एजेंट नौकरी के माध्यम से अद्यतन किया गया है। जिसे SQL एजेंट जॉब के जरिए अपडेट किया जाता है। रिकर्सियनवादियों को एकजुट!
हारून बर्ट्रेंड

1
क्षमा याचना। थोड़ी देर में वापस सर्कल करने का मौका नहीं था।
BBLake

जवाबों:


16

संक्षिप्त जवाब

ऐसा लगता है कि msdb.dbo.sysjobschedulesSQL एजेंट में पृष्ठभूमि थ्रेड द्वारा अद्यतन किया गया डेटा 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 सर्वर एजेंट कैसे प्राप्त करता है या अगले रन दिनांक को बचाता है। शायद बाद की तारीख में अधिक जांच के योग्य जब मेरे पास कुछ खाली समय हो ...


यदि पहली बार कोई नौकरी अभी तक नहीं चली है, तो sysjobschedules (अंततः) अगली_run_date और next_run_time के लिए सही मान दिखाएगा, जबकि sysjobactivity.next_scheduled_run_date पहले निष्पादन के बाद तक अशक्त रहता है। जब sysjobactivity से मूल्य प्राप्त करने के लिए आपको ऐसा करने की आवश्यकता होती है जो कि उप-समूह में job_id द्वारा किया जाता है और MAX (next_scheduled_run_date) प्राप्त करता है।
मार्क फ्रीमैन

0

msdb.dbo.sp_help_jobहमेशा सही next_run_date/ वास्तविक लौटाने के लिए प्रकट होता है next_run_time

यह उपयोग करता है sp_get_composite_job_info, जो वास्तव में पुनः प्राप्त करने के लिए निम्न कॉल करता है next_run_date/time

      IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
        INSERT INTO @xp_results
        EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner, @job_id
      ELSE
        INSERT INTO @xp_results
        EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner

चूंकि sysjobscheduleअविश्वसनीय प्रतीत होता है, मैं सिर्फ उपयोग करूंगा sp_help_job

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.