Oracle 自动任务调度

13.1 Oracle任务调度概述

在Oracle中任务调度指某一(组)执行程序在特定的时间被周期性的执行。Oracle把任务调度称为job(作业)。

Advanced Scheduler Concepts:(PPT-II-450)

13.2 理解以下概念:

1) Advanced SCHEDULER下的jobs

JOB翻译为作业,一个基本的JOB由两方面组成:program和schedule。JOB总体上可分为两大类,基于时间的JOB和基于事件的JOB。
在Oracle 10g之前,采用dbms_job程序包来完成任务调度的相关工作。在Oracle 10g之后,Oracle推出了功能更加强大的
dbms_scheduler来完成作业调度工作。

*考点:必须将JOB_QUEUE_PROCESSES 实例参数设置为>0的值,否则调度程序将无法运行,默认值为1000。如果有任何定义的、
活动的作业,那么总是运行作业队列协调器(后台进程cjq0)。

SQL> show parameter job_queue_processes

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
job_queue_processes integer 1000

SQL> select program from v$process where program like '%J%';

PROGRAM
------------------------------------------------
oracle@timran.localdomain (J000) //术语:job slave即job工作者,根据参数可以有1000个
oracle@timran.localdomain (CJQ0) //术语:Job Coordinator即job协调员

2) Advanced SCHEDULER下的program

Program指的是运行的程序。包括具体的要操作的执行代码,可选的是三种类型:

PL/SQL BLOCK : 标准的pl/sql代码块;
STORED PROCEDURE : 编译好的PL/SQL存储过程,或者Java存储过程,以及外部的c子程序;
EXECUTEABLE : ORACLE数据库之外的应用,比如操作系统命令等等。

3) Advanced SCHEDULER下的schedule

Scheduler有的资料翻译为调度,有的翻译成时间表,简单来说指的就是作业运行周期,即时间和频率。

总结一下:如果不考虑与资源计划的结合,Schedules(调度);Programs(程序);Jobs(任务)这三者之间到底是个什么关系?直白地来说
就是:program负责具体做什么(左膀),schedule负责什么时候做(右臂),job就简单了(联手左膀右臂)。11g的SCHEDULER提供了六种
建立Job的存储过程,可以将program、schedule、job分立创建,也可以混合创建,相互组合非常灵活。

浏览一下dbms_scheduler中的内容。

SQL> spool /tmp/sch.txt
SQL> desc dbms_scheduler
SQL> spool off
$more /tem/sch.txt

4)JOB CLASSES

相当于创建了一个job组,可以将那些具有相同特性的job,统统放到一个Job Classes中,在Job Classes中的Jobs可以指派优先级(1-5),
,默认优先级是3,而1的优先级最高,然后让Job Classes与资源计划器结合进行管理。

5)WINDOW

窗口指定了作业运行的起始时间(START DATE)、终止时间(END DATE),运行时间(DURATION),以及重复间隔(REPEAT INTERVAL)等,
它实际上扩展了SCHEDULER(时间表)的概念,所谓扩展是指窗口可以激活资源管理计划,当窗口打开时,数据库自动切换到相关的
resource plan上,此时这个resource plan便处于活动状态(ACTIVE)。

窗口对于job class也有着特殊的意义,通过job class和resource plan联系,这就使窗口下被激活的resource plan中所关联的job class中
的所有job被激活了,这些job会根据优先权调度运行。

6)JOB CHAIN

CHAIN可以被视做一组Programs的组合,举个简单的例子:运行PROGRAM:A以及PROGRAM:B,如果成功的话继续运行PROGRAM:C,
否则的话运行PROGRAM:D。Programs:A、B、C、D以及执行的逻辑关系就构成了一个最简单的CHAIN。

7)轻型作业

轻型作业不显示在DBA_SCHEDULER_JOBS视图中,因为轻型作业不是模式对象,与普通作业相比创建和删除轻型作业的开销非常小。
使用轻型作业有两种情形:1)作业成百上千次的批量执行,2)单个作业运行时间较短。

