Über unsMediaKontaktImpressum
Alexander Hofstetter 05. Dezember 2017

Oracle 12.2: Neue Funktionen des Datenbank-Schedulers

Der DBMS_SCHEDULER kann komplexe Jobketten starten. © Olly / Fotolia.com
© Olly / Fotolia.com

Der DBMS_SCHEDULER bietet mehr als nur eine einfache Jobausführung. Zu den Grundfunktionen gehört außer der simplen Jobausführung auch die Möglichkeit, komplexe Jobketten zu starten. In diesem Artikel werden einige Basisfunktionen, die generelle Funktionsweise, sowie neue Features des Schedulers in Version 12c Release 2 beschrieben. Der Fokus liegt auf den neuen Features. Weiterhin werden Grundfunktionen, die durch die neuen Features benötigt oder erweitert und ergänzt werden, detaillierter erklärt.

Zuerst wird die Arbeitsweise des DBMS_SCHEDULERS betrachtet. Anschließend ein Blick auf die Job-Arten und den Resource Manager gelegt. Dadurch werden die Vorteile des Schedulers im Vergleich zu den klassischen Jobs durch DBMS_JOBS dargestellt. Zu diesen Stärken gehören unter anderem die umfangreichen Möglichkeiten der zeit- und eventbasierten Jobsteuerung, sowie die Jobs vom Resource Manager der Datenbank beeinflussen zu lassen. Die neuen Features in Oracle 12.2 sind Job Incompatibilities, Resource Queues und In-Memory-Jobs. Bei diesen werden Funktionsweise und Syntax mit Beispielen erklärt.

Die Basics

Der Scheduler wurde mit Oracle 10g Release 1 als Nachfolger von DBMS_JOBS eingeführt. Das Paket DBMS_JOBS wurde mit der Version 12c Release 2 abgekündigt ("deprecated") und wird in einer zukünftigen Version der Datenbank nicht mehr zur Verfügung stehen. Anders als die alte Jobsteuerung bietet der Scheduler nicht nur eine zeitbasierte sondern auch eine ereignisbasierte Jobausführung. Weitere Vorteile sind die mitgelieferten Monitoring-, Logging- und Reportingmöglichkeiten. Zusätzlich kann man den Scheduler mittels Job Classes oder Windows an den Resource Manager anbinden.

Die erstellten Jobs werden in der Tabelle sys.scheduler$_job gespeichert. Es empfiehlt sich, die DBA_SCHEDULER Views für Abfragen und Auswertungen zu nutzen. Die Views gibt es auch mit USER_SCHEDULER.

Übersicht

