Betriebssystem-Jobs aus Oracle starten
In diesem Artikel soll es darum gehen, wie man aus einer Oracle Datenbank heraus Programme auf Betriebssystem-Ebene starten kann. Für den hier beschriebenen Weg wird mindestens Version 10g vorausgesetzt.
Inhalt
- Einrichten des Schedulers
- Benötigte Privilegien
- Einen "Externen Job" einrichten
- Stolperquellen
- Startverzeichnis
- ORA-27370: job slave failed to launch a job of type EXECUTABLE
- ORA-27369: job of type EXECUTABLE failed with exit code: Incorrect function
- ORA-27369: job of type EXECUTABLE failed with exit code: Not owner
- ORA-27300: OS system dependent operation:accessing execution agent failed with status: 2
Einrichten des Schedulers
Linux/Unix
Wie im Metalink-Dokument
391820.1
beschrieben, sind für die Benutzung des Schedulers ein paar Vorarbeiten nötig.
Als erstes müssen wir uns um die Konfigurationsdatei
$ORACLE_HOME/rdbms/admin/externaljob.ora kümmern:
chown root:oinstall $ORACLE_HOME/rdbms/admin/externaljob.ora
chmod 640 $ORACLE_HOME/rdbms/admin/externaljob.ora
Die Gruppe kann alternativ auch dba, Besitzer muss jedoch zwingend root
sein. Auch darf außer root niemand Schreibrechte auf diese Datei haben.
Nun kommt die Frage: Unter welchem Benutzer sollen die aus Oracle gestarteten
Programme laufen? Aus Sicherheitsgründen ist dies i. d. R. nicht oracle:dba,
sonst könnte sich ja jemand durch die Hintertür DBA-Rechte erschleichen, oder
an der Datenbank-Konfiguration schrauben. Dagegen spricht natürlich nichts,
wenn die entsprechend privilegierten Benutzer alle vertrauenswürdig
sind (also z. B. nur der Admin selbst über dieses Privileg verfügt). Die
Empfehlung seitens Oracle heißt: Es sollte ein möglichst unprivilegierter
Nutzer sein, i. d. R. also nobody.
Dieser Benutzer ist nun am Ende der Datei
$ORACLE_HOME/rdbms/admin/externaljob.ora einzutragen:
run_user = nobody
run_group = nobody
Abschließend noch die Datei $ORACLE_HOME/bin/extjob mit den passenden Rechten
versehen, und diese Aufgabe ist abgeschlossen:
chown root:oinstall $ORACLE_HOME/bin/extjob
chmod 4750 $ORACLE_HOME/bin/extjob
Auch hier gilt wieder: Die Gruppe kann auch dba sein, alles andere muss so
stehen bleiben.
Windows
Auch wenn obige Gedanken hier grundlegend ebenfalls gelten, scheint sich der Scheduler unter Windows herzlich wenig um obige Dateien zu scheren. Hier gilt vielmehr folgendes:
- Der Dienst
OracleJobScheduler%ORACLE_SID%muss gestartet sein - Benutzer (und damit indirekt die Gruppe) muss hier über den gerade genannten Dienst konfiguriert werden (Eigenschaften des Dienstes)
Benötigte Privilegien
Um nun Betriebssystem-Jobs einrichten zu können, braucht der jeweilige
Datenbank-Benutzer mindestens noch die Berechtigungen CREATE JOB sowie
CREATE EXTERNAL JOB.
Einen "Externen Job" einrichten
Jetzt können wir einen "externen Job" zur Ausführung eines Betriebssystem-Kommandos einrichten:
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'my_job',
job_type => 'executable',
job_action => '/path/to/executable',
enabled => true,
auto_drop => false
);
Eigentlich selbsterklärend. Hinweis: Der job_name muss für die Ausführung
wieder angegeben werden – daher sollte er kurz und prägnant sein. Setzt man
auto_drop => true, wird der Job nach der letzten Ausführung automatisch
wieder gelöscht.
Letzte Ausführung? Naja, das Beispiel ist minimal. Es lassen sich natürlich auch noch Ausführungszeiten etc. angeben – steht alles in der Oracle Dokumentation. In diesem Artikel soll es nur um das Prinzip (und die Handicaps) gehen.
Zumindest unter Windows sollte man die job_action sicherheitshalber mit einer
Umleitung versehen, also z.B. job_action => 'C:\test.bat >nul'. Sobald der
Job nämlich eine Ausgabe erzeugt, fällt der Scheduler gern einmal auf die Nase.
Einen "Externen Job" ausführen
Hat man keine Angaben zu Ausführungszeiten gemacht, oder möchte aus anderen Gründen einen solchen "scheduled job" manuell ausführen, geht dies ganz einfach über den Befehl
DBMS_SCHEDULER.RUN_JOB('my_job');
Unschwer erkennbar: Der Parameter ist das, was beim Einrichten des Jobs als
job_name definiert wurde.
Stolperquellen
… gibt es durchaus:
Startverzeichnis
Skripte starten nicht unbedingt in dem Verzeichnis, in welchem sie sich
befinden – sondern i. d. R. im Wurzelverzeichnis /. Das Skript-Verzeichnis
lässt sich in der Bash jedoch leicht ermitteln:
cd ${0%/*}
ORA-27370: job slave failed to launch a job of type EXECUTABLE
ORA-27370: job slave failed to launch a job of type EXECUTABLE
ORA-27300: OS system dependent operation:getting external job pid failed with status: 2
ORA-27301: OS failure message: No such file or directory
Das heißt meist, obige Anleitung wurde nicht richtig ausgeführt. Berechtigungen der beiden o. g. Dateien prüfen, und auch den konfigurierten Benutzer.
ORA-27369: job of type EXECUTABLE failed with exit code: Incorrect function
In diesem Fall stimmt etwas mit dem Betriebssystem-Kommando nicht:
- Das auszuführende Programm existiert nicht (Tippfehler?). Es kommt
kein "File does not exist", wenn z.B. eine Batch-Datei über
cmd.exeausgeführt wird (job_name=>'C:\Windows\System32\cmd.exe /q /c C:\test.cmd >nul') –cmd.exewurde ja gefunden - Das auszuführende Programm produziert Ausgaben, die nicht abgefangen
werden (daher das
>nul– der Scheduler mag keine Ausgaben, nur einen Errorlevel=0
ORA-27369: job of type EXECUTABLE failed with exit code: Not owner
ORA-27369: job of type EXECUTABLE failed with exit code: Not owner
ORA-06512: at "SYS.DBMS_ISCHED", line 150
ORA-06512: at "SYS.DBMS_SCHEDULER", line 441
ORA-06512: at line 1
Das kommt gern vor, und der (triviale) Fehler ist nicht unbedingt leicht zu finden: Der Scheduler lädt das Environment nicht mit – wer also in Scripten auf Umgebungsvariablen zugreift, muss diese zunächst selbst im Skript definieren. Klassiker:
. $HOME/.bashrc
Gut gedacht – geht aber leider in die Hose, und führt genau zu obigem Fehler:
Da $HOME nicht, wie erwartet, gesetzt ist, heißt die resultierende
Datei /.bashrc. Und die gehört nicht dem ausführenden Benutzer
(genau genommen existiert sie wahrscheinlich nicht einmal – aber wir kennen
ja unsere Oracle Fehlermeldungen bzgl. ihrer Genauigkeit und Treffsicherheit).
Man muss also alle Pfade selbst ermitteln. Naja, nicht alle: der $PATH
scheint zumindest gesetzt zu sein …
ORA-27300: OS system dependent operation:accessing execution agent failed with status: 2
Wer Oracle auf einer PlayStat… ahem, Windows laufen hat, muss auch den Service
OracleJobScheduler%ORACLE_SID% starten.
