Uno delle cose importanti da capire quando si parla di db Oracle, è quella che riguarda i jobs e la loro gestione.

Un job è l’insieme di uno schedulatore (Oracle Scheduler) e un programma. In breve un job è un programma schedulato (da un altro programma) in un certo intervallo di tempo.

Lo schedulatore è quindi un particolare programma Oracle che permette ad un utente la schedulazione dei programmi specificando un intervallo di tempo in cui verranno eseguiti.

La prima volta che lo schedulatore viene abilitato, un processo (che fa parte dei processi Oracle di background) chiamato Job Queue Process (CJQ) viene avviato sul db server, come mostrato nel seguente esempio:

[paolo@oracle-db ~]$ ps -ef | grep oracle | grep "cjq*"
oracle   23619     1  0 gen03 ?        00:01:10 ora_cjq0_testdb2

Oppure dal db usando la seguente query:

SELECT s.SID, s.username, s.program, s.machine, s.terminal,
       s.process client_process, s.last_call_et, p.spid server_process
  FROM v$session s, v$process p
 WHERE s.paddr = p.addr and s.program like '%CJQ%'

Per trovare e visualizzare informazioni utili sui job esistono le seguenti viste utili:

  • dba_jobs: contiene la descrizione di tutti i job nel db
  • dba_scheduler_jobs: contiene le informazioni relative a tutti i jobs dello schedulatore nel db
  • user_jobs: contiene la descrizione di tutti i job di cui è proprietario dell’utente corrente
  • user_scheduler_jobs: contiene le informazioni relative a tutti i job dello schedulatore di cui è proprietario l’utente corrente
  • user_scheduler_job_log: contiene informazioni di log di tutti i job dello schedulatore di cui è proprietario l’utente corrente
  • user_scheduler_job_run_details: contiene le informazioni dettagliate di log di tutti i job dello schedulatore per l’utente corrente (ad esempio l’errore nel caso di un job fallito oppure il relativo output)
  • user_scheduler_running_jobs: contiene tutti i job in esecuzione dello schedulatore per l’utente corrente

Gestione dei Jobs Oracle

Premessa: i comandi utilizzati sono stati usati in un ambiente di test.

Il pacchetto che viene utilizzato per gestire i job è: dbms_scheduler (nelle versioni precedenti di db Oracle, veniva usato il pacchetto: dbms_jobs).

Creazione di un job

Si possono creare differenti tipi di job:

  • Blocchi PL/SQL anonimi
  • Stored Procedures
  • Java Stored Procedures

Per creare un job usando utenza SYSTEM ad esempio di tipologia blocco PL/SQL per lo schema dbuser si esegue la seguente procedura :

BEGIN
   DBMS_SCHEDULER.create_job
      (job_name             => 'dbuser.my_job1',
       job_type             => 'PLSQL_BLOCK',
       job_action           => 'BEGIN DBMS_STATS.GATHER_TABLE_STATS(''DBUSER'',
                            ''DETTLISTINI''); END;',
       start_date           => SYSTIMESTAMP,
       repeat_interval      => 'FREQ=DAILY',
       end_date             => NULL,
       enabled              => TRUE,
       comments             => 'Gather table statistics'
      );
END;

Nota: in questo caso il blocco PL/SQL anonimo utilizzato non è salvato nel db ma dev’essere caricato ogni volta che si vuole eseguirlo; questo vuol dire definirlo nel parametro job action ogni volta che si vuole utilizzarlo.

Start/Stop di un job

Per avviare un job, basta eseguire la seguente procedura:

BEGIN
  DBMS_SCHEDULER.RUN_JOB('schema.nome_job');
END;

Di seguito un esempio, usando il job creato all’inizio:

BEGIN
  DBMS_SCHEDULER.RUN_JOB('dbuser.my_job1');
END;

Nota: non è necessario chiamare la procedura RUN_JOB per avviare un job come programmato dalla sua schedulazione, perchè lo schedulatore lo avvierà automaticamente, se abilitato.

Mentre per stopparlo, bisogna eseguire la seguente procedura:

BEGIN
  DBMS_SCHEDULER.STOP_JOB('schema.nome_job');
END;

Drop di un job

Per eliminare un job dal db si esegue :

BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'schema.nome_job');
END;

Come esempio, si riporta quello seguente:

BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'dbuser.my_job1');
END;

Abilitazione/Disabilitazione di un job

Per abilitare un job si esegue la seguente procedura:

BEGIN
   DBMS_SCHEDULER.ENABLE (NAME => 'schema.nome_job');
END;

Per disabilitare invece un job si esegue la seguente procedura:

BEGIN
   DBMS_SCHEDULER.DISABLE (NAME => 'schema.nome_job');
END;

Come esempio, si riporta quello seguente:

BEGIN
   DBMS_SCHEDULER.DISABLE (NAME => 'dbuser.my_job1');
END;

Eseguendo infatti ad esempio la seguente query:

SELECT * FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME = 'MY_JOB1';

si troverà che il campo ENABLED sarò valorizzato in FALSE.

Mettere i jobs in stato “Broken”

Un’altra cosa utile per quanto riguarda i jobs, è che si possono “marchiare” e metterli in uno specifico stato che indica al db Oracle di non eseguirli mai fino a che non saranno tolti da questo stato e messi di nuovo in stato “normale”. Lo stato in cui si mettono i jobs viene chiamato BROKEN e per fare ciò si esegue la seguente procedura:

EXECUTE DBMS_JOB.BROKEN (id_job,TRUE);

Ad es. creiamo il seguente job:

DECLARE
   l_job   PLS_INTEGER;
BEGIN
   DBMS_JOB.submit (job            => l_job,
                    what           => 'begin null; end;',
                    next_date      => TRUNC (SYSDATE) + 1,
                    INTERVAL       => 'trunc(sysdate)+1'
                   );
END;

che la procedura submit metterà nella coda dei job e in questo caso nella tabella quindi user_jobs,

Nota: in generale, un job quando fallisce la sua esecuzione più di 16 volte, viene messo nello stato di broken.

Dopodichè per vedere il job creato, si esegue la seguente query

select * from user_jobs

Da qui si evince cosi come indicato durante la creazione del job l’id da usare nella seguente query per metterlo in stato broken:

EXECUTE DBMS_JOB.BROKEN (1,TRUE);

Per verificare i jobs in stato BROKEN, si può usare la query precedente in questo modo:

select * from user_jobs
where broken='Y'

Nota: in questo caso si visualizzano i jobs in broken dell’utente corrente con cui si sta accedendo al db.

Jobs di backup

Sono specifici jobs adibiti alla copia di tutti quei files che fanno parte del db e alla sua ricostruzione (datafiles, control files, archived redo log files ecc..) in caso di guasto o di altri problemi che compromettono il db o il server che lo ospita.

Per vedere i jobs di backup gestiti da RMAN (Recovery Manager), si può eseguire la sequente query:

select start_time,end_time,input_bytes,output_bytes,status,input_type
from v$rman_backup_job_details
order by session_stamp desc

BIBLIOGRAFIA

Documentazione Oracle: https://docs.oracle.com/en/database/oracle/oracle-database/index.html

Libro: Easy Oracle Jumpstart – Oracle Database Management Concepts and Administration (Steve Karam – Robert G. Freeman)