Name Beschreibung
DBA_SCHEDULER_CHAINS Job Chains in der Datenbank
DBA_SCHEDULER_CHAIN_RULES Regeln der Job Chains in der Datenbank
DBA_SCHEDULER_CHAIN_STEPS Definierte Job Chain Steps in der Datenbank
DBA_SCHEDULER_CREDENTIALS Definierte Credentials in der Datenbank
DBA_SCHEDULER_DB_DESTS Zielobjekte, die auf Remote DBs zeigen
DBA_SCHEDULER_DESTS Zielobjekte in der lokalen Datenbank
DBA_SCHEDULER_EXTERNAL_DESTS Zielobjekte, die auf einen Remote Agent zeigen
DBA_SCHEDULER_FILE_WATCHERS File Watcher Requests in der Datenbank
DBA_SCHEDULER_GLOBAL_ATTRIBUTE DBMS_SCHEDULER Einstellungen
DBA_SCHEDULER_GROUPS Objektgruppen in der Datenbank
DBA_SCHEDULER_GROUP_MEMBERS Mitglieder der Objektgruppen in der Datenbank
DBA_SCHEDULER_INCOMPATS Job Incompatibilities in der Datenbank
DBA_SCHEDULER_INCOMPAT_MEMBER Mitglieder der Job Incompatibilities
DBA_SCHEDULER_JOBS Zentrale Job Tabellen View der Datenbank
DBA_SCHEDULER_JOB_ARGS Jobargumente aller Jobs in der Datenbank
DBA_SCHEDULER_JOB_CLASSES Job Classen in der Datenbank
DBA_SCHEDULER_JOB_DESTS Job Status aller Jobs und deren Ziele
DBA_SCHEDULER_JOB_LOG Logging Information aller Scheduler Jobs
DBA_SCHEDULER_JOB_ROLES Scheduler Jobs anhand der Datenbankrolle
DBA_SCHEDULER_JOB_RUN_DETAILS Details der Jobausführung
DBA_SCHEDULER_NOTIFICATIONS E-Mail-Benachrichtigungen der Jobs
DBA_SCHEDULER_PROGRAMS Scheduler Programs in der Datenbank
DBA_SCHEDULER_PROGRAM_ARGS Attribute der Programs in der Datenbank
DBA_SCHEDULER_REMOTE_DATABASES Registrierte Quell- und Zieldatenbanken für Remote DB Jobs
DBA_SCHEDULER_REMOTE_JOBSTATE Job Status von Remote DB Jobs
DBA_SCHEDULER_RESOURCES Resource Queues in der Datenbank
DBA_SCHEDULER_RSC_CONSTRAINTS Verknüpfung zwischen Resource Queues und deren Mitglieder
DBA_SCHEDULER_RUNNING_CHAINS Laufende Job Chains
DBA_SCHEDULER_RUNNING_JOBS Laufende Scheduler Jobs
DBA_SCHEDULER_SCHEDULES Schedules in der Datenbank
DBA_SCHEDULER_WINDOWS Windows in der Datenbank
DBA_SCHEDULER_WINDOW_DETAILS Details über die Windows in der Datenbank
DBA_SCHEDULER_WINDOW_GROUPS Windowsgruppen in der Datenbank
DBA_SCHEDULER_WINDOW_LOG Logging Information aller Windows
DBA_SCHEDULER_WINGROUP_MEMBERS Windows der Windowsgruppen
Abb.1: DBMS_Scheduler (API). © Alexander Hofstetter
Abb.1: DBMS_Scheduler (API). © Alexander Hofstetter

Die Kontrolle über die Jobs übernimmt der Job-Koordinator. Auf OS-Ebene sind das die cjqNNN-Prozesse. Dieser Prozess liest regelmäßig die Job-Tabelle (sys.scheduler$_job). Zusätzlich erstellt oder beendet der Koordinator die Job Slave-Prozesse (JNNN). Der Koordinator kann sich selbst in den Schlafmodus versetzen und diesen wieder verlassen. Die Deaktivierung des Schlafmoduses geschieht entweder, sobald ein Job ausgeführt werden muss oder bei der Neuerstellung eines Jobs mit der CREATE_JOB-Prozedur. In einem Real Application Cluster gibt es einen Job-Koordinator pro Instanz. Der Koordinator kann durch das Setzen des Parameters job_queue_processes auf 0 deaktiviert werden. DBMS_SCHEDULER und DBMS_JOB nutzen denselben Job Koordinator. Diese Konstellation stellt kein Problem dar. Oracle empfiehlt aber, auf DBMS_SCHEDULER umzustellen.

Der Job Slave-Prozess sammelt alle nötigen Informationen über den auszuführenden Job, wie zum Beispiel, welcher Code verwendet wird. Anschließend startet er eine Datenbank-Session. Sichtbar ist die Session in der View v$session.

SQL> select username, program from v$session where program like '%J00%';

USERNAME                  PROGRAM
------------------------- ---------------------------------
TVDCAPMAN                 oracle@trivadis.test.com (J006)
SYS                       oracle@trivadis.test.com (J000)
                          oracle@trivadis.test.com (J001)

In der Spalte PROGRAM ist zu erkennen, dass diese Session vom Scheduler gestartet wurde. Dort sieht man den Hostnamen und in Klammern den Slaveprozess mit einer dreistelligen Nummer, wie zum Beispiel J001. Der Prozess öffnet eine Transaktion und startet den Job. Nach dem der Job durchgelaufen ist, wird die Transaktion mit einem Commit beendet und geschlossen. Innerhalb dieser Transaktion können durch den auszuführenden Code zusätzliche Transaktionen gestartet und beendet werden. Bei Abschluss der Job-Transaktion wird auch die zugehörige Datenbanksession beendet.

