Job-Steuerung in Oracle Datenbanken

Mit Oracle 10g wurde eine neue Architektur zur Job-Steuerung innerhalb der Datenbank eingeführt. Bisher bot das Paket dbms_job mit den passenden Views (dba_jobs, dba_jobs_running) die notwendige Funktionalität an, die jedoch lange nicht so komfortabel und flexibel war, wie das neue Job-Package: Das Paket dbms_scheduler bietet eine weit größere Funktionalität.

 

Programme

Der neue Oracle-Datenbankscheduler bietet optional d ie Möglichkeit Programme zu erstellen. Sie enthalten die Metadaten der Task, aber keine Scheduler-Informationen. Die eigentlich Zeitsteuerung kann also von der Programmdefinition abgekoppelt werden. Ein Programm kann beispielsweise ein PL/SQL-Block, eine Stored Procedure oder auch ein Betriebssystemprogramm wie beispielsweise ein Shell-Script sein. Einige Beispiele zur Programmerstellung:

ORACLE Scheduler: Programme definieren
 
-- Aufruf eines anonymen PL/SQL-Blocks
BEGIN
  DBMS_SCHEDULER.create_program (
    program_name   => 'mein_plsql_block_prog',
    program_type   => 'PLSQL_BLOCK',
    program_action => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
    enabled        => TRUE,
    comments       => 'Statistiksammlung des Schemas Scott.');
END;
/
 
 
 
-- Aufruf eines Shell-Scriptes
BEGIN
  DBMS_SCHEDULER.create_program (
    program_name        => 'mein_executable_prog',
    program_type        => 'EXECUTABLE',
    program_action      => '/home/oracle/scripts/mein_script.sh',
    number_of_arguments => 0,
    enabled             => TRUE,
    comments            => 'Programm mit Aufruf eines OS-Shell-Scripts');
END;
/
 
 
 
-- Aufruf einer Stored Procedure mit Argumenten
BEGIN
  DBMS_SCHEDULER.create_program (
    program_name        => 'meine_stored_procedure_prog',
    program_type        => 'STORED_PROCEDURE',
    program_action      => 'DBMS_STATS.gather_schema_stats',
    number_of_arguments => 1,
    enabled             => FALSE,
    comments            => 'Aufruf einer Stored Procedure');
END;
/
BEGIN
  DBMS_SCHEDULER.define_program_argument (
    program_name      => 'meine_stored_procedure_prog',
    argument_name     => 'ownname',
    argument_position => 1,
    argument_type     => 'VARCHAR2',
    default_value     => 'SCOTT');
END;
/
BEGIN
  DBMS_SCHEDULER.enable (name => 'meine_stored_procedure_prog');
END;
/
 

 

Die Informationen lassen sich über die View dba_scheduler_programs abfragen:

ORACLE Scheduler: Abfrage von Programmen
 
 
SET pages 3000
COL owner FORMAT A30
COL program_name FORMAT A40
SELECT owner, program_name, enabled FROM dba_scheduler_programs;
 
OWNER  PROGRAM_NAME                  ENABLED
------ ----------------------------- ---------
SYS    PURGE_LOG_PROG                TRUE
SYS    GATHER_STATS_PROG             TRUE
SYS    AUTO_SPACE_ADVISOR_PROG       TRUE
SYS    MEIN_PLSQL_BLOCK_PROG         TRUE
SYS    MEIN_EXECUTABLE_PROG          TRUE
SYS    MEINE_STORED_PROCEDURE_PROG   TRUE

 

Um ein Programm zu löschen, gehen Sie wie folgt vor:

ORACLE Scheduler: Programme löschen
BEGIN
  DBMS_SCHEDULER.drop_program (program_name => 'MEIN_PLSQL_BLOCK_PROG');
END;
/
 
BEGIN
  DBMS_SCHEDULER.drop_program (program_name => 'MEIN_EXECUTABLE_PROG');
END;
/
 
