哈哈,关于schedule的内容还没完,本章讲Windows,通常说的Windows是指盖首富的操作系统,而此处所说的Windows,
是指SCHEDULER特性中的一个子项。在SCHEDULER中,WINDOW对应的是一个时间窗口的概念。
我们知道普通的jobs是没有运行时间管理地概念的,就是说一个job启动之后,用户只能被动地等待其执行,一直到其执行地任务完成(或DBA手动kill对应进程),
在此期间,执行的job将与其它活动的进程共同竞争当前系统中的资源。对于大型数据库系统,系统资源那可是相当宝贵的无形资产哪,
企能谁说用就用、想什么时候用就什么时候用,没点儿计划没点儿节制这还了得。你还别说,在9i之前,还真就是这么回事儿,谁想用就用,谁也管不了,
其中表示最甚的就是job。你是否想起了Job Classes,没错定义Job Classes确实可以控制job能够使用的资源,不过单单使用Job Classes并不能灵活的控制job在合适的时间使用适当的资源。
oracle 10g之后,SCHEDULER中提供了WINDOWS,事情终于得到了解决。
WINDOW 可以指定一个时间窗口,在此期间,通过与Job Classes的搭配组合,能够有效控制job执行时支配(使用)的资源。
比如说job通常是在凌晨服务器负载较低时执行,那么就可以通过WINDOW设置在此期间,允许jobs使用更多的系统资源,而到了工作时间后,
如果job仍未执行完成,为其分配另一个有限的资源,以尽可能降低job执行占用的资源对其它业务的影响。
1、创建Window
创建Window有一个专门的过程:DBMS_SCHEDULER.CREATE_WINDOW进行处理,该过程有两种调用方式
-- 基于SCHEDULE
DBMS_SCHEDULER.CREATE_WINDOW (
window_name IN VARCHAR2,
resource_plan IN VARCHAR2,
schedule_name IN VARCHAR2,
duration IN INTERVAL DAY TO SECOND,
window_priority IN VARCHAR2 DEFAULT "LOW",
comments IN VARCHAR2 DEFAULT NULL
);
-- 基于定义的调度
DBMS_SCHEDULER.CREATE_WINDOW (
window_name IN VARCHAR2,
resource_plan IN VARCHAR2,
start_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
repeat_interval IN VARCHAR2,
end_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL,
duration IN INTERVAL DAY TO SECOND,
window_priority IN VARCHAR2 DEFAULT "LOW",
comments IN VARCHAR2 DEFAULT NULL);
除去那些之前已经介绍的,已经认识的,看参数名就知道其所代表含义的之外,下列几个参数需要重点关注
Resource_plan 这一参数用来指定要使用的资源使用计划,当打开WINDOW时,就会自动按照指定的资源使用计划中的设置分配资源,
当WINDOW关闭时(没错,window是会关闭的,要不怎么说有效控制资源的使用情况泥),系统会自动切换回适当资源计划。
这个参数在执行过程时甚至可以指定为NULL或空值"",当设置为NULL时,就表示使用默认的资源计划,当设置为空值""时,表示禁用资源使用计划。
Duration 指定WINDOW的有效期,比如说指定为interval "5" hour就表示5个小时,该参数在执行过程时必须指定参数值,否则创建会报错。
Window_priority 该参数用来指定WINDOW的优先级。因为在相同时间只有一个WINDOW有效,因此如果在创建WINDOW时发现重叠的情况,ORACLE就需要根据这一参数指定的规则,
来确定优先级,说白了就是先把资源给谁用,这一参数有两个可选值:HIGH或LOW,默认值为LOW。
正如前面CREATE_WINDOW过程语法结构显示的那样,调用该过程也有两种方式,差异就在于是指定现有定义好的调度SCHEDULE,还是在执行过程时指定调度,
目标和实现的功能都是相同的,这里仅做示例,我们挑个最复杂的方式吧,执行过程时指定调度,执行脚本如下
begin
dbms_scheduler.create_window(window_name => 'mywindow1',
resource_plan => null,
start_date => sysdate,
repeat_interval => 'FREQ=DAILY; INTERVAL=5',
duration => interval '1' hour);
end;
查询当前拥有的WINDOW,可以通过*_SCHEDULER_WINDOWS视图(注意只有DBA和ALL,没有USER,因为所有定义的WINDOW都属于SYS用户)。
除了*_SCHEDULER_WINDOWS视图显示当前所有WINDOW外,还有*_SCHEDULER_WINDOW_DETAILS 视图,显示WINDOW的详细信息。
*_SCHEDULER_WINDOW_LOG 视图,显示WINDOW的日志,比如打开和关闭。
select window_name,resource_plan,to_char(start_date,'yyyy-mm-dd hh34:mi:ss') ,repeat_interval from DBA_SCHEDULER_WINDOWS where window_name = 'MYWINDOW1';
WINDOW_NAME RESOURCE_PLAN TO_CHAR(START_DATE,'YYYY-MM-DDHH24:MI:SS') REPEAT_INTERVAL
--------------- ------------------------------ --------------------------------------------------------------------------- -------------------------
MYWINDOW1 2018-05-15 15:12:02 FREQ=DAILY; INTERVAL=5
2、管理Window
通过前面那些SCHEDULER对象的学习,相当大家已经了解了ORACLE SCHEDULER中对象的特点,对于多数对象的管理,基本都是下面这几种
(1)修改对象属性,使用SET_ATTRIBUTE过程;
begin
dbms_scheduler.set_attribute("mywindow1","start_date",sysdate+1);
end;
(2)ENABLE 对象,使用ENABLE过程;
begin
dbms_scheduler.enable("mywindow1");
end;
(3)DISABLE 对象,使用DISABLE过程;
begin
dbms_scheduler.disable("mywindow1");
end;
(4)删除对象,使用DROP_WINDOW过程;
begin
dbms_scheduler.drop_window("mywindow1");
end;
(5)除此之外呢,对于WINDOW对象来说,由于其特殊作用,又有手动打开WINDOW,使用OPEN_WINDOW过程。
注意WINDOW是依赖于其调度的,因此在手动打开WINDOW时,必须为其指定duration属性
begin
dbms_scheduler.open_window("mywindow1",interval "1" hour);
end;
(6)手动关闭WINDOW,使用CLOSE_WINDOW过程
begin
dbms_scheduler.close_window("mywindow1");
end;
关闭和打开WINDOW,都会记录日志,大家可以通过*_SCHEDULER_WINDOW_LOG视图中获取这部分信息。
3、WINDOW GROUP
除了WINDOW外,还有一个与WINDOW有关系的叫WINDOW GROUP,一个WINDOW GROUP可能包含多个WINDOW。使用WINDOW GROUP的本意是这样的,
假如说某个job执行的时间比较长,甚至全天24小时都在执行,对于这类job,单个WINDOW很难有效调整其资源占用,这时间呢,
就可以通过设置一个WINDOW GROUP,该WINDOW GROUP中包含了多个WINDOW,每个WINDOW分别负责不同时间点时的资源使用计划。
然后在创建JOB时,指定schedule_name参数为WINDOW GROUP的名称(想不到SCHEDULE_NAME还能指定为WINDOW GROUP哪,其实何止WINDOW GROUP,
还可以直接指定成WINDOW哪),这样,就可以通过很简单的方式,将job与window联系在一起了。
WINDOW GROUP 的创建和管理与前面介绍的方式极其相似
创建,使用CREATE_WINDOW_GROUP过程
删除,使用DROP_WINDOW_GROUP过程
添加WINDOW成员,使用ADD_WINDOW_GROUP_MEMBER过程
删除WINDOW成员,使用REMOVE_WINDOW_GROUP_MEMBER过程
启用,使用ENABLE过程
禁用,使用DISABLE过程
这些过程的调用方式也都非常简单,大家可以私底下做做实验。