[Oracle] DBMS_SCHEDULER(job, program, schedule, window 등)

HYEOB KIM·2023년 7월 6일
1

Oracle

목록 보기
47/58

Architecture

각 항목 요약 설명

  • Program : 실행해야 할 소스
    • PL/SQL BLOCK
    • EXECUTABLE(Shell Script)
    • Stored Procedure(e.g. DBMS_STATS.gather_schema_stats)
  • Schedule : 실행 시간, 실행 주기를 정의
  • Job : 실행해야 할 소스(Program)를 실행 시간, 실행 주기(Schedule)를 설정해 주기적으로 실행하는 프로세스
  • Job Class : Job들의 집합
  • Resource Consumer Group : Resource 요구사항(CPU를 몇 % 사용할 것인지)이 유사한 User의 Group.
  • Resource Plan : Resource Consumer Group에 속한 Consumer Group들의 Resource 사용량을 정의
  • Resource Plan Directive : 이 프로시저를 통해 특정 Consumer Group의 Resource 사용량을 정의해서 Resource Plan에 등록
  • Window : 실행 시간, 실행 주기(Schedule)를 설정해 주기적으로 Resource Plan을 적용하는 프로세스
    • Job을 수행하는 Schedule과 맞춰주면 Job이 수행될 때 Resource Plan 적용 가능
  • Window Group : Window들의 집합

상세 설명

Program

: 실행해야 할 소스를 정의하는 것으로 program_type에 따라 PLSQL_BLOCK, EXECUTABLE(Shell Script), STORED_PROCEDURE(Oracle 내장 Procedure)가 있습니다.

  • program 생성(program_type 별)
BEGIN
  -- PL/SQL Block.
  DBMS_SCHEDULER.create_program (
    program_name   => 'test_plsql_block_prog',
    program_type   => 'PLSQL_BLOCK',
    program_action => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
    enabled        => TRUE,
    comments       => 'Program to gather SCOTT''s statistics using a PL/SQL block.');

  -- Shell Script.
  DBMS_SCHEDULER.create_program (
    program_name        => 'test_executable_prog',
    program_type        => 'EXECUTABLE',
    program_action      => '/u01/app/oracle/dba/gather_scott_stats.sh',
    number_of_arguments => 0,
    enabled             => TRUE,
    comments            => 'Program to gather SCOTT''s statistics us a shell script.');

  -- Stored Procedure with Arguments.
  DBMS_SCHEDULER.create_program (
    program_name        => 'test_stored_procedure_prog',
    program_type        => 'STORED_PROCEDURE',
    program_action      => 'DBMS_STATS.gather_schema_stats',
    number_of_arguments => 1,
    enabled             => FALSE,
    comments            => 'Program to gather SCOTT''s statistics using a stored procedure.');
END;
/

한편, STORED_PROCEDURE의 경우 실행하려는 프로시저가 argument를 요구하는 경우 define_program_argument 프로시저를 통해 해당 program에 넣어줄 수 있습니다.

BEGIN
  DBMS_SCHEDULER.define_program_argument (
    program_name      => 'test_stored_procedure_prog',
    argument_name     => 'ownname',
    argument_position => 1,
    argument_type     => 'VARCHAR2',
    default_value     => 'SCOTT');

  DBMS_SCHEDULER.enable (name => 'test_stored_procedure_prog');
END;
/
  • program 조회
-- program
set lines 300 pages 200
col owner for a15
col program_name for a30
col program_type for a30
col program_action for a50
col enabled for a10
col comments for a40

select owner, program_name, program_type, program_action, enabled, comments 
from dba_scheduler_programs;
  • program 삭제
BEGIN
  DBMS_SCHEDULER.drop_program (program_name => 'test_plsql_block_prog');
  DBMS_SCHEDULER.drop_program (program_name => 'test_stored_procedure_prog');
  DBMS_SCHEDULER.drop_program (program_name => 'test_executable_prog');
END;
/

Schedule

: start time, end time, 반복 주기를 정의합니다. 정의 후에 job, window에 적용할 수 있습니다.

  • schedule 생성
