oracle scheduler - ghdrako/doc_snipets GitHub Wiki

Oracle Database Scheduler (DBMS_SCHEDULER)

A built-in Oracle database feature used to schedule and manage jobs like:

  • Running PL/SQL blocks
  • Executing shell scripts
  • Automating backups
  • Scheduling batch processes

Key components:

  • Jobs – units of work to run
  • Schedules – define when jobs run
  • Programs – define what the job does
  • Job Classes & Windows – for grouping and resource management
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'my_job',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN my_procedure(); END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'FREQ=DAILY; BYHOUR=2',
    enabled         => TRUE
  );
END;
CREATE TABLE mitp.log_table(
  log_date DATE, 
  log_msg VARCHAR2(200)
);

GRANT SCHEDULER_ADMIN TO mitp;

CREATE OR REPLACE PROCEDURE mitp.run_batch
AS
BEGIN 
  INSERT INTO log_table VALUES (sysdate, 'Batch Run erfolgreich ausgeführt');
  COMMIT;
END;
/

BEGIN
    DBMS_SCHEDULER.CREATE_JOB (
     job_name           =>  'MITP_Batch_Run',
     job_type           =>  'STORED_PROCEDURE',
     job_action         =>  'run_batch',
     start_date         =>  '09.03.14 13:30:00 +01:00',
     repeat_interval    =>  'FREQ=DAILY;INTERVAL=3',
     auto_drop          =>   FALSE,
     comments           =>  'MITP Batch Job');
END;
/
SELECT job_name,state,run_count FROM user_scheduler_jobs;
JOB_NAME                       STATE            RUN_COUNT
------------------------------ --------------- ----------
MITP_BATCH_RUN                 DISABLED


BEGIN
    DBMS_SCHEDULER.ENABLE('MITP_Batch_Run');
END;
 /

SELECT job_name,state,run_count FROM user_scheduler_jobs;
JOB_NAME                       STATE            RUN_COUNT
------------------------------ --------------- ----------
MITP_BATCH_RUN                 SCHEDULED                0

SELECT job_name,state,next_run_date FROM user_scheduler_jobs;
JOB_NAME       STATE           NEXT_RUN_DATE
-------------- --------------- -----------------------------
MITP_BATCH_RUN SCHEDULED       12.03.14 13:30:00,000000 +01:00

BEGIN
  DBMS_SCHEDULER.DISABLE('MITP_Batch_Run');
END;
/
SELECT log_date,job_name,status FROM user_scheduler_job_log;
LOG_DATE                        JOB_NAME       STATUS
------------------------------- -------------- ---------
09.03.19 13:30:01,449053 +01:00 MITP_BATCH_RUN SUCCEEDED
BEGIN
    DBMS_SCHEDULER.CREATE_CHAIN(chain_name => 'BATCH_CHAIN');
END;
/

DBMS_SCHEDULER.DEFINE_CHAIN_STEP(
      chain_name => 'BATCH_CHAIN',
      step_name => 'STEP_1',
      program_name => 'BATCH_1');
END;
/
BEGIN
    DBMS_SCHEDULER.DEFINE_CHAIN_RULE(
    chain_name => 'BATCH_CHAIN',
      condition => '1 = 1',
      rule_name => 'Regel_1',
      action => 'START STEP_1');
END;
/

BEGIN
    DBMS_SCHEDULER.DEFINE_CHAIN_RULE(
      chain_name => 'BATCH_CHAIN',
      condition => 'STEP_1 COMPLETED',
      rule_name => 'Regel_2',
      action => 'START STEP_2');
END;
/


Widoki systemowe dla schedulera

Informacje o zadaniach (jobs)

Widok Opis
DBA_SCHEDULER_JOBS Wszystkie zadania w bazie (dla DBA).
ALL_SCHEDULER_JOBS Zadania dostępne dla użytkownika (wraz z grantami).
USER_SCHEDULER_JOBS Zadania należące do aktualnego użytkownika.

Harmonogramy i definicje czasu

Widok Opis
DBA_SCHEDULER_SCHEDULES Zdefiniowane harmonogramy (repeat_interval).
USER_SCHEDULER_SCHEDULES Harmonogramy utworzone przez użytkownika.

Programy (programs)

Widok Opis
DBA_SCHEDULER_PROGRAMS Definicje programów (czyli co ma być wykonane).
USER_SCHEDULER_PROGRAMS Programy użytkownika.

Klasy zadań i okna (job classes & windows)