BEGIN
  DBMS_SCHEDULER.drop_program (program_name => 'MEINE_STORED_PROCEDURE_PROG');
END;
/

 

 

Zeitplanung / Job-Steuerung / Scheduler

Schedules können Start- Endzeiten sowie Job-Intervalle definieren. Hier ein kleines Beispiel:

ORACLE Scheduler: Zeitplan erstellen
 
-- Schedule erstellen
BEGIN
  DBMS_SCHEDULER.create_schedule (
    schedule_name   => 'mein_schedule_stuendlich',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    comments        => 'Job wird stuendlich ohne Ende-Datum gestartet');
END;
/
 
 
-- Schedule-Informationen abfragen
SELECT owner, schedule_name FROM dba_scheduler_schedules;
 
OWNER                          SCHEDULE_NAME
------------------------------ ------------------------------
SYS                            DAILY_PURGE_SCHEDULE
SYS                            MEIN_SCHEDULE_STUENDLICH

 

Ein Zeitplan kann mit der Prozedur drop_schedule wieder entfernt werden:

ORACLE Scheduler: Zeitplan löschen
BEGIN
  DBMS_SCHEDULER.drop_schedule (schedule_name => 'MEIN_SCHEDULE_STUENDLICH');
END;
/
 
SELECT owner, schedule_name FROM dba_scheduler_schedules;
 
OWNER                          SCHEDULE_NAME
------------------------------ ------------------------------
SYS                            DAILY_PURGE_SCHEDULE
 

 

Datenbank-Jobs erstellen

Jobs können aus vordefinierten Programmen und Schedules zusammengestellt werden oder aber vollständig self contained erzeugt werden. Dazu gibt es Überladungen der Prozedur create_job:

ORACLE Scheduler: Datenbank-Jobs erstellen
 
 
-- Job erstellen
BEGIN
  -- Komplett self contained
  DBMS_SCHEDULER.create_job (
    job_name        => 'mein_sched_job_definition_1',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'ein self contained Job');
END;
/
 
-- Job unter Nutzung bereits definierter Programme und Schedules
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'mein_sched_job_definition_2',
    program_name    => 'mein_executable_prog',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job mit existierendem Programm und Inline-Schedule');
END;
/ 
 
-- Job mit existierendem Programm und Inline-Schedule
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'mein_sched_job_definition_3',
    program_name    => 'mein_plsql_block_prog',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job mit existierendem Programm und Inline-Schedule');
END;
/
 
-- Job mit existierendem Schedule und Inline-Programm
BEGIN
  DBMS_SCHEDULER.create_job (
     job_name      => 'mein_sched_job_definition_4',
     schedule_name => 'mein_schedule_stuendlich',
     job_type      => 'PLSQL_BLOCK',
     job_action    => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
     enabled       => TRUE,
     comments      => 'Job mit existierendem Schedule und Inline-Programm');
END;
/
 
 
-- Anzeige aller Job Details
COL job_name FORMAT a40
SELECT owner, job_name, enabled 
FROM   dba_scheduler_jobs
ORDER  BY 1, 2;
 
OWNER           JOB_NAME                       ENABLED
--------------- ------------------------------ --------
EXFSYS          RLM$EVTCLEANUP                 TRUE
EXFSYS          RLM$SCHDNEGACTION              TRUE
ORACLE_OCM      MGMT_CONFIG_JOB                TRUE
ORACLE_OCM      MGMT_STATS_CONFIG_JOB          TRUE
SYS             AUTO_SPACE_ADVISOR_JOB         TRUE
SYS             FGR$AUTOPURGE_JOB              FALSE
SYS             GATHER_STATS_JOB               FALSE
SYS             MEIN_SCHED_JOB_DEFINITION_1    TRUE
SYS             MEIN_SCHED_JOB_DEFINITION_2    TRUE
SYS             MEIN_SCHED_JOB_DEFINITION_3    TRUE
SYS             MEIN_SCHED_JOB_DEFINITION_4    TRUE
SYS             PURGE_LOG                      TRUE

 

