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)
Salve. Vorrei lanciare un Job come se venisse lanciato da “dentro” il DB, e non dalla mia Connessione Toad (che è poco stabile).
E’ possibile? Per ora faccio Tasto destro + Execute, ma mi rimane lì impallato. Il Job dure circa 20 Minuti, ma la Connessione non dura così tanto. C’è qualche Stratagemma? Grazie
Ciao Gianluca, cosa intendi per lanciarlo da “dentro” il db? Intendi un job schedulato senza il bisogno di eseguirlo te da un client per db Oracle?