Widok Opis
DBA_SCHEDULER_JOB_CLASSES Klasy zadań do grupowania jobów.
DBA_SCHEDULER_WINDOWS Okna czasowe (np. backup w nocy).
DBA_SCHEDULER_WINDOW_GROUPS Grupowanie okien.

Informacje o uruchomieniach i historii

Widok Opis
DBA_SCHEDULER_JOB_RUN_DETAILS Historia uruchomień – czy się udały, błędy itd.
DBA_SCHEDULER_JOB_LOG Logi jobów (start, stop, status).
DBA_SCHEDULER_RUNNING_JOBS Aktualnie uruchomione joby.

Inne pomocne widoki

Widok Opis
DBA_SCHEDULER_CREDENTIALS Poświadczenia do uruchamiania zewnętrznych zadań (np. shell).
DBA_SCHEDULER_GLOBAL_ATTRIBUTE Atrybuty globalne schedulera.
DBA_SCHEDULER_JOB_ARGS Argumenty przekazywane do jobów.
DBA_SCHEDULER_CHAIN* Widoki związane z zaawansowanymi łańcuchami zadań.

Przykład: Sprawdzenie wszystkich aktywnych jobów

SELECT job_name, enabled, state, last_start_date, next_run_date
FROM dba_scheduler_jobs
WHERE enabled = 'TRUE';

wyłączyć i włączyć Oracle Scheduler

Wyłączenie Oracle Scheduler:

EXEC DBMS_SCHEDULER.disable(name => 'SYS.SCHEDULER$_EVENT_QUEUE');

Lub, żeby globalnie zatrzymać wszystkie joby (scheduler jako cały mechanizm):

ALTER SYSTEM SET "_disable_scheduler" = TRUE SCOPE=MEMORY;

Uwaga: to ukryty parametr, używaj go ostrożnie – najlepiej tylko w testowym środowisku.

Alternatywnie (zalecane i bez ukrytych parametrów):

BEGIN
  DBMS_SCHEDULER.stop_job(job_name => 'job_name', force => TRUE);
END;

Ale to działa tylko na konkretne joby.

Włączenie Oracle Scheduler:

Jeśli wcześniej użyłeś "_disable_scheduler" = TRUE, to cofnij to tak:

ALTER SYSTEM RESET "_disable_scheduler" SCOPE=MEMORY;

Lub:

ALTER SYSTEM SET "_disable_scheduler" = FALSE SCOPE=MEMORY;

I ewentualnie uruchom konkretne joby:

BEGIN
  DBMS_SCHEDULER.enable('nazwa_joba');
END;

Sprawdzenie statusu Scheduler'a:

SELECT VALUE FROM V$PARAMETER WHERE NAME = '_disable_scheduler';

Lub sprawdzenie, które joby są aktywne/nieaktywne:

SELECT job_name, enabled, state
FROM dba_scheduler_jobs
WHERE owner = 'SCHEMA_NAME';

Istotne kwestie

Status i zarządzanie błędami

  • Czy job zakończył się błędem?

    • Można to sprawdzać w DBA_SCHEDULER_JOB_RUN_DETAILS albo DBA_SCHEDULER_JOB_LOG.
  • Co się dzieje w przypadku błędu?

    • Czy job ma retry policy?
    • Sprawdź pola: max_failures, retry_count, restartable.

Zależności między jobami (łańcuchy – chains)

  • Czy używasz łańcuchów (chains) do tworzenia zależności między jobami? Oracle Scheduler pozwala na modelowanie skomplikowanych procesów ETL czy batchowych przy pomocy:
    • DBMS_SCHEDULER.CREATE_CHAIN
    • Widoki: *_SCHEDULER_CHAINS, *_SCHEDULER_CHAIN_RULES, *_CHAIN_STEPS

Bezpieczeństwo i poświadczenia (credentials)

  • Jeśli scheduler uruchamia zewnętrzne procesy (np. skrypt shellowy), czy używasz credentials? Sprawdź: DBA_SCHEDULER_CREDENTIALS
    • Czy są dobrze zabezpieczone hasła?

Wydajność i limity

  • Czy joby nie kolidują ze sobą? – np. wiele intensywnych zadań o tej samej porze
  • Czy używasz job_class i resource_manager do nadzorowania, ile zasobów może zająć dana klasa jobów?

Monitoring i alerting

  • Czy masz własny monitoring jobów?
  • Przykładowo:
    • Joby, które się nie uruchomiły od X dni
    • Joby, które kończą się błędem
    • Joby, które wykonują się dłużej niż zwykle