Nachdem ein Job durchgelaufen ist, wird der Run Count in der Job-Tabelle (sys.scheduler$_job) erhöht. Es werden auch alle Logging-Informationen gespeichert. Zusätzlich wird die nächste Ausführung festgelegt, sofern dies in der Job-Definition vorgesehen ist. Danach wird geprüft, ob weitere Jobs zur Ausführung vorliegen. Andernfalls versetzt sich der Prozess in den Schlafmodus.

Bei der Erstellung eines Jobs muss man die Attribute job_type und eine job_action mitgeben. Ein Beispiel hierfür ist job_type => 'PLSQL_BLOCK' und job_action => 'begin some code; end; '.

BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
   job_name           =>  'TEST_JOB',
   job_type           =>  'STORED_PROCEDURE',
   job_action         =>  'test.dummy_proc',
   start_date         =>  '28-APR-17 07.00.00 PM Europe/Berlin',
   repeat_interval    =>  'FREQ=DAILY;INTERVAL=2',
   end_date           =>  '28-NOV-17 07.00.00 PM Europe/Berlin',
   auto_drop          =>   FALSE,
   job_class          =>  'DEFAULT_JOB_CLASS',
   comments           =>  'Aufruf einer Test Prozedur');
END;
/

Zusätzlich ist es möglich, den auszuführenden Code in ein sogenanntes Program auszulagern. Ein Program ermöglicht die Wiederverwendbarkeit von Code. Hierfür gibt es die äquivalenten Parameter program_type und program_action. Einige Job Typen verlangen explizit ein Program.

Job-Kategorien

Es gibt verschiedene Job-Arten, die ausgeführt werden können. Als Ersatz für DBMS_JOBs kann der Database-Job verwendet werden. Dieser besteht entweder aus einer Stored Procedure oder einem PL/SQL-Block.

Unter einem External Job kann man ein Executable auf Betriebssystemebene ausführen. Seit der Version 12.1 gibt es auch den Script-Job, welcher aus einem SQL-Skript (SQL*Plus), einem External-Skript (Shell) oder einem Backup-Job (RMAN) bestehen kann.

Mit einem Chain-Job kann man eine Verkettung von mehreren Schritten sowie deren Abhängigkeiten definieren. Mit einem Detached-Job wird der Scheduler-Prozess außerhalb der Datenbank verwaltet. Dies bringt den Vorteil, dass dadurch auch die Datenbank gestoppt und neu gestartet werden kann. Hier muss explizit der Job mit END_DETACHED_JOB_RUN beendet werden. Multiple-destination-Jobs laufen auf mehreren Zieldatenbanken oder Hosts.

Für die neuen In-Memory-Jobs spielt der Lightweight-Job (eingeführt mit Oracle 11.1) eine große Rolle. Lightweight-Jobs müssen auf einem Program basieren, welches eine Prozedur oder einen PL/SQL-Block beinhaltet. Zusätzlich sind Lightweight-Jobs keine Schema-Objekte und benötigen deshalb im Vergleich zu herkömmlichen Jobs weniger Metadaten. Dadurch können diese Jobs schneller erstellt und gelöscht werden. Eine Steigerung dazu ist der In-Memory-Job. Dieser wird später unter den neuen Features behandelt.

Resource Management

Der Scheduler kann den Oracle Resource Manager nutzen. Der Resource Manager bietet mehr Kontrolle über die Hardware-Ressourcen und besteht aus drei Teilen:

  • Resource Consumer Group
  • Resource Plan
  • Resource Plan Directive

Resource Consumer Groups sind eine Sammlung von User-Sessions. Wenn der Resource Manager aktiv ist, wird eine neue Datenbanksession automatisch der definierten Gruppe zugewiesen. Es gibt immer mindestens zwei vordefinierte Gruppen: SYS_GROUP und OTHER_GROUPS.