BEGIN
  DBMS_SCHEDULER.create_schedule (
    schedule_name   => 'test_hourly_schedule',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    comments        => 'Repeats hourly, on the hour, for ever.');
END;
/
  • schedule 조회
-- schedule
set lines 300 pages 200
col owner for a15
col schedule_name for a30
col start_date for a35
col repeat_interval for a35
col end_date for a35
col comments for a40

select owner, schedule_name, start_date, repeat_interval, end_date, comments 
from dba_scheduler_schedules;
  • schedule 삭제
BEGIN
  DBMS_SCHEDULER.drop_schedule (schedule_name => 'TEST_HOURLY_SCHEDULE');
END;
/

Job

: 소스 코드(PL/SQL, Shell Script)나 Oracle 내장 프로시저를 일정 주기로 실행하는 프로시저(Procedure)입니다.

  • Job 생성
    • Job을 생성할 때는 기존에 존재하는 program, schedule을 사용할 수도 있고, inline으로 직접 작성할 수도 있습니다.
BEGIN
  -- program 및 schedule을 인라인으로 모두 작성
  DBMS_SCHEDULER.create_job (
    job_name        => 'test_full_job_definition',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job defined entirely by the CREATE JOB procedure.');

  -- 기존 program, schedule을 적용
  DBMS_SCHEDULER.create_job (
    job_name      => 'test_prog_sched_job_definition',
    program_name  => 'test_plsql_block_prog',
    schedule_name => 'test_hourly_schedule',
    enabled       => TRUE,
    comments      => 'Job defined by an existing program and schedule.');

  -- 기존 program을 적용하고 schedule은 인라인으로 작성
  DBMS_SCHEDULER.create_job (
    job_name        => 'test_prog_job_definition',
    program_name    => 'test_plsql_block_prog',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job defined by existing program and inline schedule.');

  -- 기존 schedule을 적용하고 program은 인라인으로 작성
  DBMS_SCHEDULER.create_job (
     job_name      => 'test_sched_job_definition',
     schedule_name => 'test_hourly_schedule',
     job_type      => 'PLSQL_BLOCK',
     job_action    => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
     enabled       => TRUE,
     comments      => 'Job defined by existing schedule and inline program.');
END;
/
  • Job 조회

-- job
set lines 300 pages 200
col owner for a10
col job_name for a30
col job_class for a20
col enabled for a10
col SCHEDULE_OWNER for a20
col schedule_name for a30
col last_start_date for a35
col next_run_date for a35

select owner, job_name, job_class, enabled, schedule_owner, schedule_name, last_start_date, next_run_date
from dba_scheduler_jobs;
  • Job 시작 및 중지
BEGIN
  -- Run job synchronously.
  DBMS_SCHEDULER.run_job (job_name            => 'test_full_job_definition',
                          use_current_session => TRUE);

  -- Stop jobs.
  DBMS_SCHEDULER.stop_job (job_name => 'test_full_job_definition, test_prog_sched_job_definition');
END;
/
  • Job 삭제
BEGIN
  DBMS_SCHEDULER.drop_job (job_name => 'test_full_job_definition');
  DBMS_SCHEDULER.drop_job (job_name => 'test_prog_sched_job_definition');
  DBMS_SCHEDULER.drop_job (job_name => 'test_prog_job_definition');
  DBMS_SCHEDULER.drop_job (job_name => 'test_sched_job_definition');
END;
/

Job Class

: 관리의 편의성 및 비슷한 특징, Resource 요구사항을 가진 Job들을 모아놓은 그룹입니다.

  • Job Class 생성
BEGIN
  -- Job defined by an existing program and schedule and assigned to a job class.
  DBMS_SCHEDULER.create_job (
    job_name      => 'test_prog_sched_class_job_def',
    program_name  => 'test_plsql_block_prog',
    schedule_name => 'test_hourly_schedule',
    job_class     => 'test_job_class',
    enabled       => TRUE,
    comments      => 'Job defined by an existing program and schedule and assigned toa job class.');
END;
/
  • 기존에 존재하는 Job을 Job Class에 등록
BEGIN
  DBMS_SCHEDULER.set_attribute (
    name      => 'test_prog_sched_job_definition',
    attribute => 'job_class',
    value     => 'test_job_class');
END;
/
  • Job Class 조회
-- job class
set lines 300 pages 200
col job_class_name for a30
col resource_consumer_group for a30

select job_class_name, resource_consumer_group
from dba_scheduler_job_classes;
  • Resource Consumer Group 조회

Resource Consumer Group : Resource 요구사항이 유사한 User의 Group입니다. Resource Plan에서 Consumer Group 별로 Resource Plan Directive를 통해 사용할 CPU Level 및 CPU 제한 사용량, Lock waiting 시간 등을 설정해서 dbms_resource_manager.submit_pending_area()를 통해 적용할 수 있습니다.

Resource Manager에 대한 설명은 아래 참조
=> https://blog.naver.com/kimwlals/220720765171

-- resource consumer group
set lines 300 pages 200
col consumer_group for a30

select consumer_group 
from dba_rsrc_consumer_groups;
  • Job Class 삭제
BEGIN
  DBMS_SCHEDULER.drop_job_class (
    job_class_name => 'test_job_class',
    force          => TRUE);
END;
/

Window

: Resource Plan을 일정 주기로 실행하는 프로시저입니다. 특정 기간 동안 Job Class 및 해당 작업에 할당된 Resource를 제어할 수 있습니다.

  • 한 번에 한 개의 Window만 Active(Open) 될 수 있습니다.

  • Window 생성

BEGIN
  -- Window with a predefined schedule.
  DBMS_SCHEDULER.create_window (
    window_name     => 'test_window_1',
    resource_plan   => NULL,
    schedule_name   => 'test_hourly_schedule',
    duration        => INTERVAL '60' MINUTE,
    window_priority => 'LOW',
    comments        => 'Window with a predefined schedule.');

  -- Window with an inline schedule.
  DBMS_SCHEDULER.create_window (
    window_name     => 'test_window_2',
    resource_plan   => NULL,
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=hourly; byminute=0',
    end_date        => NULL,
    duration        => INTERVAL '60' MINUTE,
    window_priority => 'LOW',
    comments        => 'Window with an inline schedule.');
END;
/
  • Window 조회
-- window
set lines 300 pages 200

select window_name, resource_plan, enabled, active 
from dba_scheduler_windows;
  • 수동으로 Window open/close
BEGIN
  -- Open window.
  DBMS_SCHEDULER.open_window (
   window_name => 'test_window_2',
   duration    => INTERVAL '1' MINUTE,
   force       => TRUE);
END;
/

BEGIN
  -- Close window.
  DBMS_SCHEDULER.close_window (
   window_name => 'test_window_2');
END;
/
  • Window 삭제
BEGIN
  DBMS_SCHEDULER.drop_window (
    window_name => 'test_window_1',
    force       => TRUE);

  DBMS_SCHEDULER.drop_window (
    window_name => 'test_window_2',
    force       => TRUE);
END;
/

Window Group

  • Window Group 생성
BEGIN
  DBMS_SCHEDULER.create_window_group (
    group_name  => 'test_window_group',
    window_list => 'test_window_1, test_window_2',
    comments    => 'A test window group');
END;
/
  • Window Group 조회
-- window group
set lines 300 pages 200
col window_group_name for a30
col window_name for a30

select window_group_name, window_name 
from dba_scheduler_wingroup_members;
  • 기존에 존재하는 Window를 Window Group에 등록
BEGIN
  DBMS_SCHEDULER.add_window_group_member (
    group_name  => 'test_window_group',
    window_list => 'test_window_3');
END;
/

BEGIN
  DBMS_SCHEDULER.remove_window_group_member (
    group_name  => 'test_window_group',
    window_list => 'test_window_3');
END;
/
  • Window Group 삭제
BEGIN
  DBMS_SCHEDULER.drop_window_group (
    group_name => 'test_window_group',
    force      => TRUE);
END;
/

참고

profile
Devops Engineer

0개의 댓글