Repeat Interval – czy używasz Calendar Expressions czy PL/SQL Expressions?

  • Typowe repeat_interval:
    'FREQ=DAILY; BYHOUR=2; BYMINUTE=0;'
  • Ale można też używać dynamicznych wyrażeń PL/SQL.

Logowanie i przechowywanie historii

  • Jak długo trzymasz historię jobów? Domyślnie Oracle przechowuje je w SCHEDULER$_EVENT_LOG i SCHEDULER$_JOB_RUN_DETAILS.
  • Można użyć:
    DBMS_SCHEDULER.set_scheduler_attribute('max_job_log_entries', 1000);

Czyszczenie przeterminowanych jobów

  • Czy masz zadania jednorazowe (run_once)?
  • Czy czyszczone są stare, niepotrzebne wpisy z historii?

Checklist

Nr Obszar Punkt kontrolny
0 Zadania (Jobs) Czy wszystkie joby są w stanie ENABLED?
1 Zadania (Jobs) Czy są joby z błędami w ostatnich uruchomieniach?
2 Zadania (Jobs) Czy są joby, które nie uruchamiały się od X dni?
3 Harmonogramy Czy wszystkie harmonogramy mają poprawnie usta...
4 Logi i Historia Czy logi jobów są przechowywane wystarczająco ...
# Przygotowanie zestawu skryptów SQL do audytu Oracle Scheduler
sql_scripts = [
    {
        "Opis": "Joby w stanie innym niż ENABLED",
        "Skrypt": """SELECT owner, job_name, enabled FROM dba_scheduler_jobs WHERE enabled = 'FALSE';"""
    },
    {
        "Opis": "Joby z błędami w ostatnich uruchomieniach",
        "Skrypt": """
SELECT job_name, status, actual_start_date, run_duration, additional_info
FROM dba_scheduler_job_run_details
WHERE status != 'SUCCEEDED'
ORDER BY actual_start_date DESC;
"""
    },
    {
        "Opis": "Joby, które nie uruchamiały się od 7 dni",
        "Skrypt": """
SELECT job_name, last_start_date, next_run_date
FROM dba_scheduler_jobs
WHERE last_start_date < SYSDATE - 7;
"""
    },
    {
        "Opis": "Harmonogramy z repeat_interval",
        "Skrypt": """SELECT schedule_name, repeat_interval FROM dba_scheduler_schedules;"""
    },
    {
        "Opis": "Zbyt wiele logów – potrzeba czyszczenia?",
        "Skrypt": """
SELECT COUNT(*) AS liczba_logow
FROM dba_scheduler_job_log
WHERE log_date < SYSDATE - 30;
"""
    },
    {
        "Opis": "Joby bez retry_count i max_failures",
        "Skrypt": """
SELECT job_name, retry_count, max_failures
FROM dba_scheduler_jobs
WHERE retry_count = 0 AND max_failures = 0;
"""
    },
    {
        "Opis": "Joby uruchamiane o tej samej godzinie (możliwy konflikt)",
        "Skrypt": """
SELECT job_name, repeat_interval
FROM dba_scheduler_jobs
WHERE repeat_interval LIKE '%BYHOUR=2%'; -- Można zmienić BYHOUR
"""
    },
    {
        "Opis": "Joby zdefiniowane w klasach (job_classes)",
        "Skrypt": """
SELECT job_name, job_class FROM dba_scheduler_jobs;
"""
    },
    {
        "Opis": "Poświadczenia używane przez joby",
        "Skrypt": """
SELECT job_name, credential_name FROM dba_scheduler_jobs WHERE credential_name IS NOT NULL;
"""
    },
    {
        "Opis": "Jednorazowe joby (run_once)",
        "Skrypt": """
SELECT job_name, repeat_interval
FROM dba_scheduler_jobs
WHERE repeat_interval IS NULL;
"""
    },
    {
        "Opis": "Joby z dynamicznymi PL/SQL repeat_interval",
        "Skrypt": """
SELECT job_name, repeat_interval
FROM dba_scheduler_jobs
WHERE repeat_interval LIKE 'SYSTIMESTAMP%' OR repeat_interval LIKE 'TO_TIMESTAMP%';
"""
    }
]

df_sql_scripts = pd.DataFrame(sql_scripts)
tools.display_dataframe_to_user(name="Skrypty SQL do audytu Oracle Scheduler", dataframe=df_sql_scripts)