Jobs laufen normalerweise unter der Kontrolle des Job Koordinators. Sie können jedoch auch manuell gestartet werden:

ORACLE Scheduler:
-- Starten eines Jobs
BEGIN
  DBMS_SCHEDULER.run_job (job_name            => 'MEIN_JOB_DEFINITION_1',
                          use_current_session => FALSE);
END;
/
 
-- Beenden eines Jobs
BEGIN
  DBMS_SCHEDULER.stop_job (job_name => 'MEIN_JOB_DEFINITION_1');
END;
/

 

Mit der Prozedur DROP_JOB kann ein Job wieder entfernt werden.

ORALE Scheduler: Job löschen
 
BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'MEIN_JOB_DEFINITION_1');
END;
/
BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'MEIN_JOB_DEFINITION_2');
END;
/
 
BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'MEIN_JOB_DEFINITION_3');
END;
/
 
BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'MEIN_JOB_DEFINITION_4');
END;
/
 
 
SELECT owner, job_name, enabled FROM dba_scheduler_jobs;
 
OWNER                          JOB_NAME                       ENABL
------------------------------ ------------------------------ -----
SYS                            PURGE_LOG                      TRUE
SYS                            GATHER_STATS_JOB               TRUE

 

Ressourcensteuerung durch Job-Klassen

Job-Klassen (Job Classes) in Oracle Datenbanken erlauben die Gruppierung von Jobs mit ähnlichen Anforderungen. Sie vereinfachen hiermit die Definition und Verwaltung von Oracle Datenbank-Jobs. Wird der Parameter JOB_CLASS der Prozedur CREATE_JOB nicht belegt, so wird standardmäßig DEFAULT_JOB_CLASS verwendet. Eine Job-Klasse kann mit der Prozedur erstellt werden:

ORACLE Scheduler: Job-Klassen
 
-- Anzeige der Consumer Groups
SELECT consumer_group FROM dba_rsrc_consumer_groups;
 
CONSUMER_GROUP
------------------------------
OTHER_GROUPS
DEFAULT_CONSUMER_GROUP
SYS_GROUP
LOW_GROUP
AUTO_TASK_CONSUMER_GROUP
 
-- Erstellen der Job-Klasse in der Oracle-Datenbank
BEGIN
  DBMS_SCHEDULER.create_job_class (
    job_class_name          =>  'mein_job_class',
    resource_consumer_group =>  'low_group');
END;
/
 
 
-- Anzeige der Job Class Details in der Oracle-Datenbank
COL job_class_name FORMAT A30
COL resource_consumer_group FORMAT A40
 
SELECT job_class_name, resource_consumer_group 
FROM dba_scheduler_job_classes;
 
JOB_CLASS_NAME                 RESOURCE_CONSUMER_GROUP
------------------------------ ----------------------------------------
DEFAULT_JOB_CLASS
AUTO_TASKS_JOB_CLASS           AUTO_TASK_CONSUMER_GROUP
MEIN_JOB_CLASS                 LOW_GROUP

 

Oracle Datenbank-Jobs können nun solchen Job-Klassen zugewiesen werden. Dazu verwenden Sie die Prozedur SET_ATTRIBUTE:

ORACLE Scheduler: Job-Klassen definieren
 
-- Zuordnung zu einer Job-Klasse in der Oracle-Datenbank
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name      => 'MEIN_JOB_DEFINITION_1',
    program_name  => 'mein_plsql_block_prog',
    schedule_name => 'mein_schedule_stuendlich',
    job_class     => 'mein_job_class',
    enabled       => TRUE,
    comments      => 'Job mit existierendem Programm und Schedule und Zuordnung zu einer Job-Klasse');
END;
/
 
BEGIN
  DBMS_SCHEDULER.set_attribute (
    name      => 'MEIN_JOB_DEFINITION_1',
    attribute => 'job_class',
    value     => 'mein_job_class');
