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)