DBMS_SCHEDULER程序包可以使用最少的语法来创建轻量作业。轻量作业只有很少的参数可以指定:作业参数和计划。作业的其余
元数据(包括权限)都是从作业模板继承来的。轻量作业的模板必须是PL/SQL 块或存储过程。轻量作业必须使用DBMS_SCHEDULER
程序包在PL/SQL 中创建。JOB_STYLE参数在EM 中是不可见的。

例1,指定时间和频率的
dbms_scheduler.create_job(
job_name =>'test_ltwtjob1',
program_name =>'test_prog',
repeat_interval =>'freq=hourly',
end_date =>to_timestamp(sysdate+1),
job_style =>'lightweight',

例2,使用预定义计划
dbms_scheduler.create_job(
job_name =>'test_ltwtjob1',
program_name =>'test_prog',
shedule_name =>'test_sched'
job_style =>'lightweight',

以上两种方法,轻型作业的名字叫TEST_LTWTJOB1,程序test_prog就是它的模板,(这个模板就是指program_name是一个单独的模块),
job_style是轻型作业的关键字。

建立单一的轻型作业也许意义不大,另一种方法是通过PL/SQL块一次执行几百个轻量级作业的数组。

考点:轻型作业的指定的程序类型只能是PLSQL_BLOCK或者STORED_PROCEDURE。

8)基于事件(Event)的作业

SCHEDULER中有两种触发EVENT的情况:

Scheduler触发的Events

Scheduler 中触发的Events,一般是说当前schduler 中job 的状态发生修改,类似job 启动,或者运行结束,或者达到运行时间
等诸如此类的动作,都能够抛出一个EVENT,接收到EVENT 的application 就可以根据这些信息进行适当的处理。

Application触发的Events

外部的应用也可以触发Events,并且由Scheduler来接收并处理这一类型的Events。所谓Scheduler 处理EVENT 就是指Scheduler
启动相应的job来执行相关操作,这类job在创建时专门声明了event 的处理,这样当接收到EVENT 时,这类job就会启动。

建立和管理基于事件(Event)的作业的方法超出了OCP考试范畴,这里就不多说了。

13.3 例:

下面通过实例来演示,如何创建program、schedule、job,以便能初步理解三者间的关系。

我们使用分立创建三者的方法,先建一个测试表

SQL> create table scott.job_test1(my_date date);

第一步,创建一个名叫my_pro1的program,(带PL/SQL BLOCK)操作如下:

BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
program_name =>'my_pro1',
program_action =>'begin
insert into scott.job_test1 values(sysdate);
commit;
end;',
program_type =>'PLSQL_BLOCK',
number_of_arguments =>0,
comments =>'insert sysdate into table',
enabled =>TRUE);
END;
/

PL/SQL procedure successfully completed.
  
通过上述语句,我们定义了一个program,类型是一个oracle匿名块,其动作是将输入sysdate插入到scott.job_test中。

前三个属性是不可以省略的,它们没有缺省值,必须指定,属性number_of_arguments是指定支持的参数个数,默认为0,
最多255,这里又置为0,强调此参数为0,因为program_type是PLSQL_BLOCK。要为progremm 添加参数需要使用
DEFINE_PROGRAM_ARGUMENT存储过程。

第二步:我们建立一个schedule,规定开始program的操作时间,及操作频率。这里定义了20秒执行一次。

BEGIN
dbms_scheduler.create_schedule(
repeat_interval => 'FREQ=SECONDLY;INTERVAL=20',
start_date => sysdate,
comments => 'Start Every 20 seconds',
schedule_name => 'my_sch1');
END;
/

此处REPEAT_INTERVAL参数的语法结构比较复杂。其中最重要的是FREQ和INTERVAL 两个关键字。

FREQ 关键字用来指定间隔的时间周期,可选参数有:YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, and SECONDLY,
分别表示年、月、周、日、时、分、秒等单位。

INTERVAL 关键字用来指定间隔的频繁,可指定的值的范围从1-99。

本例'FREQ=SECONDLY;INTERVAL=30表示每30秒钟执行一次,如果是'FREQ=DAILY;INTERVAL=1';就表示每天执行一次,