END;
/
 
 
-- Anzeige der Job-Details
COL owner      FORMAT A20
COL job_name   FORMAT A40
COL job_class  FORMAT A30
SELECT owner, job_name, job_class, enabled 
FROM dba_scheduler_jobs;
 
OWNER            JOB_NAME                      JOB_CLASS            ENABLED
---------------- ----------------------------- --------------------------------
SYS              PURGE_LOG                     DEFAULT_JOB_CLASS    TRUE
SYS              FGR$AUTOPURGE_JOB             DEFAULT_JOB_CLASS    FALSE
SYS              GATHER_STATS_JOB              AUTO_TASKS_JOB_CLASS FALSE
SYS              AUTO_SPACE_ADVISOR_JOB        AUTO_TASKS_JOB_CLASS TRUE
ORACLE_OCM       MGMT_CONFIG_JOB               DEFAULT_JOB_CLASS    TRUE
ORACLE_OCM       MGMT_STATS_CONFIG_JOB         DEFAULT_JOB_CLASS    TRUE
EXFSYS           RLM$EVTCLEANUP                DEFAULT_JOB_CLASS    TRUE
EXFSYS           RLM$SCHDNEGACTION             DEFAULT_JOB_CLASS    TRUE
SYS              MEIN_SCHED_JOB_DEFINITION_1   DEFAULT_JOB_CLASS    TRUE
SYS              MEIN_SCHED_JOB_DEFINITION_2   DEFAULT_JOB_CLASS    TRUE
SYS              MEIN_SCHED_JOB_DEFINITION_3   DEFAULT_JOB_CLASS    TRUE
SYS              MEIN_SCHED_JOB_DEFINITION_4   DEFAULT_JOB_CLASS    TRUE
SYS              MEIN_PROG_SCHED_CLASS_JOB_DEF MEIN_JOB_CLASS       TRUE
SYS              MEIN_JOB_DEFINITION_1         MEIN_JOB_CLASS       TRUE
 

 

Um eine Job-Klasse aus der Datenbank zu entfernen, verwenden Sie die Prozedur DROP_JOB_CLASS:

ORACLE Scheduler: Job-Klasse entfernen
BEGIN
  DBMS_SCHEDULER.drop_job_class (
    job_class_name => 'mein_job_class',
    force          => TRUE);
END;
/
 
 
-- Anzeige der Details zu Job-Klassen in der Datenbank
SELECT job_class_name, resource_consumer_group 
FROM dba_scheduler_job_classes;
 
JOB_CLASS_NAME                 RESOURCE_CONSUMER_GROUP
------------------------------ ---------------------------
DEFAULT_JOB_CLASS
AUTO_TASKS_JOB_CLASS           AUTO_TASK_CONSUMER_GROUP
 

 

Oracle Datenbank Job Windows

Ein Job Window erstellt eine Verbindung zwischen einem Zeitplan und dem Resoure Manager. Verschiedene Ressourcen-Pläne können zu unterschiedlichen Zeiten in der Datenbank aktiviert und genutzt werden. Da Job Classes auf Resource Consumer Groups verweisen, kann die Kontrolle über Ressourcennutzungen durch Job-Klassen und deren Jobs über ein spezifisches Zeitfenster koordiniert werden.

Ein Job Window in der Oracle-Datenbank kann mit der Prozedur CREATE_WINDOW vordefiniert werden:

ORACLE Scheduler: Job Windows
BEGIN
  -- Oracle Job Window mit vordefiniertem Schedule
  DBMS_SCHEDULER.create_window (
    window_name     => 'mein_window_1',
    resource_plan   => NULL,
    schedule_name   => 'mein_schedule_stuendlich',
    duration        => INTERVAL '30' MINUTE,
    window_priority => 'LOW',
    comments        => 'Oracle Job Window mit vordefiniertem Schedule.');
END;
/
 
BEGIN
  -- Oracle Job Window mit Inline Schedule.
  DBMS_SCHEDULER.create_window (
    window_name     => 'mein_window_2',
    resource_plan   => NULL,
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    duration        => INTERVAL '60' MINUTE,
    window_priority => 'LOW',
    comments        => 'Oracle Job Window mit Inline Schedule.');
