Führen Sie den Server Agent-Job nur dann planmäßig aus, wenn die CPU inaktiv ist

8

Ich habe einen Job in SQL Server Agent eingerichtet, um eine Aktualisierungsabfrage auszuführen. Ich möchte, dass dieser Job jede Nacht zwischen Mitternacht und 5 Uhr morgens ausgeführt wird, und ich möchte, dass er in diesem Zeitraum alle 5 Minuten wiederholt wird. Aber ich möchte nur, dass der Job tatsächlich ausgeführt wird, wenn die CPU im Leerlauf ist, dh die CPU-Auslastung liegt unter 20%. Ich weiß, dass ich den Zeitplan einrichten kann, und ich kann die CPU-Leerlaufanforderung auch separat einrichten. Gibt es eine Möglichkeit für mich, es so einzurichten, dass beide "Zeitpläne" wahr sein müssen, damit der Job ausgeführt werden kann?

Vielen Dank

c.dunlap
quelle

Antworten:

6

Oder Sie können einen Job haben, der alle 5 Minuten in zwei Schritten ausgeführt wird:

Schritt 1 - Überprüft die CPU-Auslastung (PowerShell), googeln Sie einfach und es gibt viele Skripte. Wenn <20% mit Erfolg beendet werden, fahren Sie mit Schritt 2 fort, andernfalls mit Fehler beenden und den Auftrag beenden (kein Schritt 2).

Schritt 2 - ist das eigentliche UPDATE.

Oder wie Ken vorgeschlagen hat.

DenisT
quelle
2
Ich mag diesen. Ich denke, es ist eine bessere Lösung.
KenWilson
4

Die CPU-Auslastung liegt unter 20%

Konfigurieren Sie den SQL-Agenten über das Fenster Erweiterte Eigenschaften für den Zustand der inaktiven CPU . Sie würden den Wert "Durchschnittliche CPU-Auslastung fällt unter" auf 20% setzen und dann festlegen, wie lange er auf diesem Niveau bleiben muss, bevor der Job ausgeführt wird.

Konfigurieren Sie anschließend den Jobschritt, um die Zeit zu überprüfen, in der sichergestellt ist, dass er sich in Ihrem Fenster befindet, wenn Sie innerhalb des Fensters den Befehl update ausgeben.

Jetzt wird die Anforderung für alle 5 Minuten möglicherweise nicht genau mit diesem Setup erfüllt. Ich konnte in diesem Zeitplantyp nichts finden, das angibt, wie oft der Job ausgeführt werden würde. [Wenn Sie beispielsweise "und bleibt unter diesem Wert" für den Leerlauf-CPU-Zustand auf 30 Sekunden setzen, wird der Job dann so häufig ausgeführt?] Dies würde einige Tests erfordern, da ich diese Konfiguration noch nie zuvor verwendet habe. Wenn ich eine Chance bekomme, kann ich versuchen zu sehen, was es tut und werde diese Antwort aktualisieren.


quelle
Die CPU-Auslastungsbedingung funktioniert folgendermaßen: Wenn die CPU für die angegebene Dauer unter dem angegebenen Schwellenwert war, wird das Ereignis ausgelöst und der Job ausgeführt. Wenn die CPU noch eine Sekunde im Leerlauf bleibt, wird das Ereignis erneut ausgelöst, sodass der Job erneut ausgeführt wird. Es kann jedoch immer nur eine Instanz eines Jobs gleichzeitig ausgeführt werden. Das reale Ergebnis ist also, dass der Job weiterhin gestartet, ausgeführt, beendet und wiederholt wird, solange die CPU inaktiv bleibt.
c.dunlap
2

Ein Weg wäre, drei Jobs zu haben. Job eins wird nach einem Zeitplan festgelegt, der Job zwei am Anfang des Fensters aktiviert. Job zwei wird ausgeführt, wenn die CPU inaktiv ist und der dritte Job Job zwei am Ende des Fensters deaktiviert. Ich denke nicht, dass dies der einzige Weg ist, aber es ist definitiv der einfachste in meinem Kopf.

KenWilson
quelle
2

Denis war sehr nah. Aber die eigentliche Lösung wurde ein wenig getauscht. Da Powershell die CPU nicht über einen bestimmten Zeitraum überprüfen kann, sondern nur über die aktuelle Nutzung, musste die SQL Server-Prüfung verwendet werden.

Mein erster Schritt bestand darin, ein PowerShell-Skript auszuführen, das prüft, ob die aktuelle Systemzeit zwischen den beiden Zeitbeschränkungen liegt. Wenn dies der Fall ist, führt das Powershell-Skript nichts aus. Der SQL Server-Job interpretiert dies als Erfolg.

Anschließend fährt der Job mit dem letzten Schritt fort und führt die Aktualisierungsabfrage durch.

Wenn die aktuelle Zeit jedoch außerhalb des Bereichs liegt, Start-Time -s 600führe ich a aus, um das Powershell-Skript für 10 Minuten anzuhalten (simuliert die "einmalige Anforderung von 5 bis 10 Minuten"), um zu verhindern, dass der SQL Server-Agent ständig versucht, diesen Job auszuführen .

Nach 10 Minuten gibt das Powershell-Skript einen benutzerdefinierten Fehler aus. Da ich $ErrorActionPreference = "Stop"am Anfang des Skripts habe, wird das Powershell-Skript nach dem Fehler nicht mehr ausgeführt. Dieser Schritt ist sehr wichtig.

Da Powershell gestoppt wurde und nicht zurückgegeben wurde, interpretiert der SQL Server-Agent dies als Fehler und fährt nicht mit dem Schritt fort, der die Aktualisierungsabfrage ausführt.

PS Ihr habt mich in die richtige Richtung geführt. Wenn ich genug Ruf hätte, würde ich euch positiv bewerten.

Bearbeiten: Powershell-Skript hinzugefügt

$ErrorActionPreference = "Stop"

$StartTime = Get-Date "12:00 AM"
$EndDate = Get-Date "05:00 AM"
$CurrentDate = Get-Date
$ExecuteJob = $StartTime -lt $CurrentDate -and $EndDate -gt $CurrentDate
if(!$ExecuteJob){    
    Start-Sleep -s 600
    throw "Current Time not within Server downtime"
}
c.dunlap
quelle
1
PowerShell kann die CPU über einen bestimmten Zeitraum mithilfe des Cmdlets Get-Counter überprüfen. Sie können den Wert alle 5 Sekunden über 45 Sekunden abfragen mit: $ t = Get-Counter "\ Processor (_total) \% Processor Time" -SampleInterval 5 -MaxSamples 10. Anschließend können Sie die Zeichenfolge analysieren, um nur die Werte abzurufen: $ t.Readings.Trim ("\\ Server \ Prozessor (_Total) \% Prozessorzeit:")
Ja, aber dies würde erfordern, dass ich SQL Server erlaube, diesen Job alle 5 Sekunden auszuführen. Da SQL Server die CPU-Auslastung bereits über einen längeren Zeitraum überwacht, habe ich mich für diesen Weg entschieden. Dadurch kann ich den Job nur alle 10 Minuten ausführen, wenn die CPU zu hoch ist.
c.dunlap