In der ersten Gruppe sind die User SYS und SYSTEM enthalten. Alle User, die keiner Gruppe zugeordnet sind, werden automatisch mit OTHER_GROUPS verknüpft. Für Applikationen können und sollten eigene Gruppen erstellt werden. Der Resource Plan enthält eine Sammlung von Plan Directives. Mit Plan Directives werden Consumer Groups und der Plan verknüpft. Außerdem wird beschrieben, wie die Ressourcen zwischen den Consumer Groups aufgeteilt werden. Dadurch kann man unter anderem den CPU-Verbrauch einschränken, die Parallelität und Priorität festlegen oder auch die Anzahl der aktiven Sessions limitieren.

Zum Beispiel könnte man festlegen, dass die SYS_GROUP 50 Prozent der CPU bekommt. Eine Applikationsgruppe bekommt von den restlichen 50 Prozent noch 75 Prozent. Die restlichen Ressourcen werden der Gruppe OTHER_GROUPS zugewiesen. Wenn es nun zu einem CPU-Engpass kommt, wird der CPU-Konsum entsprechend eingeschränkt.

Die Steuerung des Resource Managers über den Scheduler erfolgt entweder mithilfe von Job Classes oder Windows. Ein Window ist ein Zeitfenster, in dem ein spezieller Resource Plan verwendet wird. Es kann immer nur ein Window, respektive ein Resource Plan gleichzeitig aktiv sein. Eine Überlappung zweier Windows ist möglich, wird aber nicht empfohlen. Für die Erstellung der Windows im Scheduler wird das MANAGE SCHEDULER-Privileg benötigt. Dadurch können nur Administratoren derartige Windows erstellen.

Job Classes fassen mehrere vordefinierte Parameter zusammen, die man teils auch während der Joberstellung definieren kann. Zum einen kann man über die Consumer Group festlegen, welche Ressourcen durch den Resource Manager gewährleistet werden. Zum anderen kann ein Service definiert werden, über welchen der Job in einem Real Application Cluster läuft. Eine weitere Einstellungsmöglichkeit ist das Logging Level. 

Parameter Beschreibung
LOGGING_OFF Kein Logging
LOGGING_FAILED_RUNS Nur fehlschlagende Jobs werden protokolliert.
LOGGING_RUNS Jeder Job Lauf schreibt einen Logging-Eintrag
LOGGING_FULL Jeder Job Lauf schreibt einen Logging-Eintrag. Zusätzlich wird ein Eintrag für jede Job-Änderung geschrieben. Dazu gehören:
  • Erstellen/ Löschen
  • Aktivieren/ Deaktivieren
  • Update (SET_ATTRIBUTE)
  • Stop

Job Classes werden im SYS-Schema erstellt und erfordern dadurch das MANAGE SCHEDULER-Privileg. Dieses Datenbankrecht sollte nur den Administratoren zur Verfügung stehen. Der DBA kann der Applikation das Execute-Privileg auf die Jobklassen erteilen. Somit können die Applikationen bereits erstellte Klassen nutzen.

Job-Steuerung

Es gibt zwei verschiedene Möglichkeiten. einen Job auszuführen. Entweder starten die Jobs bei definierten Events oder zeitgesteuert. Bei dem eventbasierten Job müssen bei Erstellung die Parameter event_condition und queue_spec definiert werden.

Bei der zeitbasierten Steuerung muss man ein Startdatum (start_date) angeben. Man hat zusätzlich die Möglichkeit, zu definieren, ob der Job wiederholt werden soll und in welchem Intervall (repeat_interval). Optional kann ein Enddatum (end_date) spezifiziert werden. Das REPEAT_INTERVAL wird entweder mit der Calendar Expression oder einer PL/SQL-Expression beschrieben. Beispiel für eine Jobdefinition mit einem Wiederholungsintervall von fünf Minuten:

Calendar: FREQ=MINUTELY; INTERVAL=5;
PL/SQL: SYSTIMESTAMP + INTERVAL '5' MINUTE;