END;
/
 
 
-- Anzeige der Windows in der Datenbank.
COL window_name FORMAT A30
COL resource_plan FORMAT a30
 
SELECT window_name, resource_plan, enabled, active
FROM   dba_scheduler_windows;
WINDOW_NAME         RESOURCE_PLAN  ENABLED ACTIVE
------------------- -------------- ----------------
WEEKNIGHT_WINDOW                   TRUE    FALSE
WEEKEND_WINDOW                     TRUE    FALSE
MEIN_WINDOW_1                      TRUE    FALSE
MEIN_WINDOW_2                      TRUE    FALSE
 

 

Oracle Job Windows können auch manuell geöffnet oder geschlossen werden. Verwenden Sie dazu die Prozeduren OPEN_WINDOW und CLOSE_WINDOW:

ORACLE Scheduler: Job Windows manuell öffnen und schließen
BEGIN
  -- Open window.
  DBMS_SCHEDULER.open_window (
   window_name => 'mein_window_2',
   duration    => INTERVAL '1' MINUTE,
   force       => TRUE);
END;
/
 
 
-- Anzeige der Oracle Job Windows
SELECT window_name, resource_plan, enabled, active
FROM   dba_scheduler_windows;
WINDOW_NAME                    RESOURCE_PLAN                  ENABLED         ACTIVE
------------------------------ ------------------------------ --------------- ---------------
WEEKNIGHT_WINDOW                                              TRUE            FALSE
WEEKEND_WINDOW                                                TRUE            FALSE
MEIN_WINDOW_1                                                 TRUE            FALSE
MEIN_WINDOW_2                                                 TRUE            TRUE
 
BEGIN
  -- Schließen des Oracle Job Windows
  DBMS_SCHEDULER.close_window (
   window_name => 'mein_window_2');
END;
/
 
PL/SQL procedure successfully completed.
 

 

Oracle Job Windows können mit der Prozedur DROP_WINDOW gelöscht werden:

ORACLE Scheduler: Löschen von Job-Windows
 
BEGIN
  DBMS_SCHEDULER.drop_window (
    window_name => 'mein_window_1',
    force       => TRUE);
 
  DBMS_SCHEDULER.drop_window (
    window_name => 'mein_window_2',
    force       => TRUE);
END;
/

 

Window Groups

Eine Oracle Window Group ist eine Zusammenstellung mehrerer Job Windows. Zur Erstellung verwenden Sie die Prozedur CREATE_WINDOW_GROUP:

ORACLE Scheduler: Window Group erstellen
 
BEGIN
  DBMS_SCHEDULER.create_window_group (
    group_name  => 'mein_window_group',
    window_list => 'mein_window_1, mein_window_2',
    comments    => 'A test window group');
END;
/
 
 
-- Anzeige der Details der  Oracle Window Group
SELECT window_group_name, enabled, number_of_windowS
FROM   dba_scheduler_window_groups;
 
WINDOW_GROUP_NAME              ENABL NUMBER_OF_WINDOWS
------------------------------ ----- -----------------
MAINTENANCE_WINDOW_GROUP       TRUE                  2
MEIN_WINDOW_GROUP              TRUE                  2
 
 

 

Windows können Sie hinzufügen oder löschen, indem Sie die Prozeduren ADD_WINDOW_GROUP_MEMBER und REMOVE_WINDOW_GROUP_MEMBER aufrufen:

ORACLE Scheduler: Window Group erstellen
BEGIN
  -- Neues Fenster erstellen
  DBMS_SCHEDULER.create_window (
    window_name     => 'mein_window_3',
    resource_plan   => NULL,
    schedule_name   => 'mein_schedule_stuendlich',
    duration        => INTERVAL '60' MINUTE,
    window_priority => 'LOW',
    comments        => 'Window mit vordefiniertem Schedule.');
