행위

"오라클 스케줄러"의 두 판 사이의 차이

DB CAFE

(참고사항)
1번째 줄: 1번째 줄:
 
= 오라클 JOB, SCHEDULES =
 
= 오라클 JOB, SCHEDULES =
 +
* ORACLE JOB과 ORACLE SCHEDULER ​가장 큰 차이점이라면 OS상의 crontab에 등재되는 shell프로그램도 ORACLE SCHEDULER에서 실행 가능
  
----
+
== DBMS_JOB ==
 +
- 특정 시간 및 간격으로 특정 작업을 수행
 +
 
 +
== DBMS_SCHEDULER ==
 +
* 매우 복잡하고 정교한 수준의 스케줄 작업 가능
 +
* DBMS_SCHEDULER 의 장점
 +
*: - GUI(EM)을 통해서 손쉬운 관리 가능
 +
*: - 모듈화된 스케줄 오브젝트를 통해서 쉽게 공유. ( 프로그램, 스케줄, 잡 )
 +
*: - 모든 스케줄 활동이 기록.
 +
*: - TimeZone 지원.
 +
*: - 디비간 이동시 손쉽다(By DataPump)
 +
 
 +
=== 프로그램(Program) ===
 +
# 실행 가능한 프로그램(Program)을 말함
 +
# DBMS_JOB 은 PL/SQL 블록, 저장 프로시저(Stored Procedure)만 가능
 +
# DBMS_SCHEDULER는 외부 프로그램까지 사용 가능
 +
#: - ( PL/SQL 블록, 저장 프로시저(Stored Procedure), 실행 파일(Executable, Unix Shell, Windows 실행 파일) )
 +
#: - DBMS_SCHEDULER.CREATE_PROGRAM 프로시져를 통해 등록 가능하며 [ALL/DBA/USER]_SCHEDULER_PROGRAMS 뷰를 통해서 확인 가능
 +
# 스케줄링에 의해서 실행 ( 프로그램 이름, 타입, Argument 갯수 등 )
 +
 
 +
=== 스케줄(Schedule) - DBMS_SCHEDULER.CREATE_SCHEDULE ===
 +
# 작업을 수행할 스케줄을 말함.
 +
# 작업 시작 시간, 종료 시간, 간격 등을 지정.
 +
# DBMS_JOB에 비해 유연함
 +
#:<source lang=sql>EX ) "FREQ=YEARLY; BYMONTH=4; BYMONTHDAY=15; BYHOUR=9; BYMINUTE=0; BYSECOND=0" -- 매년 4월 15일 9시에 작업 수행</source>
 +
# DBMS_SCHEDULER.CREATE_SCHEDULE 프로시져로 등록 가능
 +
# [ALL/DBA/USER]_SCHEDULER_SCHEDULES 뷰를 통해서 확인 가능
 +
# 구문 설명
 +
## USING PL/SQL Expression
 +
##: 예시) repeat_interval =>'sysdate+36/24'
 +
## Using Calendar Expression
 +
##: 예시 1) repeat_interval => 'FREQ=HOURLY;INTERVAL=4' ( Indiates a repeat interval of every four hours )
 +
##: 예시 2) 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 )
 +
 
 +
{{틀:고지상자2
 +
|제목= [인터벌 설정법]
 +
|내용=<source lang=sql>
 +
Execute daily          'SYSDATE + 1'
 +
Execute once per week  'SYSDATE + 7'
 +
Execute hourly        'SYSDATE + 1/24'
 +
Execute every 10 min.  'SYSDATE + 10/1440'
 +
Execute every 30 sec.  'SYSDATE + 30/86400'
 +
Do not re-execute      NULL
 +
</source>
 +
1) 10분간격으로 실행
 +
 
 +
<source lang=sql>
 +
SYSDATE + 1/24/6
 +
</source>
 +
 +
2) 현재 시간으로 부터 다음 날 현재 시간에 실행 (매일) 
 +
<source lang=sql>
 +
SYSDATE + 1    -- 지금이 오후3시면 다음날 오후 3시 에 매일매일 실행됩니다.
 +
</source>
 +
 +
3) 매일 새벽 5시
 +
<source lang=sql>
 +
TRUNC(SYSDATE) + 1 + 5 / 24
 +
</source>
 +
 +
4) 매일 밤 10시
 +
<source lang=sql>
 +
TRUNC(SYSDATE)  + 20 / 24
 +
</source>
 +
}}
 +
 
 +
=== 잡(Job) - DBMS_SCHEDULER.CREATE_JOB ===
 +
# 주어진 프로그램과 스케줄에 따라 수행할 작업을 말함
 +
# 명시적으로 생성된 프로그램(프로시져,함수등) 과 스케줄을 이용할 수도 있고, 작업을 생성하면 암묵적인 프로그램과 스케줄을 생성할 수도 있다.
 +
# DBMS_SCHEDULER.CREATE_JOB 프로시져를 통해 등록 가능
 +
# [ALL/DBA/USER]_SCHEDULER_JOBS 뷰를 통해 확인 가능
 +
# 작업이 수행되면서 남는 로그 데이터는 [ALL/DBA/USER]_SCHEDULER_JOB_LOG 뷰나 [ALL/DBA/USER]_SCHEDULER_JOB_RUN_DETAILS 뷰를 통해 확인 가능
 +
 
 +
=== 작업 클래스(Job Class) ===
 +
# 작업의 공통 속성을 묶어서 만든 분류를 말한다.
 +
# Resouce Consumer Group, Service, Logging Level, Log History 의 속성을 조합해서 하나의 클래스 생성 한다.
 +
# Resource Consumer Group 은 DBMS_RESOURCE_MANGER 패키지를 통해서 생성,자원을 얼마나 사용 가능하게 할지를 지정
 +
# Service는 작업이 특정 서비스에 대한 리소스 친화도(Resource Affinity)를 가지도록 지정
 +
# Service는 RAC 에서 클러스터 내의 여러 노드를 묶은 논리적인 그룹
 +