Es können aber auch wesentlich komplexere Wiederholungen festlegt werden, wie zum Beispiel:

  • jeden zweiten Donnerstag:
    FREQ=Weekly; INTERVAL=2; BYDAY=THU
  • der letzte Arbeitstag (Montag bis Freitag) im Monat:
    FREQ=MONTHLY; BYDAY=MON,TUE,WED,THU,FRI; BYSETPOS=-1;
  • jede zweite Stunde alle fünf Minuten montags bis freitags:
    FREQ=MINUTELY;INTERVAL=5;BYDAY=MON,TUE,WED,THU,FRI;
    BYHOUR=0,2,4,6,8,10,12,14,16,18,20,22

In der Dokumentation ist diese Syntax sehr ausführlich mit diversen Beispielen beschrieben [1].

Neue Funktionen in Oracle 12.2

Es gibt folgende neue Funktionen in Oracle Database 12c Release 2:

  • Job Incompatibilities
  • Resource Queues
  • In-Memory-Jobs

Die ersten beiden sind Möglichkeiten der Jobsteuerung. Bei In-Memory-Jobs handelt es sich um einen neuen Job-Typ.

Job Incompatibilities

Mit Job Incompatibilities gibt es nun die Möglichkeit, zwei oder mehrere Jobs inkompatibel miteinander zu definieren. Das heißt, nur ein Job in der definierten Gruppe kann zur gleichen Zeit laufen. Die Inkompatibilität ist entweder auf Job- oder Program-Ebene. Dabei unterscheidet sich die Funktionsweise. Falls beispielsweise mehrere ressource-intensive Jobs ausgeführt werden müssen, kann diese neue Funktion verhindern, dass beide gleichzeitig laufen. Dadurch läuft nur einer der beiden Jobs und der Start des anderen wird verzögert.

Aber wie funktioniert das Ganze? Zunächst auf Job-Level-Ebene: Wie oben beschrieben kann nur ein Job innerhalb einer Job Incompatibility-Gruppe gleichzeitig laufen. Jobs die nicht in dieser Gruppe definiert sind laufen trotzdem wie geplant. Wenn bereits ein Job innerhalb einer solchen Gruppe läuft, muss der andere Job warten bis der erste Job abgeschlossen ist.

Abb.2: Beispiel 2. © Alexander Hofstetter
Abb.2: Beispiel 2. © Alexander Hofstetter
Abb.3: Beispiel 3. © Alexander Hofstetter
Abb.3: Beispiel 3. © Alexander Hofstetter

Beispiel 1 (ohne Abb.):
Es ist eine Job Incompatibility Group mit Job A, B und C definiert. Wenn Job A läuft, muss Job B und C mit dem Start warten, bis Job A fertig ist.

Beispiel 2 (Abb.2):
In diesem Fall startet Job A zuerst. Als nächstes ist Job D an der Reihe. Dieser Job startet ganz normal, da er nicht Teil der Incompatibility-Gruppe ist. Job B kann allerdings nicht wie geplant starten, sondern muss warten, bis Job A beendet ist.

Job Incompatibilities auf Program Level sind hingegen anders implementiert. Hier bestimmt man zwei oder mehrere Programs, welche nicht parallel laufen dürfen. Das heißt, während ein Job mit einem in der Gruppe definierten Program läuft, dürfen andere Jobs nur bei Nutzung des gleichen Programs gestartet werden. Jobs die ein anderes Program aus der Incompatibility-Gruppe aufrufen, müssen warten, bis alle Jobs, die das Program des zuerst gestarteten Jobs nutzen, durchgelaufen sind.

Beispiel 3 (Abb.3):
Es ist eine inkompatible Gruppe mit Program A, B und C definiert. Zusätzlich sind Jobs 1 bis 8 geplant. Job 1 und 2 nutzen Program A. Job 3 und 4 nutzen Program B. Und die restlichen Jobs (5 bis 8) nutzen Program C. Wenn jetzt der Job 5 gestartet wird, bedeutet das, dass nur noch Job 5, 6, 7 und 8 gestartet werden können. Die Jobs 1 bis 4 können erst gestartet werden, wenn alle Jobs, die das Program C ausführen, beendet sind.

Für Job Incompatibilities ist kein besonderes Privileg notwendig. Das CREATE JOB-Recht ist ausreichend. Zur Verwaltung gibt es vier neue Prozeduren im Package DBMS_SCHEDULER:

  • Um eine Gruppe zu erstellen gibt es die Prozedur CREATE_INCOMPATIBILITY.

