DBMS_JOB 패키지 수행된 작업 분석시 고려 사항
● DBMS_JOB 패키지에 의해 수행된 SQL 텍스트를 눈으로 관찰 불가.( DBMS_SCHEDULER 도 동일 )
● DBMS_JOB 패키지에 수행되는 백그라운드 작업은 SQL trace 수행시 UDUMP 가 아닌 BDUMP 디렉토리에 트레이스 파일을 남긴다.
● 등록된 작업(JOB)은 [ALL/DBA/USERS]_JOBS 뷰와 DBMS_JOBS_RUNNING 뷰를 통해 관찰 가능하다.
-- 샘플 테이블 생성
SQL> DROP TABLE T_DBMS_JOB ;
SQL> CREATE TABLE T_DBMS_JOB
( INST_ID NUMBER, SID NUMBER, DESCR VARCHAR2(100), ACTION_ID NUMBER, ACTION_DT DATE DEFAULT SYSDATE ) ;
-- 스케줄 수행할 프로시저 생성
SQL> CREATE OR REPLACE PROCEDURE DO_SOMETHING
IS
V_SID NUMBER ;
V_INST NUMBER ;
BEGIN
SELECT DISTINCT SID INTO V_SID FROM V$MYSTAT ;
SELECT INSTANCE_NUMBER INTO V_INST FROM V$INSTANCE ;
DBMS_APPLICATION_INFO.SET_MODULE( MODULE_NAME => 'DO_SOMETHING', ACTION_NAME => 'START');
FOR I IN 1 .. 2 LOOP
INSERT INTO T_DBMS_JOB ( INST_ID, SID, DESCR, ACTION_ID ) VALUES ( V_INST, V_SID, 'DBMS_JOB TESTING', I ) ;
END LOOP ;
COMMIT ;
-- FOR MONTORING
-- DBMS_LOCK.SLEEP(10) ;
DBMS_APPLICATION_INFO.SET_MODULE( MODULE_NAME => 'DO_SOMETHING', ACTION_NAME => 'END');
END ;
-- 테스트로 수행
SQL> exec do_something ;
PL/SQL procedure successfully completed.
-- 결과 확인
SQL> col descr for a20
SQL> select * from t_dbms_job ;
INST_ID SID DESCR ACTION_ID ACTION_DT
---------- ---------- -------------------- ---------- ---------------
2 1066 DBMS_JOB TESTING 1 06-APR-11
2 1066 DBMS_JOB TESTING 2 06-APR-11
SQL> truncate table t_dbms_job ;
Table truncated.
SQL> select * from t_dbms_job ;
no rows selected
SQL> col descr for a30
SQL> var job_no number ;
SQL> exec dbms_job.submit(:job_no, 'do_something;');
PL/SQL procedure successfully completed.
SQL> select * from t_dbms_job ;
no rows selected
SQL> select * from t_dbms_job ;
no rows selected
==> 결과가 보여지지 않는다. 반드시 DBMS_JOB.SUBMIT 후에 COMMIT 을 수행해야 결과가 보여짐(스케줄이 작동한다)
SQL> commit ;
Commit complete.
SQL> select * from t_dbms_job ;
INST_ID SID DESCR ACTION_ID ACTION_DT
---------- ---------- ------------------------------ ---------- ---------------
2 1015 DBMS_JOB TESTING 1 06-APR-11
2 1015 DBMS_JOB TESTING 2 06-APR-11
SQL> var job_no number ;
SQL> exec dbms_job.submit(:job_no,'do_something;',sysdate,'sysdate+1/24/60');
PL/SQL procedure successfully completed.
SQL> select job, what, last_date, next_date, broken, failures, instance from dba_jobs where what='do_something;';
JOB WHAT LAST_DATE NEXT_DATE B FAILURES INSTANCE
---------- ---------------------------------------- --------------- --------------- - ---------- ----------
394 do_something; 06-APR-11 N 0
==> LAST_DATE 값이 NULL 아직 한번도 수행 된적 없음 !!! 임으로 한번 수행하는게 필요하다.!!!
SQL> select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') from dual ;
TO_CHAR(SYSDATE,'YY
-------------------
2011/04/06 17:54:33
SQL> select * from T_DBMS_JOB order by action_dt desc ;
no rows selected
--임으로 한번 수행
SQL> exec dbms_job.run(398) ;
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
398 do_something; 2011/04/06 17:57:08 2011/04/06 17:58:08 N 0 0
SQL> select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') from dual ;
TO_CHAR(SYSDATE,'YY
-------------------
2011/04/06 17:57:26
SQL> select * from T_DBMS_JOB order by action_dt desc ;
INST_ID SID DESCR ACTION_ID ACTION_DT
---------- ---------- ------------------------------ ---------- ---------------
2 1066 DBMS_JOB TESTING 2 06-APR-11
2 1066 DBMS_JOB TESTING 1 06-APR-11
-- 시간 경과 후 매분 수행되는 결과 확인
SQL> select * from T_DBMS_JOB order by action_dt desc ;
INST_ID SID DESCR ACTION_ID ACTION_DT
---------- ---------- ------------------------------ ---------- ---------------
1 1072 DBMS_JOB TESTING 1 06-APR-11
1 1072 DBMS_JOB TESTING 2 06-APR-11
1 1072 DBMS_JOB TESTING 2 06-APR-11
1 1072 DBMS_JOB TESTING 1 06-APR-11
2 1066 DBMS_JOB TESTING 2 06-APR-11
2 1066 DBMS_JOB TESTING 1 06-APR-11
6 rows selected.
==> 인스턴스를 넘나들면서 수행 된다.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;'; < /FONT>
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
398 do_something; 2011/04/06 17:59:08 2011/04/06 18:00:08 N 0 0
- JOB 삭제
SQL> exec dbms_job.remove(398);
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
no rows selected
SQL> truncate table T_DBMS_JOB ;
Table truncated.
SQL> select * from T_DBMS_JOB order by action_dt desc ;
no rows selected
SQL> select instance_number from v$instance ;
INSTANCE_NUMBER
---------------
2
SQL> var job_no number ;
SQL> exec dbms_job.submit(job=>:job_no, what= >'do_something;', instance=>1, force=>true, interval= >'sysdate+1/24/60');
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
400 do_something; 2011/04/06 18:02:31 N 1
SQL> select * from T_DBMS_JOB order by action_dt desc ;
no rows selected
SQL> commit ;
Commit complete.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
400 do_something; 2011/04/06 18:02:54 2011/04/06 18:03:54 N 0 1
SQL> select * from T_DBMS_JOB order by action_dt desc ;
INST_ID SID DESCR ACTION_ID ACTION_DT
---------- ---------- ------------------------------ ---------- ---------------
1 1072 DBMS_JOB TESTING 2 06-APR-11
1 1072 DBMS_JOB TESTING 1 06-APR-11
--시간 경과 후
SQL> select inst_id, sid, to_char(action_dt,'YYYY/MM/DD HH24:MI:SS') from T_DBMS_JOB order by action_dt desc ;
INST_ID SID TO_CHAR(ACTION_DT,'
---------- ---------- -------------------
1 1072 2011/04/06 18:04:55
1 1072 2011/04/06 18:04:55
1 1072 2011/04/06 18:03:54
1 1072 2011/04/06 18:03:54
1 1072 2011/04/06 18:02:54
1 1072 2011/04/06 18:02:54
6 rows selected.
==> 항상 1에서만 수행 되고, 1에서 수행 불가시에만, 2번 노드에서 수행
SQL> exec dbms_job.remove(400);
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
no rows selected
SQL> truncate table T_DBMS_JOB ;
Table truncated.
SQL> select * from T_DBMS_JOB order by action_dt desc ;
no rows selected
SQL> var job_no number ;
SQL> exec dbms_job.submit(job=>:job_no, what= >'do_something;', instance=>1, force=>false, interval= >'sysdate+1/24/60');
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
401 do_something; 2011/04/06 18:08:07 N 1
SQL> commit ;
Commit complete.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';< /FONT>
JOB WHAT LAST_D NEXT_D B FAILURES INSTANCE
---------- ---------------------------------------- ------------------- ------------------- - ---------- ----------
401 do_something; 2011/04/06 18:08:26 2011/04/06 18:09:26 N 0 1
SQL> select inst_id, sid, to_char(action_dt,'YYYY/MM/DD HH24:MI:SS') from T_DBMS_JOB order by action_dt desc ;
INST_ID SID TO_CHAR(ACTION_DT,'
---------- ---------- -------------------
1 1072 2011/04/06 18:08:26
1 1072 2011/04/06 18:08:26
....
SQL> select count from t_dbms_job ;
COUNT
----------
48
SQL> select distinct inst_id from t_dbms_job ;
INST_ID
----------
1
SQL> exec dbms_job.remove(401);
PL/SQL procedure successfully completed.
SQL> select job, what, to_char(last_date,'YYYY/MM/DD HH24:MI:SS') AS LAST_D,
to_char(next_date,'YYYY/MM/DD HH24:MI:SS') AS NEXT_D, broken, failures, instance
from dba_jobs where what='do_something;';< /FONT>
no rows selected
SQL> var job_no number ;
SQL> exec dbms_job.submit(:job_no,'do_something;',sysdate,'sysdate+1/24/60');
#. USING PL/SQL Expression
: repeat_interval =>'sysdate+36/24'
#. Using Calendar Expression
: i) repeat_interval => 'FREQ=HOURLY;INTERVAL=4' ( Indiates a repeat interval of every four hours )
ii) repeat_interval => 'FREQ=YEARLY;BYMONTH=MAR,JUN,SEP,DEC;BYMONTH=15'
( indicate as repeat interval of every year on Mar 15th, Jun 15th, Sep 15th and Dec 15th )
-- 샘플 테이블 생성
CREATE TABLE CHECK_SCHEDULE
( INST_ID NUMBER, ACT_DATE DATE DEFAULT SYSDATE, ACT_DESC VARCHAR2(100)) ;
-- 샘플 프로시져 생성
CREATE OR REPLACE PROCEDURE OPS$ORACLE.DO_SCHEDULE_PROG
IS
V_SID NUMBER ;
V_INST NUMBER ;
BEGIN
SELECT INSTANCE_NUMBER INTO V_INST FROM V$INSTANCE ;
INSERT INTO CHECK_SCHEDULE ( INST_ID, ACT_DATE, ACT_DESC ) VALUES ( V_INST, SYSDATE, 'DO SCHEDULEING') ;
END ;
-- 스케줄 등록
EXEC DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name=>'CHK_SCHE',repeat_interval=>'FREQ=MINUTELY');
-- 스케줄 확인
SELECT SCHEDULE_NAME, REPEAT_INTERVAL
FROM DBA_SCHEDULER_SCHEDULES
WHERE OWNER ='OPS$ORACLE' AND SCHEDULE_NAME='CHK_SCHE';
SCHEDULE_NAME REPEAT_INTERVAL
CHK_SCHE FREQ=MINUTELY
-- 프로그램 등록
EXEC DBMS_SCHEDULER.CREATE_PROGRAM(PROGRAM_NAME=>'DO_SCHEDULE_PROGRAM',PROGRAM_TYPE=>'STORED_PROCEDURE',PROGRAM_ACTION=>'DO_SCHEDULE_PROG');
-- 프로그램 Enable
EXEC DBMS_SCHEDULER.ENABLE('DO_SCHEDULE_PROGRAM');
-- 프로그램 등록 확인
SELECT PROGRAM_NAME, PROGRAM_ACTION, ENABLED
FROM DBA_SCHEDULER_PROGRAMS
WHERE OWNER ='OPS$ORACLE' AND PROGRAM_NAME='DO_SCHEDULE_PROGRAM';
PROGRAM_NAME PROGRAM_ACTION ENABLED
DO_SCHEDULE_PROGRAM DO_SCHEDULE_PROG TRUE
-- 잡 등록
EXEC DBMS_SCHEDULER.CREATE_JOB(JOB_NAME=>'CHK_SCHE_JOB' ,PROGRAM_NAME=>'DO_SCHEDULE_PROGRAM' ,SCHEDULE_NAME=>'CHK_SCHE' ,AUTO_DROP=>FALSE);
-- 잡 Enable
EXEC DBMS_SCHEDULER.ENABLE('CHK_SCHE_JOB');
-- 잡 등록 확인
SELECT JOB_NAME, PROGRAM_NAME, SCHEDULE_NAME, ENABLED
FROM DBA_SCHEDULER_JOBS
WHERE OWNER ='OPS$ORACLE' AND JOB_NAME='CHK_SCHE_JOB';
JOB_NAME PROGRAM_NAME SCHEDULE_NAME ENABLED
CHK_SCHE_JOB DO_SCHEDULE_PROGRAM CHK_SCHE TRUE
-- 작업 결과 확인
SELECT LOG_DATE, ACTUAL_START_DATE, JOB_NAME, STATUS
FROM DBA_SCHEDULER_JOB_RUN_DETAILS WHERE JOB_NAME ='CHK_SCHE_JOB';
LOG_DATE ACTUAL_START_DATE JOB_NAME STATUS
2011/04/20 13:36:02.127937 +09:00 2011/04/20 13:36:02.087344 +09:00 CHK_SCHE_JOB SUCCEEDED
2011/04/20 13:37:01.223407 +09:00 2011/04/20 13:37:01.209592 +09:00 CHK_SCHE_JOB SUCCEEDED
2011/04/20 13:38:01.127528 +09:00 2011/04/20 13:38:01.110444 +09:00 CHK_SCHE_JOB SUCCEEDED
-- 실제 결과 확인
SELECT * FROM CHECK_SCHEDULE ;
INST_ID ACT_DATE ACT_DESC
1 2011/04/20 13:36:02 DO SCHEDULEING
1 2011/04/20 13:37:01 DO SCHEDULEING
1 2011/04/20 13:38:01 DO SCHEDULEING
1 2011/04/20 13:39:01 DO SCHEDULEING
1 2011/04/20 13:40:01 DO SCHEDULEING