第三步:创建job,按照指定的schedule,执行program,创建job时,start_date,repeat_interval,job_action等均无须指定,因为这些参数
将由program和schedule来控制。操作如下:

BEGIN
dbms_scheduler.create_job(
job_name => 'my_job1',
program_name => 'my_pro1',
schedule_name => 'my_sch1',
comments => 'insert sysdate into table',
enabled => TRUE);
END;
/

这样,操作完成后,ORACLE就会自动定时(当前设置为30秒执行一次)program中定义的操作。

检查结果:

SQL> select * from scott.job_test1;

MY_DATE
-------------------
2012-11-22 15:56:13
2012-11-22 15:56:43
2012-11-22 15:57:13
......

可以通过一些视图查看JOB状态

DBA_SCHEDULER_JOBS
DBA_SCHEDULER_RUNNING_JOBS; //这两个都是查看当前job运行状态的(考点)
DBA_SCHEDULER_JOB_LOG
DBA_SCHEDULER_JOB_RUN_DETAILS

例如,查看刚刚创建的"MY_JOB1"任务的执行情况的细节,执行命令如下:

SQL>select log_id, log_date, status, additional_info from user_scheduler_job_run_details where job_name = 'MY_JOB1';

除了作业按照时间表自动运行,你也可以手工干预它们,举几个例子:

使能作业:
SQL> exec dbms_scheduler.enable('my_job1');
禁用作业:
SQL> exec dbms_scheduler.disable('my_job1');
删除作业:
SQL> exec dbms_scheduler.drop_job('my_job1');
运行作业:
SQL> exec dbms_scheduler.run_job('my_job1');
停止作业:
SQL> exec dbms_scheduler.stop_job('my_job1');

等等,很多类似的存储过程...

从管理角度看,你能创建JOB,也应该能修改JOB,即修改JOB的属性,由于JOB属性众多,Oracle把这部分工作独立出来作为一个
存储过程,这就是DBMS_SCHEDULER.set_attribute, 此过程可以修改JOB属性,这里仅举几个(也是考点):

1)JOB_TYPE:指定job执行的任务的类型

有四个可选值:'PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE', and 'CHAIN'。

2)JOB_ACTION:指定job 执行的任务.这一参数所指定的值依赖于JOB_TYPE 参数中的值, 比如说JOB_TYPE设置为 'STORED_PROCEDURE',
那么本参数值中指定的可以是ORACLE 中的过程名。

3)LOGGING_LEVEL:指定对jobs 执行情况记录的日志信息级别。

SCHEDULER 管理的JOB 对任务的执行情况专门进行了记录,同时用户还可以选择日志中记录信息的级别,有下列三种选择:

DBMS_SCHEDULER.LOGGING_OFF:关闭日志记录功能;
DBMS_SCHEDULER.LOGGING_RUNS:对任务的运行信息进行记录;
DBMS_SCHEDULER.LOGGING_FULL:记录任务所有相关信息,不仅有任务的运行情况,甚至连任务的创建、修改等也均将记入日志。

4)AUTO_DROP:当为TRUE时,一旦job到达停止运行的时间,该job就会被自动删除,否则的话job仍然存在,不过状态被修改为COMPLETED。

5)RESTARTABLE:指定jobs运行出错后,能否适时重启,该参数默认情况下设置为FALSE,如果设置为TRUE,就表示当任务运行时出错,
下次运行时间点到达时仍会启动,并且如果运行仍然出错,会再重复,连接出错达到6次,该job 就会停止。

13.5 Job Class(类)和 Window(窗口)

job class包含着一组有相同特性的job, 而window是一个时间段,当系统时间进入到窗口时间段,则窗口打开,作业运行。

它们和资源计划的关联是个难点:一个job是怎样和资源计划联系起来的?

看图(PPT-II-452),通过两条线路将JOB和资源计划关联起来的,需要理解的是:

第一条线路:
创建一个job class,将该Job class绑定某个资源用户组,则这个Job_Class将服从该用户组的资源分配计划。

创建job,再通过set_attribute过程赋予相对优先权(1-5), 然后将job加入Job Class后,会根据设定的优先值从1-5顺序执行的,1首先被执行,默认是3。