Syntax:

DBMS_SCHEDULER.CREATE_INCOMPATIBILITY (
   incompatibility_name    IN VARCHAR2,
   object_name             IN VARCHAR2,
   constraint_level        IN VARCHAR2 DEFAULT 'JOB_LEVEL',
   enabled                 IN BOOLEAN DEFAULT TRUE,
   comments                IN VARCHAR2 DEFAULT NULL);

Beispiel:

BEGIN
dbms_scheduler.create_incompatibility(
  incompatibility_name => 'incompatible1',
  object_name => 'job1,job2,job3',
  enabled => true);
END;
/
  • ADD_TO_INCOMPATIBILITY fügt einen weiteren Job oder ein weiteres Program zu einer bestehenden Gruppe hinzu.

Beispiel:

BEGIN
dbms_scheduler.add_to_incompatibility(
  incompatibility_name => 'incompatible1',
  object_name => 'job4');
END;
  • Mit REMOVE_FROM_INCOMPATIBILITY kann man diese wieder entfernen.

Beispiel:

BEGIN
dbms_scheduler.remove_from_incompatibility(
  incompatibility_name => 'incompatible1',
  object_name => 'job2');
END;
  • Und um eine Gruppe zu entfernen, kann man DROP_INCOMPATIBILITY durchführen.

Beispiel:

BEGIN
dbms_scheduler.drop_incompatibility(
  incompatibility_name => 'incompatible1');
END;
/

Zur Kontrolle gibt es zwei DBA / USER / ALL-Views:

  • In der View USER_SCHEDULER_INCOMPATS steht der Name der Gruppe (INCOMPATIBILITY_NAME) und der Level (Job- oder Programebene):
Name                  Type
--------------------  -------------
INCOMPATIBILITY_NAME  VARCHAR2(128)
CONSTRAINT_LEVEL      VARCHAR2(13)
ENABLED               VARCHAR2(5)
JOBS_RUNNING_COUNT    NUMBER
COMMENTS              VARCHAR2(256)
  • In der View USER_SCHEDUER_INCOMPAT_MEMBER wird die Verknüpfung zwischen der Gruppe und den Objekten dargestellt:
Name                   Type
---------------------  -------------
INCOMPATIBILITY_OWNER  VARCHAR2(128)
INCOMPATIBILITY_NAME   VARCHAR2(128)
OBJECT_OWNER           VARCHAR2(128)
OBJECT_NAME            VARCHAR2(128)

Resource Queues

Bei den Resource Queues wird festgelegt, wie viele Ressourcen allen mit den Resource Queues verknüpften Jobs zur Verfügung stehen. Allerdings handelt es sich hierbei nicht um Hardware-Ressourcen. Man muss diese Ressourcen als Objekt betrachten. Diese Ressource wird benannt und ihre Wertigkeit beim Erstellen bestimmt. Man kann also die Ressource resource_name => 'app_resource1' mit units => 2 (Einheiten) erstellen. Bei verknüpften Jobs wird festgelegt, wie viele dieser Ressourcen (app_resource1) eine Jobausführung benötigt.

Bei der Ausführung stellt der Scheduler sicher, dass die vorhandenen Ressourcen nicht überschritten werden. Solange die benötigten Ressourcen (app_resource1) zur Verfügung stehen, kann ein verknüpfter Job nicht starten.

Die Steuerung dieser Resource Queues besteht aus drei Prozeduren:

  • Mit CREATE_RESOURCE erstellt man eine Ressource. Mit Units definiert man die Anzahl der Einheiten, die die Resource Queue zur Verfügung hat.

Beispiel:

BEGIN
   DBMS_SCHEDULER.CREATE_RESOURCE(
      resource_name => 'app_resource1',
      units => 2,
      status => 'ENFORCE_CONSTRAINTS',
      comments => 'Resource1');
END;
/

In diesem Beispiel hat man die Resource Queue APP_RESOURCE1 mit zwei Einheiten erstellt.

  • Mit der Prozedur SET_RESOURCE_CONSTRAINT kann man Jobs und Program einer Resource Queue zuteilen und den jeweiligen Ressourcenverbrauch pro Durchlauf definieren.