# Logging Level 은 작업 실행에 대한 로그 데이터의 레벨을 지정
 +
# Log History 는 로그 데이터를 얼마나 저장할 지를 지정한다
 +
# 같은 작업 클래스에 속하는 작업은 같은 속성을 공유하기 때문에 관리상의 편의점을 제공
 +
# 하나의 JOB 은 하나의 JOB CLASS 에만 속함
 +
 
 +
=== 윈도우(Window) ===
 +
# 특정 리소스 플랜(Resoure Plan)을 적용하는 시간 단위를 의미
 +
# 리소스 플랜은 오라클이 자원을 관리하는 단위로, 작업의 종류에 따라 CPU 등의 자원을 얼마나 부여할 지를 지정하는 역할
 +
#: - 윈도우를 지정하면 해당 윈도우 안에서 실행되는 작업은 윈도우 생성시 지정한 리소스 플랜을 사용하게 된다
 +
 
 +
=== 체인(Chain ) ===
 +
# 프로그램의 집합을 의미
 +
# 일련의 프로그램들을 순서대로 수행하고자 할 경우에 사용.
 +
 
 +
=== 스케줄작업과 RAC Instance ===
 +
# DBMS_JOB ==> 작업을 실행할 인스턴스 번호를 지정 // 한노드로 지정 시에 좀 더 편리
 +
# DBMS_SCHEDULER => Instance_Stickness 라는 개념을 통해 좀 더 지능적으로 인스턴스를 할당
 +
# INSTANCE_STICKSNESS = TRUE ( DBMS_SCHEDULER.SET_ATTRIBUTE ) 의미
 +
#: - 작업 수행 시 현재 가장 부하가 적은 인스턴스에 작업을 분배 한다.
 +
#: - 이후 작업 수행 시에는 가능한 최초에 지정된 인스턴스에서 작업을 수행하도록 한다.
 +
#: - 이 매커니즘을 일컬어 인스턴스 접착도라고 하며 리소스 친화도를 구현하는 방법
 +
#: - 최초에 지정된 인스턴스가 다운되거나, 부하가 심해서 작업을 수행할 수 없을 경우 다른 인스턴스에서 작업을 수행
 +
#: - 만일 INSTANCE_STICKNESS 속성 값이 FALSE 이면 오라클은 인스턴스 순서대로 작업을 수행한다.
 +
#: - DBMS_JOB 패키지를 이용해 작업을 수행하되 인스턴스 번호를 지정하지 않은 경우와 거의 같은 방식으로 작동한다.
  
ORACLE JOB과 ORACLE SCHEDULER ​가장 큰 차이점이라면
 
OS상의 crontab에 등재되는 shell프로그램도 ORACLE SCHEDULER에서 작동 가능
 
  
 
== 오라클스케쥴러 등록을 위한 권한 ==
 
== 오라클스케쥴러 등록을 위한 권한 ==
12번째 줄: 114번째 줄:
  
 
== 명령어 ==
 
== 명령어 ==
<source lang=sql>
+
# DBMS_SCHEDULER.CREATE_PROGRAM
1. DBMS_SCHEDULER.CREATE_PROGRAM
+
#: - JOB이 스케쥴러에 맞게 돌면서 실제로 동작하는 프로그램(외부의 shell이나 SP, PLSQL_BLOCK 등) 을 등
- JOB이 스케쥴러에 맞게 돌면서 실제로 동작하는 프로그램(외부의 shell이나 SP, PLSQL_BLOCK 등) 을 등
+
# DBMS_SCHEDULER.CREATE_SCHEDULER
 
+
#: - 주기적으로 돌아갈 스케쥴을 등록
2. DBMS_SCHEDULER.CREATE_SCHEDULER
+
# DBMS_SCHEDULER.CREATE_JOB
- 주기적으로 돌아갈 스케쥴을 등록
+
#: - 수행할 작업을 등록한다.  
 
 
3. DBMS_SCHEDULER.CREATE_JOB
 
- 수행할 작업을 등록한다.  
 
</source>
 
  
 
== 사용 방법 ==
 
== 사용 방법 ==
 
+
=== 동작할 프로그램 등록 ===
 
 
=== 1. 동작할 프로그램 등록 ===
 
 
<source lang=sql>
 
<source lang=sql>
 
BEGIN
 
BEGIN
38번째 줄: 134번째 줄:
 
</source>
 
</source>
  
==== 1-1. 매개변수가 있는 경우 ====
+
==== 매개변수가 있는 경우 ====
 
<source lang=sql>
 
<source lang=sql>
 
BEGIN
 
BEGIN
 
/*-------------------------------------------------------------------------------------------------------------------
 
/*-------------------------------------------------------------------------------------------------------------------
program_name: 프로그램이름
+
program_name: 프로그램 이름
 
program_action: 실제 액션이 일어나는 SP(미리 등록되어있어야 한다). 여기서 shell 프로그램등을 돌릴 수도 있다.
 
program_action: 실제 액션이 일어나는 SP(미리 등록되어있어야 한다). 여기서 shell 프로그램등을 돌릴 수도 있다.
 
program_type: SP 라고 명시
 
program_type: SP 라고 명시
53번째 줄: 149번째 줄:
 
argument_value: 인수값
 
argument_value: 인수값
 
--------------------------------------------------------------------------------------------------------------------*/
 