第二条线路:
建立window时必须绑定一个resource plan,当系统时间进入window后,便激活了该resource plan。Window也可以设置优先权(high和low)

window的优先级的作用是:在窗口重叠的情况下如何选择哪个窗口打开,假定有两个窗口,设置为同一时间
打开则优先级为high的会打开,如果是同样的优先级,window时间长的打开,如果优先级相同,window时间长度也相同,
怎么办?则两个window都不打开,返还给原来活动的window。

window和schedule功能上相似,但Oracle设计让window和resource plan绑定,以便可以完成不同的resource plan的自动切换。

查看哪个窗口是活动的以及哪个资源计划与该窗口相关联,可以使用DBA_SCHEDULER_WINDOWS视图。

SQL>SELECT window_name,resource_plan,enabled,active FROM DBA_SCHEDULER_WINDOWS;

例;Job Class和Window在Scheduler框架内的作用

接续刚才的例子,把两条线路完成:

4)使用EM建立一个Job Class,名叫My_Class,将之前的MY_JOB1加入到My_Class(MY_JOB1默认加入的是DEFAULT_JOB_CLASS),再将My_Class关联OLTP组。

5)建立一个叫DAY_WIN的窗口,该窗口将激活DAYTIME计划

BEGIN
DBMS_SCHEDULER.CREATE_WINDOW(
window_name=>'"DAY_WIN"',
resource_plan=>'DAYTIME',
start_date=>systimestamp at time zone 'Asia/Shanghai',
duration=>numtodsinterval(1, 'minute'),
repeat_interval=>'FREQ=MINUTELY;INTERVAL=2',
end_date=>null,
window_priority=>'HIGH',
comments=>'');
END;
/

这将立即打开DAY_WIN窗口,每隔2分钟将再次打开该窗口,每次激活DAYTIME计划,duration的含义是打开窗口的持续时间。这里的1分钟是窗口Active状态为true可以持续1分钟。
| 2分钟 | 2分钟 |...
窗口再次打开间隔2分钟 |--------------- |---------------|...
窗口持续打开时间1分钟 |Active | 关闭 |Active| 关闭 |...

也就是说:当repeat_interval(间隔)>duration(持续时间)才有意义,Oracle不检查这两个时间单位的逻辑关系。

至此,一个job关联一个resource_plan的框架已经搭建起来了,4)和5)两条线路需要联动配合,实为关键。

6)改一下MY_JOB1的时间表,原来它关联MY_SCH1这个Schedule,现在让它关联DAY_WIN这个window,

即EDIT(MY_JOB1)-->Schedul Type-->Use_Pre_Define_Window-->DAY_WIN

改一下MY_JOB1的JOB CLASS,原来它关联DEFAULT_JOB_CLASS,现在让它关联MY_CLASS

测试一下:

SQL> alter system set resource_manager_plan=''; //关闭资源计划,现在没有资源计划激活。

SQL> select * from scott.job_test1;

可以看到原来是每半分钟插入一条记录,现在是每间隔2分钟插入一条记录。

SQL> show parameter resource_manager_plan

resource_manager_plan string SCHEDULER[0x115E7]:DAYTIME //DAYTIME资源计划被DAY_WIN自动激活了(保持1分钟,2分钟后再激活)。

OK!到此,整个例子基本完成了。

*考点:
1)当create job过程创建作业时,无法指派优先级,必须在后面使用API的set attribute过程。
2)作业A在其类中的优先级是1,作业B在另一个类的优先级是5,作业B处于resource plan中有更高的优先权的使用者组内,则B先于A被执行。

