• OCP读书笔记(17)


    轻量级作业:
    也称为持久性轻量级作业,如果当我们的数据库每秒钟需要创建、删除或修改数十个或数百个作业时,使用轻量级作业是降低开销的最佳方法

    常规作业:
    是由oracle 11g Scheduler 所支持的作业,常规作业需要很多的系统开销,因为他们必须由Scheduler创建且每次执行完由Scheduler删除,常规作业提供了使用诸如其它用户程序的优点,并且提供了对运行此作业的权限细粒度控制

    轻量级作业有别于常规作业的特征如下:
    1.轻量级作业不是数据库对象,不会产生创建或删除轻量级作业时多引起的开销
    2.与普通作业相比,创建和删除轻量级作业的时间少的很多;
    3.轻量级作业的作业元数据和运行时数据占用的磁盘空间很少;
    4.由于占用的磁盘空间少,可以再RAC环境中平衡轻量级作业的负载;

    轻量级作业有几个缺点:
    1.无法设置轻量级作业的权限,作业的权限从模板的计划继承而来
    2.由于轻量级作业使用模板,无法创建完全独立的轻量级作业,我们必须使用PL/SQL命令创建轻量级作业,而无法用过EM创建

    创建轻量级作业:
    我们可以使用DBMS_SCHEDULER.CREATE_PROGRAM创建与轻量级作业一起使用的模板,供轻量级作业的模板存储为PLSQL_BLOCKSTORED_PROCEDURE类型的计划,创建轻量级作业时,指定LIGHEWERGHT的JOB_STYLE。JOB_STYLE的默认值是REGULAR

    例:

    grant execute on dbms_scheduler to scott;
    create table d as select * from dept;

    创建一个调度MY_SCHED:

    BEGIN
      dbms_scheduler.create_schedule(
        repeat_interval => 'FREQ=MINUTELY',
        start_date => systimestamp at time zone 'Asia/Shanghai',
        schedule_name => '"SCOTT"."MY_SCHED"'
      );
    END;
    /

    创建一个程序MY_PROG:

    BEGIN
      dbms_scheduler.create_program(
        program_name=>'"SCOTT"."MY_PROG"',
        program_action=>'begin
          insert into d select * from d;
          commit;
        end;',
        program_type=>'PLSQL_BLOCK',
        number_of_arguments=>0,
        comments=>'',
        enabled=>TRUE
      );
    END;
    /

    创建一个轻量级作业my_lightweight_job2:

    BEGIN
      dbms_scheduler.create_job(
        job_name => 'my_lightweight_job2',
        program_name => 'MY_PROG',
        schedule_name => 'MY_SCHED',
        enabled=>true,
        job_style => 'LIGHTWEIGHT'
      );
    END;
    /

    select * from d;

    删除一个轻量级作业:
    BEGIN
      dbms_scheduler.drop_job(
        job_name => 'my_lightweight_job2'
      );
    END;
    /

    基于时间的调度

    conn hr/hr
    create table job_test(sdate date);

    创建程序

    BEGIN
      dbms_scheduler.create_program(
        program_name=>'HR.insert_sysdate',
        program_action=>'insert into job_test values(sysdate);',
        program_type=>'PLSQL_BLOCK',
        number_of_arguments=>0,
        comments=>'',
        enabled=>TRUE
      );
    END;

    创建调度

    BEGIN
      dbms_scheduler.create_schedule(
        repeat_interval => 'FREQ=SECONDLY',
        start_date => systimestamp at time zone '+8:00',
        schedule_name => '"HR"."INSERT_SCHE"'
      );
    END;

    创建作业

    BEGIN
      dbms_scheduler.create_job(
        job_name => '"HR"."INSERT_JOB"',
        program_name => 'HR.INSERT_SYSDATE',
        schedule_name => 'HR.INSERT_SCHE',
        job_class => 'DEFAULT_JOB_CLASS',
        auto_drop => FALSE,
        enabled => TRUE
      );
    END;

    查看结果

    conn hr/hr
    select * from job_test;

    监视作业

    select job_name, status, error#, run_duration from user_scheduler_job_run_details

    删除作业

    begin
      dbms_scheduler.drop_job(job_name => '"HR"."INSERT_JOB"', force => true);
    end;

    基于事件的调度

    创建测试用表

    conn hr/hr
    create table event_job_test(id number, createdatae date);
    alter table event_job_test add constraint pk_event_job_test primary key(id);
    create sequence seq_event_job_test;

    创建一个类型:

    create or replace type t_event_queue as object(object_owner varchar2(50), event_name varchar2(50));

    创建一个队列表,该队列包含的字段就是我们刚才创建的类型t_event_queue所包含的属性。

    conn /as sysdba
    grant execute on dbms_aqadm to hr;

    conn hr/hr

    begin
      dbms_aqadm.create_queue_table(
        queue_table=>'event_queue_tab',
        queue_payload_type=>'t_event_queue',
        multiple_consumers=>true
      );
    end;
    /

    创建一个队列,并将该队列与前面创建的队列表关联

    begin
      dbms_aqadm.create_queue(
        queue_name=>'event_queue',
        queue_table=>'event_queue_tab'
      );
    end;
    /

    启动队列

    begin
      dbms_aqadm.start_queue(queue_name=>'event_queue');
    end;
    /

    创建一个基于事件的任务

    conn /as sysdba

    BEGIN
      dbms_scheduler.create_job(
        job_name => '"HR"."EVENT_BASE_JOB"',
        job_type => 'PLSQL_BLOCK',
        job_action => 'begin
          insert into hr.event_job_test values(seq_event_job_test.nextval, sysdate);
          commit;
        end;',
        event_condition => 'tab.user_data.object_owner=''HR'' and        tab.user_data.event_name=''give_me_an_event''',
        queue_spec => 'HR.EVENT_QUEUE',
        start_date => systimestamp at time zone '+8:00',
        job_class => 'DEFAULT_JOB_CLASS',
        auto_drop => FALSE,
        enabled => TRUE
      );
    END;

    向队列中插入消息

    没插入之前,查询表,发现没数据。

    conn hr/hr
    select * from event_job_test;

    向队列里插入消息

    conn /as sysdba
    grant execute on dbms_aq to hr;

    conn hr/hr

    declare
      l_enqueue_options dbms_aq.enqueue_options_t;
      l_message_properties dbms_aq.message_properties_t;
      l_message_handle raw(16);
      l_queue_msg t_event_queue;
    begin
      l_queue_msg := t_event_queue('HR','give_me_an_event');
      dbms_aq.enqueue(
        queue_name=>'event_queue',
        enqueue_options=>l_enqueue_options,
        message_properties=>l_message_properties,
        payload=>l_queue_msg,
        msgid=>l_message_handle
      );
      commit;
    end;

    select * from event_job_test;

    删除作业:

    begin
      dbms_scheduler.drop_job(job_name => '"HR"."EVENT_BASE_JOB"',  force => true);
    end;

    ---------------------------------------------------------------------------------------------------------------------------------------------

    创建基于事件的调度加载数据

    创建测试用表

    conn scott/tiger

    create table t as select * from emp where 1=2;

    vi /u01/load.ctl

    load data
    infile '/u01/data.txt'
    badfile '/u01/bad.emp'
    discardfile '/u01/discadr.emp'
    truncate
    into table t
    fields terminated by ','
    trailing nullcols
    (EMPNO,
    ENAME,
    JOB,
    MGR,
    HIREDATE,
    SAL,
    COMM,
    DEPTNO)

    vi /u01/load.sh

    #!/bin/bash
    export ORACLE_BASE=/u01/app/oracle
    export ORACLE_HOME=$ORACLE_BASE/product/11.2/db_1
    export ORACLE_SID=orcl
    $ORACLE_HOME/bin/sqlldr scott/tiger control=/u01/load.ctl log=/u01/load.log

    保存退出

    chmod +x /u01/load.sh

    将emp中的数据转储到/u01/data.txt中:

    set trims on
    spool /u01/data.txt

    select
    EMPNO||','||
    ENAME||','||
    JOB||','||
    MGR||','||
    HIREDATE||','||
    SAL||','||
    COMM||','||
    DEPTNO from emp;

    spool off

    创建一个类型:

    sqlplus scott/tiger

    create or replace type t_event_queue as object
    (
    object_owner varchar2(10),
    object_name varchar2(20),
    event_type varchar2(20),
    event_timestamp number(2)
    );
    /

    创建一个队列表,该队列包含的字段就是我们刚才创建的类型t_event_queue所包含的属性。

    conn /as sysdba

    grant execute on dbms_aqadm to scott;

    conn scott/tiger

    begin
    dbms_aqadm.create_queue_table(
    queue_table=>'event_queue_tab',
    queue_payload_type=>'t_event_queue',
    multiple_consumers=>true);
    end;
    /

    创建一个队列,并将该队列与前面创建的队列表关联

    begin
    dbms_aqadm.create_queue(
    queue_name=>'event_queue',
    queue_table=>'event_queue_tab');
    end;
    /

    启动队列

    begin
    dbms_aqadm.start_queue(queue_name=>'event_queue');
    end;
    /

    创建一个基于事件的任务

    conn /as sysdba

    BEGIN
    sys.dbms_scheduler.create_job(job_name => '"SYS"."PERFORM_DATA_LOAD"', --属主必须是sys
    job_type => 'EXECUTABLE',
    job_action => '/u01/load.sh',
    event_condition => 'tab.user_data.object_owner = ''SCOTT''
    and tab.user_data.object_name = ''DATA.TXT''
    and tab.user_data.event_type = ''FILE_ARRIVAL''
    and tab.user_data.event_timestamp < 9',--创建一个作业,如果成批装入的数据文件在上午 9:00 之前到达文件系统,则运行此作业
    queue_spec => 'SCOTT.EVENT_QUEUE',
    start_date => systimestamp at time zone
    '+8:00',
    job_class => 'DEFAULT_JOB_CLASS',
    auto_drop => FALSE,
    enabled => TRUE);
    END;

    /

    向队列中插入消息

    conn scott/tiger

    select * from t;

    向队列里插入消息

    conn /as sysdba
    grant execute on dbms_aq to scott;
    conn scott/tiger

    declare
    l_enqueue_options dbms_aq.enqueue_options_t;
    l_message_properties dbms_aq.message_properties_t;
    l_message_handle raw(16);
    l_queue_msg t_event_queue;
    begin
    l_queue_msg := t_event_queue('SCOTT', 'DATA.TXT', 'FILE_ARRIVAL',8);
    dbms_aq.enqueue(queue_name => 'event_queue',
    enqueue_options => l_enqueue_options,
    message_properties => l_message_properties,
    payload => l_queue_msg,
    msgid => l_message_handle);
    commit;
    end;

    /

    select * from t;

    删除作业:

    conn /as sysdba

    begin
    dbms_scheduler.drop_job(job_name => '"SYS"."PERFORM_DATA_LOAD"', force => true);
    end;
    /

    总结一下oracle db里用job调度shell的注意点:

    1、shell脚本里开头要加#!/bin/bash等指定使用的shell类型
    2、所有相关环境变量都得在shell里明确指定
    3、如果要写入文件必需使用绝对路径
    4、使用sys用户建立job

  • 相关阅读:
    CSS div 塌陷问题
    jquery 选择器包含特殊字符
    ASP.NET Core Action 读取流
    SQL 列拼接使用
    bootstrap div 固定
    Jquery 操作HTML5自定义属性data-*
    Vue 页面加载闪现代码问题
    iframe 加载完成事件
    closest
    【开发者的精进】 数据驱动下的程序设计
  • 原文地址:https://www.cnblogs.com/thlzhf/p/3385678.html
Copyright © 2020-2023  润新知