--------------------------------------------------------------------------------------------------------------------*/
 
 
   DBMS_SCHEDULER.CREATE_PROGRAM (
 
   DBMS_SCHEDULER.CREATE_PROGRAM (
 
       PROGRAM_NAME => 'STATS_MAIN_BATCH_PROGRAM'
 
       PROGRAM_NAME => 'STATS_MAIN_BATCH_PROGRAM'
74번째 줄: 169번째 줄:
  
  
=== 2. 스케줄 등록 ===
+
=== 스케줄 등록 ===
# 10g 이상
 
<source lang=sql>
 
BEGIN
 
/*-------------------------------------------------------------------------------------------------------------------
 
schedule_name: 스케쥴 이름
 
start_date: 스케쥴이 작동을 시작 할 시각. 입력한 시점부터 스케쥴러가 시작된다. AM 03시로 설정함
 
end_date: 스케쥴이 작동을 멈출 시간.
 
repeat_interval: 스케쥴이 작동하는 주기. 하루 한번 돌게 설정 매일 AM 03시에 동작함.
 
comments: 부가설명
 
--------------------------------------------------------------------------------------------------------------------*/
 
DBMS_SCHEDULER.CREATE_SCHEDULE(
 
schedule_name => 'SCHEDULE_DAILY_AM_3_HOUR',
 
start_date      => TRUNC(SYSDATE)+1 +3/24,
 
end_date        => null,
 
repeat_interval => 'FREQ=DAILY;INTERVAL=1',
 
comments => 'Every AM 03 HOUR');
 
END;
 
</source>
 
 
 
# 11g, 12c 이상
 
 
<source lang=sql>
 
<source lang=sql>
 
/*-------------------------------------------------------------------------------------------------------------------
 
/*-------------------------------------------------------------------------------------------------------------------
117번째 줄: 192번째 줄:
 
</source>
 
</source>
  
=== 3. JOB 등록, 실제 수행 될 작업으로 스케쥴러와 프로그램 명시 ===
+
=== JOB 등록, 실제 수행 될 작업으로 스케쥴러와 프로그램 명시 ===
 
<source lang=sql>
 
<source lang=sql>
 
BEGIN
 
BEGIN
138번째 줄: 213번째 줄:
 
</source>
 
</source>
  
=== 4. 스케줄러 삭제 ===
+
=== 스케줄러 삭제 ===
 
<source lang=sql>
 
<source lang=sql>
 
execute dbms_scheduler.drop_job('FRG_BALANCE_HIST_UPDATE_JOB',false);  
 
execute dbms_scheduler.drop_job('FRG_BALANCE_HIST_UPDATE_JOB',false);  
 
execute dbms_scheduler.drop_program('FRG_BALANCE_HIST_UPDATE_PRG',false);
 
execute dbms_scheduler.drop_program('FRG_BALANCE_HIST_UPDATE_PRG',false);
 
execute dbms_scheduler.drop_schedule('SCHEDULE_30_MIN',false);
 
execute dbms_scheduler.drop_schedule('SCHEDULE_30_MIN',false);
 +
</source>
  
 +
* job먼저 지우고 program 삭제
 +
* program 먼저 지우려고 하면 종속된 객체라면서 안지워짐.
  
*.job먼저 지우고 program 삭제
+
<source lang=sql>
*.program 먼저 지우려고 하면 종속된 객체라면서 안지워짐.
 
 
 
 
 
 
BEGIN
 
BEGIN
 
   DBMS_SCHEDULER.DROP_JOB(
 
   DBMS_SCHEDULER.DROP_JOB(
163번째 줄: 238번째 줄:
 
</source>
 
</source>
  
=== 5. 등록 정보 확인 ===
+
=== 스케줄러 등록/실행 정보 조회 뷰 ===
 
<source lang=sql>
 
<source lang=sql>
 
SELECT * FROM DBA_SCHEDULER_JOBS; --등록된 job
 
SELECT * FROM DBA_SCHEDULER_JOBS; --등록된 job
176번째 줄: 251번째 줄:
  
 
=== 참고사항 ===
 
=== 참고사항 ===
 +
* JOB_CLASS 생성
 
<source lang=sql>
 
<source lang=sql>
 
# JOB_CLASS 설정
 
# JOB_CLASS 설정
200번째 줄: 276번째 줄:
  
 
== 스케줄 등록 예시  ==
 
== 스케줄 등록 예시  ==
 +
=== 샘플 테이블 생성 ===
 +
* 테이블 DBCAFE.CHECK_SCHEDULE 생성
 
<source lang=sql>
 
<source lang=sql>
-- 샘플 테이블 생성
+
CREATE TABLE CHECK_SCHEDULE (  
CREATE TABLE CHECK_SCHEDULE ( INST_ID NUMBER, ACT_DATE DATE DEFAULT SYSDATE, ACT_DESC VARCHAR2(100)) ;
+
                            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 ;
+
</source>
  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');  
+
* 프로시져 DBCAFE.SP_SCHD_TEST 생성 
 +
<source lang=sql>
 +
CREATE OR REPLACE PROCEDURE DBCAFE.SP_SCHD_TEST
 +
    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 ;
 +
</source>
  
-- 스케줄 확인  
+
=== 스케줄러 생성 ===
 +
* 스케줄러 SCHD_DBCAFE 생성 
 +
<source lang=sql>
 +
EXEC DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name=>'SCHD_DBCAFE',repeat_interval=>'FREQ=MINUTELY'); -- 매분마다 실행 
 +
</source>
 +
 
 +
=== 스케줄러 현재상태 확인 ===
 +
* DBA_SCHEDULER_SCHEDULES
 +
<source lang=sql>
 
SELECT SCHEDULE_NAME, REPEAT_INTERVAL  
 
SELECT SCHEDULE_NAME, REPEAT_INTERVAL  
 
   FROM DBA_SCHEDULER_SCHEDULES  
 
   FROM DBA_SCHEDULER_SCHEDULES  
  WHERE OWNER ='OPS$ORACLE'  
+
  WHERE OWNER ='DBCAFE'  
   AND SCHEDULE_NAME='CHK_SCHE';  
+
   AND SCHEDULE_NAME='SCHD_DBCAFE';  
 +
</source>
  
SCHEDULE_NAME REPEAT_INTERVAL CHK_SCHE FREQ=MINUTELY
+
=== 프로그램 등록 ===
 
+
<source lang=sql>
-- 프로그램 등록  
 
 
EXEC DBMS_SCHEDULER.CREATE_PROGRAM(
 
EXEC DBMS_SCHEDULER.CREATE_PROGRAM(
     PROGRAM_NAME=>'DO_SCHEDULE_PROGRAM'
+
     PROGRAM_NAME=>'SP_SCHD_PROG_DBCAFE'
 
   , PROGRAM_TYPE=>'STORED_PROCEDURE'
 
   , PROGRAM_TYPE=>'STORED_PROCEDURE'
 
   , PROGRAM_ACTION=>'DO_SCHEDULE_PROG');  
 
   , PROGRAM_ACTION=>'DO_SCHEDULE_PROG');  
 +
</source>
  
-- 프로그램 Enable  
+
=== 프로그램 Enable ===
EXEC DBMS_SCHEDULER.ENABLE('DO_SCHEDULE_PROGRAM');  
+
<source lang=sql>
 +
EXEC DBMS_SCHEDULER.ENABLE('SP_SCHD_PROG_DBCAFE');  
 +
</source>
  
-- 프로그램 등록 확인  
+
=== 프로그램 등록 확인 ===
 +
<source lang=sql>
 
SELECT PROGRAM_NAME, PROGRAM_ACTION, ENABLED  
 
SELECT PROGRAM_NAME, PROGRAM_ACTION, ENABLED  
 
   FROM DBA_SCHEDULER_PROGRAMS  
 
   FROM DBA_SCHEDULER_PROGRAMS  
  WHERE OWNER ='OPS$ORACLE' AND PROGRAM_NAME='DO_SCHEDULE_PROGRAM';  
+
  WHERE OWNER ='DBCAFE' AND PROGRAM_NAME='SP_SCHD_PROG_DBCAFE';  
 +
</source>
  
-- 잡 등록  
+
=== 잡 등록 ===
EXEC DBMS_SCHEDULER.CREATE_JOB(JOB_NAME=>'CHK_SCHE_JOB' ,PROGRAM_NAME=>'DO_SCHEDULE_PROGRAM' ,SCHEDULE_NAME=>'CHK_SCHE' ,AUTO_DROP=>FALSE);  
+
<source lang=sql>
 +
EXEC DBMS_SCHEDULER.CREATE_JOB(
 +
    JOB_NAME     => 'SCHD_JOB_DBCAFE'  
 +
  , PROGRAM_NAME => 'SP_SCHD_PROG_DBCAFE'  
 +
  , SCHEDULE_NAME=> 'SCHD_DBCAFE'  
 +
  , AUTO_DROP   => FALSE   );  
 +
</source>
  
-- 잡 Enable
+
=== 잡 Enable ==
EXEC DBMS_SCHEDULER.ENABLE('CHK_SCHE_JOB');  
+
<source lang=sql>
 +
-- 확인 필요 ???
 +
-- EXEC DBMS_SCHEDULER.ENABLE('SCHD_JOB_DBCAFE');  
  
-- 잡 등록 확인  
+
</source>
 +
 +
 
 +
=== 스케줄러 실행 / 진행 사항 조회  ===
 +
-- 잡 등록/생성 확인  
 +
<source lang=sql>
 
SELECT JOB_NAME, PROGRAM_NAME, SCHEDULE_NAME, ENABLED  
 
SELECT JOB_NAME, PROGRAM_NAME, SCHEDULE_NAME, ENABLED  
   FROM DBA_SCHEDULER_JOBS WHERE OWNER ='OPS$ORACLE' AND JOB_NAME='CHK_SCHE_JOB';  
+
   FROM DBA_SCHEDULER_JOBS  
 +
WHERE OWNER ='DBCAFE'  
 +
  AND JOB_NAME='SCHD_JOB_DBCAFE';  
  
 
-- 작업 결과 확인
 
-- 작업 결과 확인
 
SELECT LOG_DATE, ACTUAL_START_DATE, JOB_NAME, STATUS  
 
SELECT LOG_DATE, ACTUAL_START_DATE, JOB_NAME, STATUS  
 
   FROM DBA_SCHEDULER_JOB_RUN_DETAILS  
 
   FROM DBA_SCHEDULER_JOB_RUN_DETAILS  
WHERE JOB_NAME ='CHK_SCHE_JOB';  
+
WHERE JOB_NAME ='SCHD_JOB_DBCAFE';  
  
 
-- 실제 결과 확인
 
-- 실제 결과 확인
275번째 줄: 386번째 줄:
 
--등록된 스케쥴러  
 
--등록된 스케쥴러  
 
SELECT * FROM DBA_SCHEDULER_SCHEDULES;
 
SELECT * FROM DBA_SCHEDULER_SCHEDULES;
 +
</source>
  
-- 스케쥴 삭제  
+
=== 스케쥴 삭제 ===
 +
<source lang=sql>
 
BEGIN
 
BEGIN
 
         DBMS_SCHEDULER.DROP_JOB(
 
         DBMS_SCHEDULER.DROP_JOB(
282번째 줄: 395번째 줄:
 
           FORCE      => false);
 
           FORCE      => false);
 
END ;  
 
END ;  
 +
</source>
  
-- 스케쥴 시작
+
<source lang=sql>
 +
 
 +
</source>
 +
 
 +
=== 스케쥴 시작 ===
 +
<source lang=sql>
 
EXECUTE DBMS_SCHEDULER.ENABLE('SCH_PROC_MSG_STATE');
 
EXECUTE DBMS_SCHEDULER.ENABLE('SCH_PROC_MSG_STATE');
 +
</source>
  
-- 스케쥴 정지
+
=== 스케쥴 정지 ===
 +
<source lang=sql>
 
EXECUTE DBMS_SCHEDULER.DISABLE('SCH_PROC_MSG_STATE');
 
EXECUTE DBMS_SCHEDULER.DISABLE('SCH_PROC_MSG_STATE');
 +
</source>
  
 +
=== 잡 관련 기타 프로시져  ===
 +
<source lang=sql>
 
DBMS_JOB.submit : job 등록
 
DBMS_JOB.submit : job 등록
 
DBMS_JOB.remove : 제거
 
DBMS_JOB.remove : 제거
296번째 줄: 420번째 줄:
 
DBMS_JOB.what : job 수행 으로 등록된 object 를 변경
 
DBMS_JOB.what : job 수행 으로 등록된 object 를 변경
 
DBMS_JOB.run : job을 수동으로 실행
 
DBMS_JOB.run : job을 수동으로 실행
</source>  
+
</source>
[등록 예제]
+
 
 +
=== [등록 예제2] ===
 
<source lang=sql>
 
<source lang=sql>
 
DECLARE
 
DECLARE
328번째 줄: 453번째 줄:
  
  
=== RAC에서 2번 노드에서만 실행 ===
+
=== RAC에서 2번 노드에서만 실행 예제 ===
 
<source lang=sql>
 
<source lang=sql>
 
   SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
 
   SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
336번째 줄: 461번째 줄:
 
</source>
 
</source>
  
[인터벌 설정법]
 
<source lang=sql>
 
Execute daily          'SYSDATE + 1'
 
Execute once per week  'SYSDATE + 7'
 
Execute hourly        'SYSDATE + 1/24'
 
Execute every 10 min.  'SYSDATE + 10/1440'
 
Execute every 30 sec.  'SYSDATE + 30/86400'
 
Do not re-execute      NULL
 
 
1. 10분간격으로 실행
 
 
SYSDATE + 1/24/6
 
 
2. 현재 시간으로 부터 다음 날 현재 시간에 실행 (매일)
 
 
SYSDATE + 1    -- 지금이 오후3시면 다음날 오후 3시 에 매일매일 실행됩니다.
 
 
3. 매일 새벽 5시
 
 
TRUNC(SYSDATE) + 1 + 5 / 24
 
 
4. 매일 밤 10시
 
 
TRUNC(SYSDATE)  + 20 / 24
 
</source>
 
  
 
[[Category:oracle]]
 
[[Category:oracle]]

2024년 7월 22일 (월) 18:48 판

thumb_up 추천메뉴 바로가기


1 오라클 JOB, SCHEDULES[편집]

  • ORACLE JOB과 ORACLE SCHEDULER ​가장 큰 차이점이라면 OS상의 crontab에 등재되는 shell프로그램도 ORACLE SCHEDULER에서 실행 가능

1.1 DBMS_JOB[편집]

- 특정 시간 및 간격으로 특정 작업을 수행

1.2 DBMS_SCHEDULER[편집]

  • 매우 복잡하고 정교한 수준의 스케줄 작업 가능
  • DBMS_SCHEDULER 의 장점
    - GUI(EM)을 통해서 손쉬운 관리 가능
    - 모듈화된 스케줄 오브젝트를 통해서 쉽게 공유. ( 프로그램, 스케줄, 잡 )
    - 모든 스케줄 활동이 기록.
    - TimeZone 지원.
    - 디비간 이동시 손쉽다(By DataPump)

1.2.1 프로그램(Program)[편집]

  1. 실행 가능한 프로그램(Program)을 말함
  2. DBMS_JOB 은 PL/SQL 블록, 저장 프로시저(Stored Procedure)만 가능
  3. DBMS_SCHEDULER는 외부 프로그램까지 사용 가능
    - ( PL/SQL 블록, 저장 프로시저(Stored Procedure), 실행 파일(Executable, Unix Shell, Windows 실행 파일) )
    - DBMS_SCHEDULER.CREATE_PROGRAM 프로시져를 통해 등록 가능하며 [ALL/DBA/USER]_SCHEDULER_PROGRAMS 뷰를 통해서 확인 가능
  4. 스케줄링에 의해서 실행 ( 프로그램 이름, 타입, Argument 갯수 등 )

1.2.2 스케줄(Schedule) - DBMS_SCHEDULER.CREATE_SCHEDULE[편집]

  1. 작업을 수행할 스케줄을 말함.
  2. 작업 시작 시간, 종료 시간, 간격 등을 지정.
  3. DBMS_JOB에 비해 유연함
    EX ) "FREQ=YEARLY; BYMONTH=4; BYMONTHDAY=15; BYHOUR=9; BYMINUTE=0; BYSECOND=0" -- 매년 4월 15일 9시에 작업 수행
  4. DBMS_SCHEDULER.CREATE_SCHEDULE 프로시져로 등록 가능
  5. [ALL/DBA/USER]_SCHEDULER_SCHEDULES 뷰를 통해서 확인 가능
  6. 구문 설명
    1. USING PL/SQL Expression
      예시) repeat_interval =>'sysdate+36/24'
    2. Using Calendar Expression
      예시 1) repeat_interval => 'FREQ=HOURLY;INTERVAL=4' ( Indiates a repeat interval of every four hours )
      예시 2) 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 )
notifications_active [인터벌 설정법]
Execute daily          'SYSDATE + 1'
 Execute once per week  'SYSDATE + 7'
 Execute hourly         'SYSDATE + 1/24'
 Execute every 10 min.  'SYSDATE + 10/1440'
 Execute every 30 sec.  'SYSDATE + 30/86400'
 Do not re-execute      NULL

1) 10분간격으로 실행

SYSDATE + 1/24/6

2) 현재 시간으로 부터 다음 날 현재 시간에 실행 (매일)

SYSDATE + 1    -- 지금이 오후3시면 다음날 오후 3시 에 매일매일 실행됩니다.

3) 매일 새벽 5시

TRUNC(SYSDATE) + 1 + 5 / 24

4) 매일 밤 10시

TRUNC(SYSDATE)  + 20 / 24

1.2.3 잡(Job) - DBMS_SCHEDULER.CREATE_JOB[편집]

  1. 주어진 프로그램과 스케줄에 따라 수행할 작업을 말함
  2. 명시적으로 생성된 프로그램(프로시져,함수등) 과 스케줄을 이용할 수도 있고, 작업을 생성하면 암묵적인 프로그램과 스케줄을 생성할 수도 있다.
  3. DBMS_SCHEDULER.CREATE_JOB 프로시져를 통해 등록 가능
  4. [ALL/DBA/USER]_SCHEDULER_JOBS 뷰를 통해 확인 가능
  5. 작업이 수행되면서 남는 로그 데이터는 [ALL/DBA/USER]_SCHEDULER_JOB_LOG 뷰나 [ALL/DBA/USER]_SCHEDULER_JOB_RUN_DETAILS 뷰를 통해 확인 가능

1.2.4 작업 클래스(Job Class)[편집]

  1. 작업의 공통 속성을 묶어서 만든 분류를 말한다.
  2. Resouce Consumer Group, Service, Logging Level, Log History 의 속성을 조합해서 하나의 클래스 생성 한다.
  3. Resource Consumer Group 은 DBMS_RESOURCE_MANGER 패키지를 통해서 생성,자원을 얼마나 사용 가능하게 할지를 지정
  4. Service는 작업이 특정 서비스에 대한 리소스 친화도(Resource Affinity)를 가지도록 지정
  5. Service는 RAC 에서 클러스터 내의 여러 노드를 묶은 논리적인 그룹
  6. Logging Level 은 작업 실행에 대한 로그 데이터의 레벨을 지정
  7. Log History 는 로그 데이터를 얼마나 저장할 지를 지정한다
  8. 같은 작업 클래스에 속하는 작업은 같은 속성을 공유하기 때문에 관리상의 편의점을 제공
  9. 하나의 JOB 은 하나의 JOB CLASS 에만 속함

1.2.5 윈도우(Window)[편집]

  1. 특정 리소스 플랜(Resoure Plan)을 적용하는 시간 단위를 의미
  2. 리소스 플랜은 오라클이 자원을 관리하는 단위로, 작업의 종류에 따라 CPU 등의 자원을 얼마나 부여할 지를 지정하는 역할
    - 윈도우를 지정하면 해당 윈도우 안에서 실행되는 작업은 윈도우 생성시 지정한 리소스 플랜을 사용하게 된다

1.2.6 체인(Chain )[편집]

  1. 프로그램의 집합을 의미
  2. 일련의 프로그램들을 순서대로 수행하고자 할 경우에 사용.

1.2.7 스케줄작업과 RAC Instance[편집]

  1. DBMS_JOB ==> 작업을 실행할 인스턴스 번호를 지정 // 한노드로 지정 시에 좀 더 편리
  2. DBMS_SCHEDULER => Instance_Stickness 라는 개념을 통해 좀 더 지능적으로 인스턴스를 할당
  3. INSTANCE_STICKSNESS = TRUE ( DBMS_SCHEDULER.SET_ATTRIBUTE ) 의미
    - 작업 수행 시 현재 가장 부하가 적은 인스턴스에 작업을 분배 한다.
    - 이후 작업 수행 시에는 가능한 최초에 지정된 인스턴스에서 작업을 수행하도록 한다.
    - 이 매커니즘을 일컬어 인스턴스 접착도라고 하며 리소스 친화도를 구현하는 방법
    - 최초에 지정된 인스턴스가 다운되거나, 부하가 심해서 작업을 수행할 수 없을 경우 다른 인스턴스에서 작업을 수행
    - 만일 INSTANCE_STICKNESS 속성 값이 FALSE 이면 오라클은 인스턴스 순서대로 작업을 수행한다.
    - DBMS_JOB 패키지를 이용해 작업을 수행하되 인스턴스 번호를 지정하지 않은 경우와 거의 같은 방식으로 작동한다.


1.3 오라클스케쥴러 등록을 위한 권한[편집]

GRANT CREATE ANY JOB TO 계정명;

1.4 명령어[편집]

  1. DBMS_SCHEDULER.CREATE_PROGRAM
    - JOB이 스케쥴러에 맞게 돌면서 실제로 동작하는 프로그램(외부의 shell이나 SP, PLSQL_BLOCK 등) 을 등
  2. DBMS_SCHEDULER.CREATE_SCHEDULER
    - 주기적으로 돌아갈 스케쥴을 등록
  3. DBMS_SCHEDULER.CREATE_JOB
    - 수행할 작업을 등록한다.

1.5 사용 방법[편집]

1.5.1 동작할 프로그램 등록[편집]

BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name => 'STATS_MAIN_BATCH_PROGRAM',
program_action => 'STATS_MAIN_BATCH',
program_type => 'STORED_PROCEDURE',
comments => 'Service desk stats main batch program',
enabled => TRUE);
END;

1.5.1.1 매개변수가 있는 경우[편집]

BEGIN
/*-------------------------------------------------------------------------------------------------------------------
program_name: 프로그램 이름
program_action: 실제 액션이 일어나는 SP(미리 등록되어있어야 한다). 여기서 shell 프로그램등을 돌릴 수도 있다.
program_type: SP 라고 명시
number-of_arguments: 사용할 인수 개수
comments: 코멘트.부가설명
enabled: 사용가능 설정
argument_position: 몇번째 인수인지
argument_name: 인수이름
argument_type: 인수타입
argument_value: 인수값
--------------------------------------------------------------------------------------------------------------------*/
   DBMS_SCHEDULER.CREATE_PROGRAM (
       PROGRAM_NAME => 'STATS_MAIN_BATCH_PROGRAM'
      ,PROGRAM_TYPE => 'STORED_PROCEDURE'
      ,PROGRAM_ACTION => 'STATS_MAIN_BATCH'
      ,NUMBER_OF_ARGUMENTS => 1
      ,ENABLED => FALSE
      ,COMMENTS => 'SERVICE DESK STATS MAIN BATCH PROGRAM');
      
   DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (
       PROGRAM_NAME => 'STATS_MAIN_BATCH_PROGRAM'
      ,ARGUMENT_POSITION => 1
      ,ARGUMENT_NAME => 'I_DT'
      ,ARGUMENT_TYPE => 'VARCHAR2'
      ,DEFAULT_VALUE => 'TO_CHAR(SYSDATE-1, ''YYYYMMDD'')'
    );
   DBMS_SCHEDULER.ENABLE(NAME => 'STATS_MAIN_BATCH_PROGRAM');
END;


1.5.2 스케줄 등록[편집]

/*-------------------------------------------------------------------------------------------------------------------
schedule_name : 스케쥴 이름
start_date: 스케쥴이 작동을 시작 할 시각. 입력한 시점부터 스케쥴러가 시작된다. AM 03시로 설정함
end_date: 스케쥴이 작동을 멈출 시간.
repeat_interval: 'FREQ=DAILY/DAILY/;INTERVAL=1; -- 매실행 '  참고) 매 1회만 시/분/초 실행 BYHOUR/BYMINUTE/BYSECOND=0;
comments: 
--------------------------------------------------------------------------------------------------------------------*/
BEGIN
  SYS.DBMS_SCHEDULER.CREATE_SCHEDULE
    (
      schedule_name    => 'RTIS_DBA.RTIS_TBL_DAILY_BKUP_SCHE'
     ,start_date       => TO_TIMESTAMP_TZ('2019/05/02 20:50:58.423332 +09:00','yyyy/mm/dd hh24:mi:ss.ff tzh:tzm')
     ,repeat_interval  => 'freq=daily;byhour=01;byminute=10;bysecond=0;'
     ,end_date         => NULL
     ,comments         => '매일 01:10 JOB 실행'
    );
END;
/

1.5.3 JOB 등록, 실제 수행 될 작업으로 스케쥴러와 프로그램 명시[편집]

BEGIN
/*-------------------------------------------------------------------------------------------------------------------
job_name: 작업이름
program_name: 구동 될 프로그램이름 명시. 위에서 등록한 프로그램이름을 적어준다.
schedule_name: 어떤 스케쥴러가 돌면서 이 작업을 수행 할 것인가. 위에 등록한 스케쥴러이름을 적어준다.
job_class: JOB을 Class 라는 단위로 그룹핑해서 관리한다. 많은 양의 스케쥴러 관리를 위해 추가 할 수 있다.
enabled: 사용가능 설정
comments: 코멘트.부가설명
--------------------------------------------------------------------------------------------------------------------*/
DBMS_SCHEDULER.CREATE_JOB (
job_name =>'STATS_MAIN_BATCH_JOB',
program_name =>'STATS_MAIN_BATCH_PROGRAM',
schedule_name =>'SCHEDULE_DAILY_AM_3_HOUR',
comments => 'Service desk stats main batch program',
--job_class =>'SCHEDULER_JOB_CLASS',
enabled =>TRUE);
END;

1.5.4 스케줄러 삭제[편집]

execute dbms_scheduler.drop_job('FRG_BALANCE_HIST_UPDATE_JOB',false); 
execute dbms_scheduler.drop_program('FRG_BALANCE_HIST_UPDATE_PRG',false);
execute dbms_scheduler.drop_schedule('SCHEDULE_30_MIN',false);
  • job먼저 지우고 program 삭제
  • program 먼저 지우려고 하면 종속된 객체라면서 안지워짐.
BEGIN
   DBMS_SCHEDULER.DROP_JOB(
        JOB_NAME   => 'STATS_MAIN_BATCH_JOB',
        FORCE      => FALSE);
END;


BEGIN
   DBMS_SCHEDULER.DROP_PROGRAM(
        PROGRAM_NAME   => 'STATS_MAIN_BATCH_PROGRAM',
        FORCE          => FALSE);
END;

1.5.5 스케줄러 등록/실행 정보 조회 뷰[편집]

SELECT * FROM DBA_SCHEDULER_JOBS; --등록된 job
SELECT * FROM DBA_SCHEDULER_JOB_ARGS; --job의 arguments
SELECT * FROM DBA_SCHEDULER_RUNNING_JOBS; --현재 running중인 job들의정보
SELECT * FROM DBA_SCHEDULER_JOB_LOG; --job의 log
SELECT * FROM DBA_SCHEDULER_JOB_RUN_DETAILS; --job의수행된정보및Error 정보
SELECT * FROM DBA_SCHEDULER_PROGRAMS; -- 등록된 Program
SELECT * FROM DBA_SCHEDULER_PROGRAM_ARGS; -- 프로그램의 매게변수
SELECT * FROM DBA_SCHEDULER_SCHEDULES; --등록된 스케쥴러

1.5.6 참고사항[편집]

  • JOB_CLASS 생성
# JOB_CLASS 설정
BEGIN
DBMS_SCHEDULER.CREATE_JOB_CLASS (
job_class_name =>'SCHEDULER_JOB_CLASS',
logging_level =>DBMS_SCHEDULER.LOGGING_FULL,
log_history =>1,
comments =>'SCHEDULER_JOB_CLASS');
END;
  • PROGRAM, SCHEDULE, JOB 세 개로 세분화하여 등록하는 형태.
  • 하지만 세개 모두 등록하지 않고 CREATE_JOB 한 개만 등록하여 사용하는 방법도 있다.
  • DBA_SCHEDULER_JOBS/USER_SCHEDULER_JOBS
select * from user_scheduler_jobs;
  • - CREATE_PROGRAM 에서 사용했던 program_type, program_action과 같이 job_type, job_action 컬럼 존재
    - CREATE_SCHEDULE에서 사용했던 start_date, end_date, repeat_interval이 존재.
  1. API

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sched.htm

1.6 스케줄 등록 예시[편집]

1.6.1 샘플 테이블 생성[편집]

  • 테이블 DBCAFE.CHECK_SCHEDULE 생성
CREATE TABLE CHECK_SCHEDULE ( 
                             INST_ID NUMBER, ACT_DATE DATE DEFAULT SYSDATE, ACT_DESC VARCHAR2(100)
                            ) ;

1.6.2 샘플 프로시져 생성[편집]

  • 프로시져 DBCAFE.SP_SCHD_TEST 생성
CREATE OR REPLACE PROCEDURE DBCAFE.SP_SCHD_TEST 
    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 ;

1.6.3 스케줄러 생성[편집]

  • 스케줄러 SCHD_DBCAFE 생성
EXEC DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name=>'SCHD_DBCAFE',repeat_interval=>'FREQ=MINUTELY'); -- 매분마다 실행

1.6.4 스케줄러 현재상태 확인[편집]

  • DBA_SCHEDULER_SCHEDULES
SELECT SCHEDULE_NAME, REPEAT_INTERVAL 
  FROM DBA_SCHEDULER_SCHEDULES 
 WHERE OWNER ='DBCAFE' 
   AND SCHEDULE_NAME='SCHD_DBCAFE';

1.6.5 프로그램 등록[편집]

EXEC DBMS_SCHEDULER.CREATE_PROGRAM(
     PROGRAM_NAME=>'SP_SCHD_PROG_DBCAFE'
   , PROGRAM_TYPE=>'STORED_PROCEDURE'
   , PROGRAM_ACTION=>'DO_SCHEDULE_PROG');

1.6.6 프로그램 Enable[편집]

EXEC DBMS_SCHEDULER.ENABLE('SP_SCHD_PROG_DBCAFE');

1.6.7 프로그램 등록 확인[편집]

SELECT PROGRAM_NAME, PROGRAM_ACTION, ENABLED 
  FROM DBA_SCHEDULER_PROGRAMS 
 WHERE OWNER ='DBCAFE' AND PROGRAM_NAME='SP_SCHD_PROG_DBCAFE';

1.6.8 잡 등록[편집]

EXEC DBMS_SCHEDULER.CREATE_JOB(
     JOB_NAME     => 'SCHD_JOB_DBCAFE' 
   , PROGRAM_NAME => 'SP_SCHD_PROG_DBCAFE' 
   , SCHEDULE_NAME=> 'SCHD_DBCAFE' 
   , AUTO_DROP    => FALSE   );

1.7 = 잡 Enable[편집]

-- 확인 필요 ???
-- EXEC DBMS_SCHEDULER.ENABLE('SCHD_JOB_DBCAFE');


1.7.1 스케줄러 실행 / 진행 사항 조회[편집]

-- 잡 등록/생성 확인

SELECT JOB_NAME, PROGRAM_NAME, SCHEDULE_NAME, ENABLED 
  FROM DBA_SCHEDULER_JOBS 
 WHERE OWNER ='DBCAFE' 
   AND JOB_NAME='SCHD_JOB_DBCAFE'; 

-- 작업 결과 확인
SELECT LOG_DATE, ACTUAL_START_DATE, JOB_NAME, STATUS 
  FROM DBA_SCHEDULER_JOB_RUN_DETAILS 
WHERE JOB_NAME ='SCHD_JOB_DBCAFE'; 

-- 실제 결과 확인
SELECT * FROM CHECK_SCHEDULE ; 

-- 등록된 job 확인 
SELECT * FROM DBA_SCHEDULER_JOBS;

-- job의 arguments
SELECT * FROM DBA_SCHEDULER_JOB_ARGS; 

--현재 running중인 job들의정보
SELECT * FROM DBA_SCHEDULER_RUNNING_JOBS;

--job의 log
SELECT * FROM DBA_SCHEDULER_JOB_LOG;

--job의수행된정보및Error 정보 
SELECT * FROM DBA_SCHEDULER_JOB_RUN_DETAILS;

-- 등록된 Program
SELECT * FROM DBA_SCHEDULER_PROGRAMS; 

-- 프로그램의 매개변수
SELECT * FROM DBA_SCHEDULER_PROGRAM_ARGS; 

--등록된 스케쥴러 
SELECT * FROM DBA_SCHEDULER_SCHEDULES;

1.7.2 스케쥴 삭제[편집]

BEGIN
        DBMS_SCHEDULER.DROP_JOB(
           JOB_NAME   => 'SCH_PROC_MSG_STATE',
           FORCE      => false);
END ;

1.7.3 스케쥴 시작[편집]

EXECUTE DBMS_SCHEDULER.ENABLE('SCH_PROC_MSG_STATE');

1.7.4 스케쥴 정지[편집]

EXECUTE DBMS_SCHEDULER.DISABLE('SCH_PROC_MSG_STATE');

1.7.5 잡 관련 기타 프로시져[편집]

DBMS_JOB.submit : job 등록
DBMS_JOB.remove : 제거
DBMS_JOB.change : 변경
DBMS_JOB.next_date : job의 다음 수행시간 변경
DBMS_JOB.interval : job의 실행 cycle 지정
DBMS_JOB.what : job 수행 으로 등록된 object 를 변경
DBMS_JOB.run : job을 수동으로 실행

1.7.6 [등록 예제2][편집]

DECLARE
  X NUMBER;
BEGIN
  SYS.DBMS_JOB.SUBMIT
    ( job       => X 
     ,what      => '실행할 object'
     ,next_date => to_date('17-11-2007 09:00:00','dd/mm/yyyy hh24:mi:ss')
     ,interval  => 'TRUNC(SYSDATE) + 1 + 9/24'
     ,no_parse  => TRUE
    );
  SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x)); -- 이부분은 job큐의 번호가 됩니다.
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
   job_name             => 'SCH_PROC_MSG_STATE_TO_DAY',
   job_type             => 'PLSQL_BLOCK',
   job_action           => 'BEGIN MEM_NPRO.TEST_PROC (TO_CHAR(SYSDATE , ''YYYYMMDD'')); END;',
   start_date           => TO_DATE('2011-12-14 17:30:00' , 'YYYY-MM-DD HH24:MI:SS'),
   repeat_interval      => 'FREQ=MINUTELY;INTERVAL=30',
   end_date             =>  NULL,
   enabled              =>  TRUE,
   comments             => 'HJ SCH_PROC_MSG_STATE_TO_DAY');
END;


1.7.7 RAC에서 2번 노드에서만 실행 예제[편집]

SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
    (  name      => 'RTIS_DBA.SCH_RTIS_SQL_GATHER'
     ,attribute  => 'INSTANCE_ID'
     ,value      => 2);