Beispiel:

BEGIN
    DBME_SCHEDULER.SET_RESOURCE_CONSTRAINT(
         OBJECT_NAME   => 'job1',
         RESOURCE_NAME => 'app_resource1',
         UNITS         =>1);
END;
/

Im Beispiel verbraucht der Job1 den Wert 1 bei einem Durchlauf von der Resource Queue app_resource1. Gäbe es zusätzlich einen Job2, der zwei Ressourcen-Einheiten benötigt, dann könnte man Job1 und Job2 nicht gleichzeitig ausführen. Man bräuchte drei Einheiten der app_resource1-Ressource, es stehen aber nur zwei zur Verfügung. Die Jobs werden daher nacheinander ausgeführt.

  • Um eine Resource Queue zu löschen, muss man nur den DROP_RESOURCE-Prozedur ausführen.

Beispiel:

BEGIN
   DBMS_SCHEDULER.DROP_RESOURCE(
      resource_name => 'app_resource1',
      force         => true
   )
END;
/

Eine nachträgliche Änderung der Anzahl der Ressourcen einer Resource Queue kann mit der SET_ATTRIBUTE-Prozedur durchgeführt werden.

Beispiel:

BEGIN
    DBME_SCHEDULER.SET_RESOURCE_CONSTRAINT(
         NAME      => 'app_resource1',
         ATTRIBUTE => 'units',
         VALUE     =>10);
END;
/

Zur Kontrolle gibt es zwei DBA / USER / ALL-Views:

  • In der View USER_SCHEDULER_RESOURCES stehen die Resource Queues, ihr aktueller Status und Informationen über die Einheiten:
Name                 Type
-------------------  --------------
RESOURCE_NAME        VARCHAR2(128)
STATUS               VARCHAR2(19)
RESOURCE_UNITS       NUMBER
UNITS_USED           NUMBER
JOBS_RUNNING_COUNT   NUMBER
COMMENTS             VARCHAR2(256)

In der View USER_SCHEDULER_RSC_CONSTRAINTS ist die Verknüpfung zwischen der Resource Queue und den Objekten erkennbar:

Name            Type
--------------  -------------
OBJECT_OWNER    VARCHAR2(128)
OBJECT_NAME     VARCHAR2(128)
RESOURCE_OWNER  VARCHAR2(128)
RESOURCE_NAME   VARCHAR2(128)
UNITS_USED      NUMBER

In-Memory-Jobs

Sie sind so konzipiert, dass man sie in einer kurzen Zeit erstellt und ausführt. Allerdings wird im Vergleich zu herkömmlichen Jobs etwas mehr Arbeitsspeicher benötigt. Der Zweck dieses Job-Typs ist es, den Overhead, den es bei der Erstellung und Ausführung von normalen Jobs gibt, zu vermeiden. Mit Lightweight-Jobs kann man diesen Overhead bereits in früheren Oracle-Versionen schon reduzieren. Mit den neuen In-Memory-Jobs kann der Overhead weiter verringert werden. Es gibt zwei Arten von In-Memory Jobs:

  • In-Memory Runtime: Diese Jobs basieren auf dem Lightweight-Job. Das bedeutet, der Job ist persistent und wiederausführbar. Standardmäßig läuft dieser Job mit der DEFAULT_IN_MEMORY_JOB_CLASS. In dieser Job Class ist das Logging-Level auf NONE gesetzt. Dadurch sind keinerlei Informationen in den Scheduler Views zu finden. Das bedeutet aber auch, dass man zusätzlich zu dem CREATE JOB-Privileg das EXECUTE-Privileg auf diese Klasse benötigt. Erstellt wird ein In-Memory Runtime-Job wie ein normaler Datenbank-Job mit dem job_style-Parameter mit dem Wert IN_MEMORY_RUNTIME.

Beispiel:

BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name => 'my_repeat_job',
    program_name => 'repeat_prog',
    start_date => systimestamp,
    repeat_interval => 'freq=secondly;interval=10',
    job_style => 'IN_MEMORY_RUNTIME',
    enabled => true);
