행위

오라클 스케줄러

DB CAFE

thumb_up 추천메뉴 바로가기


1 오라클 JOB, SCHEDULES[편집]

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

1.1 DBMS_JOB[편집]

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

1.2 DBMS_SCHEDULER[편집]

  • 매우 복잡하고 정교한 수준의 스케줄 작업 가능




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 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.6.9 잡 Enable[편집]

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


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

-- 잡 등록/생성 확인

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.6.11 스케쥴 삭제[편집]

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

1.6.12 스케쥴 시작[편집]

EXECUTE DBMS_SCHEDULER.ENABLE('SCH_PROC_MSG_STATE');

1.6.13 스케쥴 정지[편집]

EXECUTE DBMS_SCHEDULER.DISABLE('SCH_PROC_MSG_STATE');

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

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.6.15 [등록 예제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.6.16 RAC에서 2번 노드에서만 실행 예제[편집]

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