Ich habe in T-SQL an Code gearbeitet, um einem SQL Agent-Job mithilfe des Befehls sp_add_jobschedule in der Datenbank msdb neue Zeitpläne hinzuzufügen. Wenn ich einen neuen Zeitplan (normalerweise eine einmalige Ausführung zu einem bestimmten Datum / einer bestimmten Uhrzeit) hinzufüge und sofort die Werte in sysjobschedules und sysschedules betrachte, kann ich feststellen, dass der neue Zeitplan hinzugefügt wurde und mit der job_id für meinen SQL-Agenten verknüpft ist Job. Die Werte für next_run_date und next_run_time enthalten jedoch 0. Wenn ich zurückkomme und sie mir in zwei oder drei Minuten noch einmal ansehe, zeigen sie immer noch Nullen. Wenn ich jedoch noch 5 oder 10 Minuten später zurückkomme, werden Datum und Uhrzeit des nächsten geplanten Laufs korrekt angezeigt.
Meine Fragen sind also:
- Wie oft werden diese Werte aktualisiert?
- Welcher Prozess aktualisiert diese Werte?
- Wenn ich einen Zeitplan hinzufügen würde, der beispielsweise 1 Minute in der Zukunft liegt, würde dies bedeuten, dass der Job nicht ausgeführt wird, da das Datum / die Uhrzeit für die nächste Ausführung noch nicht aktualisiert wurden?
Beispiel für den Code, mit dem ich einen neuen Zeitplan hinzufüge:
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
Dabei ist @jobID eine Binärdatei (16), die die job_id des betreffenden Jobs enthält. @ScheduleRunDate und @ScheduleRunTime sind INTs mit Datum und Uhrzeit.
Antworten:
Kurze Antwort
Es sieht so aus, als würden die Daten in alle 20 Minuten
msdb.dbo.sysjobschedules
von einem Hintergrundthread in SQL Agent aktualisiertSQLAgent - Schedule Saver
(oder seltener, wennxp_sqlagent_notify
sie nicht aufgerufen wurden und in der Zwischenzeit keine Jobs ausgeführt wurden).Weitere Informationen finden Sie
next_scheduled_run_date
inmsdb.dbo.sysjobactivity
. Dies wird in Echtzeit jedes Mal aktualisiert, wenn ein Job geändert oder ausgeführt wird. Als zusätzlichen Bonussysjobactivity
speichert das die Daten richtig (als Datum / Uhrzeit-Spalte), wodurch es viel einfacher ist, damit zu arbeiten als mit diesen dummen INTs.Das ist die kurze Antwort:
Lange Antwort
Wenn Sie dem Kaninchen einen Moment lang folgen möchten, wenn Sie anrufen
sp_add_jobschedule
, wird diese Ereigniskette in Gang gesetzt:Jetzt können wir das Kaninchen nicht mehr weiter verfolgen, weil wir nicht wirklich sehen können, was es
xp_sqlagent_notify
tut. Ich denke jedoch, dass wir davon ausgehen können, dass dieses erweiterte Verfahren mit dem Agentenservice interagiert und dass es eine Änderung an diesem bestimmten Job und Zeitplan gegeben hat. Indem wir einen serverseitigen Trace ausführen, können wir sofort feststellen, dass der folgende dynamische SQL-Code vom SQL-Agenten aufgerufen wird:Es scheint, dass
sysjobactivity
das sofort aktualisiert wird undsysjobschedules
nur nach einem Zeitplan aktualisiert wird. Wenn wir den neuen Zeitplan auf einmal am Tag ändern, zWir sehen immer noch das sofortige Update auf
sysjobactivity
wie oben und dann ein weiteres Update, nachdem der Job beendet ist. Verschiedene Updates stammen aus dem Hintergrund und anderen Threads in SQL Agent, z.Ein Hintergrund-Thread (der "Schedule Saver" -Thread) erscheint und wird aktualisiert
sysjobschedules
. meiner ersten Untersuchung zufolge ist dies alle 20 Minuten der Fall und geschieht nur, wennxp_sqlagent_notify
ein Aufruf aufgrund einer Änderung eines Jobs seit seiner letzten Ausführung erfolgt ist (ich habe keine weiteren Tests durchgeführt, um festzustellen, was passiert, wenn ein Job ausgeführt wurde) geändert und ein anderer wurde ausgeführt, wenn der Thread "Schedule Saver" beide aktualisiert - ich vermute, es muss, überlässt dies aber dem Leser als Übung).Ich bin nicht sicher, ob der 20-Minuten-Zyklus vom Zeitpunkt des Starts von SQL Agent, von Mitternacht oder von einem bestimmten Computer abweicht. Auf zwei verschiedenen Instanzen auf demselben physischen Server wurde der Thread "Schedule Saver"
sysjobschedules
auf beiden Instanzen fast zur gleichen Zeit aktualisiert - 18:31:37 und 18:51:37 auf einer und 18:31:39. 18:51:39 auf der anderen Seite. Ich habe den SQL Server-Agenten auf diesen Servern nicht gleichzeitig gestartet, aber es besteht die Möglichkeit, dass die Startzeiten 20 Minuten versetzt sind. Ich bezweifle es, aber ich habe momentan keine Zeit, es zu bestätigen, indem ich Agent auf einem von ihnen neu starte und auf weitere Updates warte.Ich weiß, wer es getan hat und wann es passiert ist, weil ich dort einen Abzug platziert und ihn erfasst habe, falls ich ihn nicht in der Spur finden konnte oder ich ihn versehentlich herausgefiltert habe.
Das heißt, es ist nicht schwer, mit einem Standard-Trace zu fangen, dieser kommt sogar als nicht-dynamisches DML durch:
Wenn Sie eine stärker gefilterte Ablaufverfolgung ausführen möchten, um dieses Verhalten über einen längeren Zeitraum nachzuverfolgen (z. B. bei einem Neustart des SQL-Agenten statt bei Bedarf), können Sie eine Ablaufverfolgung ausführen, die appname =
'SQLAgent - Schedule Saver'
... hat.Also ich denke, wenn du die nächste Laufzeit sofort wissen willst, sieh dir das an
sysjobactivity
, nichtsysjobschedules
. Diese Tabelle wird direkt vom Agenten oder seinen Hintergrundthreads ("Jobaktivität aktualisieren", "Jobmanager" und "Jobaufruf-Engine") aktualisiert, wenn eine Aktivität stattfindet oder von dieser benachrichtigt wirdxp_sqlagent_notify
.Beachten Sie jedoch, dass es sehr einfach ist, eine der beiden Tabellen auszutricksen, da es keinen Schutz gegen das Löschen von Daten aus diesen Tabellen gibt. (Wenn Sie sich beispielsweise für eine Bereinigung entschieden haben, können Sie problemlos alle Zeilen für diesen Job aus der Aktivitätstabelle entfernen.) In diesem Fall bin ich mir nicht sicher, wie der SQL Server-Agent das nächste Ausführungsdatum abruft oder speichert. Vielleicht verdient eine spätere Untersuchung mehr, wenn ich etwas Freizeit habe ...
quelle
msdb.dbo.sp_help_job
scheint immer das richtige aktuellenext_run_date
/ zurückzugebennext_run_time
.Es wird verwendet
sp_get_composite_job_info
, um den folgenden Aufruf tatsächlich abzurufennext_run_date/time
.Da
sysjobschedule
scheint unzuverlässig zu sein, würde ich nur verwendensp_help_job
.quelle