轻量级作业:
也称为持久性轻量级作业,如果当我们的数据库每秒钟需要创建、删除或修改数十个或数百个作业时,使用轻量级作业是降低开销的最佳方法常规作业:是由oracle 11g Scheduler 所支持的作业,常规作业需要很多的系统开销,因为他们必须由Scheduler创建且每次执行完由Scheduler删除,常规作业提供了使用诸如其它用户程序的优点,并且提供了对运行此作业的权限细粒度控制轻量级作业有别于常规作业的特征如下: 1.轻量级作业不是数据库对象,不会产生创建或删除轻量级作业时多引起的开销 2.与普通作业相比,创建和删除轻量级作业的时间少的很多; 3.轻量级作业的作业元数据和运行时数据占用的磁盘空间很少; 4.由于占用的磁盘空间少,可以再RAC环境中平衡轻量级作业的负载;轻量级作业有几个缺点: 1.无法设置轻量级作业的权限,作业的权限从模板的计划继承而来 2.由于轻量级作业使用模板,无法创建完全独立的轻量级作业,我们必须使用PL/SQL命令创建轻量级作业,而无法用过EM创建创建轻量级作业:我们可以使用DBMS_SCHEDULER.CREATE_PROGRAM创建与轻量级作业一起使用的模板,供轻量级作业的模板存储为PLSQL_BLOCK或STORED_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'truncateinto table tfields terminated by ','trailing nullcols(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)vi /u01/load.sh
#!/bin/bash
export ORACLE_BASE=/u01/app/oracleexport ORACLE_HOME=$ORACLE_BASE/product/11.2/db_1export 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.txtselect
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/tigerdeclare
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