END;
/
  • In-Memory Full: Hier handelt es sich um einen nicht persistenten Job, der rein im Memory ausgeführt wird. Der Job muss mit einem Programm verknüpft werden, welches eine Prozedur oder einen PL/SQL-Block aufruft. Der IN-MEMORY Full-Job ist nicht wiederholbar. Der größte Performance-Vorteil entsteht durch die Vermeidung von Redo bei der Erstellung und Ausführung des Jobs. In einer Real Application Cluster-Umgebung ist der Job nur auf dem Knoten sichtbar, auf dem er erstellt wurde.
    In einer Data Guard Umgebung wird dieser Job-Typ nicht auf eine Physical oder Logical Standby übertragen.
    Hier wird bei der Erstellung der job_style-Parameter auf den Wert IN_MEMORY_FULL gesetzt.

Beispiel:

BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name => 'my_immediate_job',
    program_name => 'fast_op',
    job_style => 'IN_MEMORY_FULL',
    enabled => true);
END;
/

Es gibt zwei v$-Views in denen ein paar Informationen zu laufenden In-Memory-Jobs stehen. Diese sind allerdings nicht dokumentiert.

  • V$SCHEDULER_INMEM_MDINFO:
Name               Type
-----------------  ---------------------------
OBJID              NUMBER
PRGOID             NUMBER
LAST_ENABLED_TIME  TIMESTAMP(3) WITH TIME ZONE
CLSOID             NUMBER
INSTANCE_ID        NUMBER
FLAGS              NUMBER
CREATOR            VARCHAR2(128)
CLIENT_ID          VARCHAR2(65)
GUID               VARCHAR2(33)
CON_ID             NUMBER
  • V$SCHEDULER_INMEM_RTINFO:
Name              Type
----------------  ---------------------------
USERID            NUMBER
OBJID             NUMBER
ID_TYPE           NUMBER
NAME              VARCHAR2(128)
NEXT_RUN_DATE     TIMESTAMP(3) WITH TIME ZONE
LAST_START_DATE   TIMESTAMP(3) WITH TIME ZONE
LAST_END_DATE     TIMESTAMP(3) WITH TIME ZONE
RUN_COUNT         NUMBER
FAILURE_COUNT     NUMBER
RUNNING_INSTANCE  NUMBER
RUNNING_SLAVE     NUMBER
JOB_STATUS        NUMBER
CON_ID            NUMBER

Fazit

Mit den neuen Features gibt es interessante neue Möglichkeiten, Jobs zu regulieren. Job Incompatibilities und Resource Queues sind neue Methoden die verhindern, dass mehrere lastintensive Job zur selben Zeit laufen. Vor allem die Job Incompatibilities bieten eine enorme Erleichterung. Vor Oracle 12.2 musste man eine derartige Anforderung entweder mit komplexen Jobketten bewerkstelligen, in dem man erst ein Job und dann nach dem Durchlauf als weiteren Teil der Kette den nächsten Job startet. Oder man konnte die Jobsteuerung selbst übernehmen, indem man in seiner Applikationslogik den jeweiligen Job manuell gestartet hat. Jetzt übernimmt der Oracle Scheduler diese Aufgabe mit einer einfachen Konfiguration. Leider funktionieren Job Incompabilities und Resource Queues nur bei automatischer Durchführung und nicht bei manueller Ausführung durch die RUN_JOB-Prozedur. Dies ist bei der Konfiguration zu beachten.

Mit In-Memory-Jobs gibt es eine Methode, noch schneller Jobs auf den Weg zu bringen, als es bisher mit Lightweight-Jobs möglich ist. Dies ist besonders von Vorteil, wenn man eine große Anzahl von Jobs parallel starten möchte.

nach Oben
Autor

Alexander Hofstetter

Alexander Hofstetter ist als Senior Consultant bei der Trivadis GmbH in München im Bereich Infrastructure Managed Services tätig. Einer seiner Schwerpunkte liegt in der Oracle-Datenbank-Administration.
>> Weiterlesen
botMessage_toctoc_comments_929