oracle之三 自动任务调度的更多相关文章

  1. Oracle的自动统计信息不收集直方图的信息

    Oracle的自动统计信息不收集直方图的信息 在oracle9i中,默认的统计信息收集是不收集直方图信息的,也就是说默认的MOTHOD_OPT模式为FOR ALL COLUMNS SIZE 1 在10 ...

  2. Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:

    Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长: 通过Hibernate注解的方式映射oracel数据库的sequence主键生成器 ...

  3. Windows下Oracle数据库自动备份批处理脚本

    expdb命令版本 @echo off REM ########################################################### REM # Windows Se ...

  4. oracle之三存储库及顾问框架

    AWR存储库及顾问框架(PPT-I-349-360) 14.1 Oracle数据库采样ASH和AWR. 1) ASH(Active Session History) ASH收集的是活动会话的样本数据, ...

  5. Windows系统下Oracle每天自动备份

    linux和unix下面使用shell可以很方便实现,如果windows环境下可以结合计划任务实现 创建备份目录d:\backup, 创建批处理命令Bak.bat,编写备份脚本 exp user/pa ...

  6. CentOS7下Oracle的自动备份

    概述 Linux下Oracle自动备份就没有MSSQL那么简单,在Linux下Oracle的备份需要借助crontab 指令,crontab 能够自动执行系统定时任务,通过配置crontab 指向Or ...

  7. Linux oracle数据库自动备份自动压缩脚本代码

    Linux oracle数据库备份完成后可以自动压缩脚本代码. 复制代码代码如下: #!/bin/bash #backup.sh #edit: www.jbxue.com ##系统名称 sysname ...

  8. Oracle DB 自动管理共享内存

    • 启用Oracle Enterprise Manager (EM) 内存参数 • 设置自动优化的内存参数 • 使用手动优化的SGA 参数覆盖最小大小 • 使用SGA Advisor 设置SGA_TA ...

  9. Oracle 每天自动生成AWR报告

    经验丰富的老员工希望能够每天为数据库生成1个AWR报告,以便于后期分析数据库的性能变化,手动生成太麻烦,查了一下资料,发现可以自动生成,过程如下. 数据库环境:11gR2 RAC(双节点) AWR报告 ...

随机推荐

  1. 题解 P1407

    建图方式:旧关系女人连男人,现关系男人连女人(当然,反过来也可以) 原因可以这样考虑: 如果一个男的把女的绿了,那么这个女人就会去找一个她曾经交往过的男人,也就是在这种情况下,某种"影响&q ...

  2. Maven项目在进行单元测试报错:ClassNoFoundExceptipon

    解决方法: 只要把Java--------compiler-------building-------Buil path problems ------- incomplete build path ...

  3. 一句话木马变形(截止2020年8月16日通杀D盾、安全狗,微步,webshellKiller)

    首先一句话木马: <?php assert($_POST['a']); ?> D盾扫描,5级 分开写: <?php $a = "assert"; $b = $_P ...

  4. Linux 将文件打包、压缩并分割成指定大小

    打包文件: tar -cvf .tar 分割文件: split -b 3G -d -a .tar .tar. //使用split命令,-b 3G 表示设置每个分割包的大小,单位还是可以k // -d ...

  5. Cirros镜像

    Openstack的开发,基本都使用这个image来测试,因为他比较小,只有10M. 镜像介绍 镜像的地址: https://launchpad.net/cirros/trunk/0.3.0/+dow ...

  6. Alpha阶段项目复审(鸽牌开发小分队)

    团队:鸽牌开发专业小分队 项目:必备记 集合帖:集合帖 项目复审: 团队名字 项目链接 优点 缺点和bug报告 最终名次 歪瑞古德小队 海岛漂流 1.功能齐全,上手简单2.界面简洁美观3.想法新颖,可 ...

  7. vuex的模块化使用

    store文件如下 1.modules下文件是模块化的划分,里面的js有state,action,mutations.然后通过 export default { namespaced: true, s ...

  8. 由浅入深理解 IOC 和 DI

    目录 由浅入深理解 IOC 和 DI 开闭原则 OCP(Open Closed Principle) 面向抽象编程 逐步理解实现 IOC 和 DI 的过程(LOL Demo 示例) 比较尴尬的编写程序 ...

  9. Nginx Ingress 高并发实践

    概述 Nginx Ingress Controller 基于 Nginx 实现了 Kubernetes Ingress API,Nginx 是公认的高性能网关,但如果不对其进行一些参数调优,就不能充分 ...

  10. 【Android】AndroidStudio关于EventBus报错解决方法its super classes have no public methods with the @Subscribe

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先说明,以前我用eventBus的 ...