Oracle Scheduler Jobs Kurzfassung

Oracle Scheduler Jobs – eine Kurzfassung

Wer regelmäßig automatische Vorgänge in seiner Datenbank laufen lässt, wie zum Beispiel das Aufrufen von Services, Datenübernahmen oder regelmäßige Berechnungen, der wird sehr bald auf Oracle Scheduler Jobs treffen. Diese können auf verschiedene Arten regelmäßig Prozeduren und ähnliches in regelmäßigen Abständen ausführen.

Die grundlegende Definition benötigt zumindest folgende Parameter:

  • job_name: der Name des Scheduler Jobs
  • job_type: der Typ des Scheduler Jobs, ist es ein PL/SQL Block oder ein direkter Prozeduraufruf, …
  • job_action: der tatsächlich auszuführende Ausdruck (abhängig von job_type)

und würde dann so aussehen:

begin
  dbms_scheduler.create_job(job_name   => 'DELETE_LOGS',
                            job_type   => 'PLSQL_BLOCK',
                            job_action => 'begin delete from my_logs; end;');
end;
/

select * from user_scheduler_jobs;

Dieser Scheduler Job wird erstmal nur erstellt werden, aber nicht laufen. Das liegt am Attribut enabled. Dieses wird per Default auf FALSE gesetzt. Der Job muss also mittels eines eigenen Befehls ausgeführt werden (alternativ kann das Attribut beim Erstellen des Jobs bereits auf TRUE gesetzt werden, dann läuft der Job zum angegebenen start_date):

begin
  dbms_scheduler.run_job(job_name            => 'DELETE_LOGS',
                         use_current_session => FALSE);
end;

Mit diesem Befehl läuft der Job einmal durch. Das Attribut use_current_session definiert dabei, ob die aktuelle Session dafür verwendet wird, oder der Job in eines eigenen Session ausgeführt wird (aus persönlicher Erfahrung würde ich immer FALSE als Wert mit übergeben).

Im oben beschriebenen Fall wird der Job nach dem Durchlauf gelöscht. Auch das wird durch ein Attribut gesteuert: auto_drop. Dieses wird standardmäßig beim erstellen auf TRUE gesetzt. Wird beim Erstellen der Wert mit FALSE übergeben, so wird der Job nicht gelöscht sondern kann beliebig oft ausgeführt werden.

Sämtliche Attribute können nach Erstellung des Jobs noch angepasst werden, zum Beispiel mit folgendem Statement:

begin
  dbms_scheduler.set_attribute(name      => 'DELETE_LOGS',
                               attribute => 'auto_drop',
                               value     => FALSE);
end;

Die Funktion ist überladen, im Attribut Value muss immer der korrekte Datentyp verwendet werden (hier BOOLEAN).

Soll der Job nun regelmäßig laufen, so muss das Attribut repeat_interval korrekt gesetzt sein. Dieses bietet nahezu unbegrenzte Möglichkeiten, die genaue Syntax entnehmen sie bitte der Package Dokumentation die am Ende des Artikels verlinkt ist. Gleichermaßen kann das Startdatum (default Jetzt) mit dem Attribut start_date gesetzt werden.

Die Jobs protokollieren jeden Lauf mit Status, Outputs, Dauer und noch etlichen anderen Parametern.

select * from user_scheduler_job_log;
select * from user_scheduler_job_run_details;

Nehmen wir an Sie fragen alle Minuten ein Webservice ab. Wenn der Job mit den Standard Werten erstellt wurde, wird dann jede Minute eine Zeile im Log und eine in den Laufdetails erstellt und eine Zeile für den Output erstellt (Im Output wird alles was per dbms_output.put_line etc. ausgegeben wird in einem BLOB Feld gespeichert).
Im Falle eines Webservice kann das potentiell der Request und Response Wert sein. Das kann schon eine entsprechend große Menge an Daten werden und das jede Minute. Wird das Log aber nicht oder nur im Fehlerfall benötigt bzw. soll der Output nicht gespeichert werden, so kann das durch die Attribute store_output und job_class geregelt werden.

Das Attribut store_output ist wie das Attribut auto_drop oder enabled und kann dementsprechend gesetzt werden. Die job_class ist etwas komplexer. Job Klassen definieren Standard Attribute für alle Jobs denen die Klasse zugewiesen wird. Insbesondere auch das Logging Level und die Log History, das ist die Dauer wie lange Job Logs gespeichert werden. Wird keine Klasse angegeben, dann erhält ein erstellter Job automatisch die Klasse DEFAULT_JOB_CLASS. Diese protokolliert alle Durchläufe und speichert die Logs entsprechend dem Scheduler Attribut log_history.

declare
  val VARCHAR2(4000);
begin
  dbms_scheduler.get_scheduler_attribute(attribute => 'log_history',
                                         value     => val);
  dbms_output.put_line(val);
end;

Ist dieses Attribut entsprechend hoch gesetzt (z.B. 1000), dann werden Logs 1000 Tage nach Erstellung gelöscht. Bei einem minütlich laufenden Prozess sind das dann 60*24*1000 = 1.440.000 Zeilen Log Einträge. Wird nun noch ein Output mitgespeichert, so kann das Job Log potentiell sehr groß werden (bei 10 KB Output sind wir bereits bei 14.400.000 KB das entspricht knapp 14 GB). Um das zu verhindern kann man die Scheduler Job Klasse bei der Erstellung mit angeben oder im Nachhinein wie jedes Attribut des Jobs setzen. Folgende zwei Job Klassen sind hier interessant, da standardmäßig vorhanden:

  • SCHED$_LOG_ON_ERRORS_CLASS: Log History wie DEFAULT_JOB_CLASS aber es werden nur fehlerhafte Läufe im Log festgehalten
  • NOLOG_JOBS: Es werden keine Logs geschrieben

Alle vorhandenen Klassen können mittels

select * from dba_scheduler_job_classes;

abgerufen werden.

Eine wichtige Sache muss hier unbedingt beachtet werden. Nehmen wir an wir wollen unserem DELETE_LOGS Scheduler Job die NOLOG_JOBS Klasse zuweisen. Das Statement dafür würde wie folgt aussehen:

begin
  dbms_scheduler.set_attribute(name      => 'DELETE_LOGS',
                               attribute => 'job_class',
                               value     => 'NOLOG_JOBS');
end;

Wenn dieses Statement nun ausgeführt wird, so kann es sein, dass der Fehler ORA-01031 insufficient privileges zurückgegeben wird, und der Job danach disabled ist. Ist das der Fall, so muss der Benutzer welcher den Job erstellt hat EXECUTE Recht für die NOLOG_JOBS Klasse erhalten:

/* Auszuführen als SYS */grant execute on NOLOG_JOBS to [USERNAME];
/* Reenable Job and set auto-drop to FALSE*/begin  dbms_scheduler.enable(name => 'DELETE_LOGS');
  dbms_scheduler.set_attribute(name      => 'DELETE_LOGS',
                               attribute => 'auto_drop',
                               value     => false);
end;

Damit sollte der Job die neue Klasse haben und wieder wie zuvor ausgeführt werden.

DBMS_SCHEDULER in Oracle 12c: https://docs.oracle.com/database/121/ARPLS/d_sched.htm#ARPLS72235

DBMS_SCHEDULER in Oracle 11g: http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sched.htm

0 Antworten

Hinterlassen Sie einen Kommentar

Wollen Sie an der Diskussion teilnehmen?
Feel free to contribute!

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.