END;
/
BEGIN
  -- Hinzufügen des neuen Job-Fensters
  DBMS_SCHEDULER.add_window_group_member (
    group_name  => 'mein_window_group',
    window_list => 'mein_window_3');
END;
/
 
 
-- Informationen anzeigen
COL window_group_name FORMAT a30
SELECT window_group_name, window_name
FROM   dba_scheduler_wingroup_members;
 
WINDOW_GROUP_NAME              WINDOW_NAME
WINDOW_GROUP_NAME              WINDOW_NAME
------------------------------ ------------------------------
MAINTENANCE_WINDOW_GROUP       WEEKNIGHT_WINDOW
MAINTENANCE_WINDOW_GROUP       WEEKEND_WINDOW
MEIN_WINDOW_GROUP              MEIN_WINDOW_1
MEIN_WINDOW_GROUP              MEIN_WINDOW_2
MEIN_WINDOW_GROUP              MEIN_WINDOW_3
 
-- Entfernen des Job-Fensters
BEGIN
  DBMS_SCHEDULER.remove_window_group_member (
    group_name  => 'mein_window_group',
    window_list => 'mein_window_3');
END;
/
 
-- Informationen anzeigen
SELECT window_group_name, window_name
FROM   dba_scheduler_wingroup_members;
 
WINDOW_GROUP_NAME              WINDOW_NAME
------------------------------ ------------------------------
MAINTENANCE_WINDOW_GROUP       WEEKNIGHT_WINDOW
MAINTENANCE_WINDOW_GROUP       WEEKEND_WINDOW
MEIN_WINDOW_GROUP              MEIN_WINDOW_1
MEIN_WINDOW_GROUP              MEIN_WINDOW_2
 
 

 

Eine Window Group kann mit der Prozedur  drop_window_group gelöscht werden:

SQL
 
BEGIN
  DBMS_SCHEDULER.drop_window_group (
    group_name => 'mein_window_group',
    force      => TRUE);
END;
/
 
 
--  Anzeige der Informationen
SELECT window_group_name, enabled, number_of_windowS
FROM   dba_scheduler_window_groups;
 
WINDOW_GROUP_NAME              ENABL NUMBER_OF_WINDOWS
------------------------------ ----- -----------------
MAINTENANCE_WINDOW_GROUP       TRUE                  2

 

Aktivieren und Deaktivieren von Scheduler-Objekten

Alle Scheduler-Objekte können aktiviert und deaktiviert werden, indem Sie die überladenen Prozeduren ENABLE und DISABLE aufrufen:

ORACLE Scheduler: Jobs und Programme aktivieren/deaktivieren
-- Aktivieren von Jobs und Programmen
BEGIN
  DBMS_SCHEDULER.enable (name => 'mein_plsql_block_prog');
END;
/
BEGIN
  DBMS_SCHEDULER.enable (name => 'mein_sched_job_definition_1');
END;
/
 
 
-- Deaktivieren von Jobs und Programmen
BEGIN
  DBMS_SCHEDULER.disable (name => 'mein_plsql_block_prog');
END;
/
BEGIN
  DBMS_SCHEDULER.disable (name => 'mein_sched_job_definition_1');
END;
/
 

Attribute von Oracle Scheduler-Objekten ändern:

Attribute aller Scheduler-Objekte können über die überladene Prozedur SET_ATTRIBUTE geändert werden:

ORACLE Scheduler: Attirbute setzen / änder
BEGIN
  DBMS_SCHEDULER.set_attribute (
    name      => 'mein_schedule_stuendlich',
    attribute => 'repeat_interval',
    value     => 'freq=hourly; byminute=30');
END;
/

 

Um Attribute auf Null zu setzen, kann wie folgt verfahren werden:

ORACLE Scheduler: Attribute zurücksetzen
BEGIN
  DBMS_SCHEDULER.set_attribute_null (
    name      => 'mein_schedule_stuendlich',
    attribute => 'repeat_interval');
END;
/