ORACLE_OCP之Oracle Scheduler( ORACLE调度器)自动执行任务
- 文章目标:
- 使用Oracle Scheduler简化管理任务
- 创建作业,计划和调度日程
- 监视作业执行
- 使用基于时间或基于事件的计划来执行Oracle Scheduler作业
- 描述窗口,窗口组,作业类别和消费组的使用
- 使用电子邮件通知
- 使用工作链执行一系列相关任务
- 描述远程系统上的调度器作业
- 使用高级调度器功能对作业进行优先级排序
一、简化任务管理
二、理解简单的JOB
BEGIN
sys.dbms_scheduler.create_job(
job_name => '"HR"."CREATE_LOG_TABLE_JOB"',
job_type => 'PLSQL_BLOCK', job_action => 'begin
execute immediate (''create table session_history(
snap_time TIMESTAMP WITH LOCAL TIME ZONE,
num_sessions NUMBER)''); end;',
start_date => systimestamp at time zone 'America/New_York',
job_class => 'DEFAULT_JOB_CLASS',
comments => 'Create the SESSION_HISTORY table',
auto_drop => FALSE, enabled => TRUE);
END;
三、Oracle Scheduler Core Components ORACLE 调度器内核组件
四、使用ORACLE调度器
- 使用调度器简化任务:
- 创建程序(启用或禁用)-可选
- 在多个作业中重用此操作
- 在不需要重新创建PL/SQL块的情况下更改作业的程序
- 创建一个调度计划.
- 创建并提交作业.(定时执行)
- 创建程序(启用或禁用)-可选
五、使用ORACLE调度器
- 您可以通过使用EMCC控制或通过使用DBMS_SCHEDULER - PL / SQL包来执行所有步骤。
- 1.创建程序
- 使用CREATE_PROGRAM过程创建一个程序。创建程序是使用计划程序的可选步骤。您还可以在CREATE_JOB过程中对要在匿名PL / SQL块中执行的操作进行编码。通过分别创建程序,可以一次定义操作,然后在多个作业中重复使用该操作。这使您可以更改作业的程序,而不必重新创建PL / SQL块。
默认情况下,程序是在禁用状态下创建的(除非ENABLED参数设置为TRUE)。禁用的程序只有在启用后才能由作业执行。您可以通过为ENABLED指定TRUE值来指定应在启用状态下创建程序。
- 使用CREATE_PROGRAM过程创建一个程序。创建程序是使用计划程序的可选步骤。您还可以在CREATE_JOB过程中对要在匿名PL / SQL块中执行的操作进行编码。通过分别创建程序,可以一次定义操作,然后在多个作业中重复使用该操作。这使您可以更改作业的程序,而不必重新创建PL / SQL块。
- 2.创建和使用调度计划
- 作业计划可以是预定义的计划(通过CREATE_SCHEDULE过程创建),也可以定义为作业创建的一部分。
该计划指定有关何时运行作业的属性,例如:
开始时间(定义开始执行的时间)和结束时间(指定结束时间,之后该时间不再有效且不再进行调度)
该表达式指定作业的重复间隔
通过合并现有时间表创建的复杂时间表
开始作业之前必须满足的条件或状态变化(称为事件)
通过使用调度日程(而不是在作业定义中指定作业的执行时间),您可以管理多个作业的计划执行,而不必更新多个作业定义。如果修改了日程表,则使用该日程表的每个作业都会自动使用新的日程表。
- 作业计划可以是预定义的计划(通过CREATE_SCHEDULE过程创建),也可以定义为作业创建的一部分。
- 3.创建和运行作业
- 作业是日程安排和对操作的描述以及作业所需的任何其他参数的组合。您可以为作业设置许多属性。属性控制作业的执行方式。
- 1.创建程序
六、持久的轻量级作业
- 减少开始工作所需的开销和时间
- 占用磁盘上的空间很小,主要用于作业元数据和用于存储过程运行时数据
- 从作业模板创建(在命令行中)
七、基于时间的作业
- Example:创建一个从今晚开始的每晚11:00调用备份脚本的作业
BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name=>'HR.DO_BACKUP', job_type => 'EXECUTABLE', job_action => '/home/usr/dba/rman/nightly_incr.sh', start_date=> SYSDATE, repeat_interval=>'FREQ=DAILY;BYHOUR=23', /* next night at 11:00 PM */ comments => 'Nightly incremental backups'); END; /
八、创建一个基于事件的调度计划
- 创建一个基于事件的作业, 你必须设置:
- 队列规范(您的应用程序需要在队列消息中以开始作业)
- 一个事件条件(与Oracle Streams AQ规则条件相同的语法),如果为TRUE,则开始作业
九、创建一个基于事件的作业
- Example:创建一个作业,该作业将批量加载数据文件,并且在9:00 AM之前到达文件系统时运行.
BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name=>'ADMIN.PERFORM_DATA_LOAD', job_type => 'EXECUTABLE', job_action => '/loaddir/start_my_load.sh', start_date => SYSTIMESTAMP, event_condition => 'tab.user_data.object_owner = ''HR'' and tab.user_data.object_name = ''DATA.TXT'' and tab.user_data.event_type = ''FILE_ARRIVAL'' and tab.user_data.event_timestamp < 9 ', queue_spec => 'HR.LOAD_JOB_EVENT_Q'); END;
十、基于事件的调度
-
事件类型:
- 由用户生成或应用程序生成的事件
- 由调度程序生成的事件
-
调度器作业引发的事件:
- JOB_STARTED
- JOB_SUCCEEDED
- JOB_FAILED
- JOB_BROKEN
- JOB_COMPLETED
- JOB_STOPPED
- JOB_SCH_LIM_REACHED
- JOB_DISABLED
- JOB_CHAIN_STALLED
- JOB_ALL_EVENTS
- JOB_RUN_COMPLETED
- JOB_OVER_MAX_DUR
-
Example of raising an event:
DBMS_SCHEDULER.SET_ATTRIBUTE(‘hr.do_backup’,
‘raise_events’, DBMS_SCHEDULER.JOB_FAILED);
十一、创建复杂的调度计划
- INCLUDE:将日期列表添加到日历表达式结果中
- EXCLUDE:从日历表达式结果中删除日期列表
- INTERSECT:仅使用两个或两个以上时间表的共同日期
十二、使用电子邮件通知
- 通过电子邮件通知更改作业状态
- 由作业状态事件触发
- 多个通知,多个收件人
- * _SCHEDULER_NOTIFICATIONS视图
- 使用调度器的电子邮件告知功能:
-
指定将用于发送电子邮件的SMTP服务器的地址:
DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE
(‘email_server’,‘host[:port]’); -
(可选)设置默认的发件人电子邮件地址:
DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE
(‘email_sender’,‘valid email address’); -
添加指定作业的电子邮件通知
DBMS_SCHEDULER.ADD_JOB_EMAIL_NOTIFICATION (
job_name IN VARCHAR2,
recipients IN VARCHAR2,
sender IN VARCHAR2 DEFAULT NULL,
subject IN VARCHAR2
DEFAULT dbms_scheduler.default_notification_subject,
body IN VARCHAR2
DEFAULT dbms_scheduler.default_notification_body,
events IN VARCHAR2
DEFAULT ‘JOB_FAILED,JOB_BROKEN,JOB_SCH_LIM_REACHED,
JOB_CHAIN_STALLED,JOB_OVER_MAX_DUR’,
filter_condition IN VARCHAR2 DEFAULT NULL);DBMS_SCHEDULER.REMOVE_JOB_EMAIL_NOTIFICATION (
job_name IN VARCHAR2,
recipients IN VARCHAR2 DEFAULT NULL,
events IN VARCHAR2 DEFAULT NULL);
-
十三、创建作业链
- 创建一个链对象。
- 定义链式步骤。
- 定义链规则。
- 开始链:
- 启用链。
- 创建一个指向链的作业。
- 链是一系列命名的程序,这些程序链接在一起以实现共同的目标。这就是所谓的“依赖关系调度”。链的示例如下:
- 先运行程序A,然后运行程序B,但只有在程序A和B成功完成后才运行程序C,否则运行程序D。
相互依赖的程序链中的每个位置都称为一个步骤。通常,在开始一组初始的连锁步骤之后,后续步骤的执行取决于一个或多个先前步骤的完成。要创建和使用链,请按顺序完成以下步骤。除非另有说明,否则所有提到的过程都是DBMS_SCHEDULER软件包的一部分。- 1.使用CREATE_CHAIN过程创建一个链。链名称可以可选地用架构名称限定(例如,myschema.myname)。
- 2.定义(一个或多个)链式步骤。定义步骤将为其命名,并指定该步骤执行的操作。每个步骤可以指向以下之一:
- 一个程序
- 另一个链(嵌套链)
- 一个事件
- 您可以通过调用DEFINE_CHAIN_STEP过程来定义一个指向程序或嵌套链的步骤。
- 要定义等待事件发生的步骤,请使用DEFINE_CHAIN_EVENT_STEP过程。过程参数可以指向事件时间表,也可以包括内联队列规范和事件条件。指向事件的步骤将等待,直到引发指定事件为止。如果事件发生,则该步骤成功完成。
- 3.创建链对象后,定义链规则。链式规则定义了步骤运行的时间,并定义了步骤之间的依赖性。每个规则都有一个条件和一个动作:
- 如果条件评估为TRUE,则执行操作。该条件可以包含在SQL WHERE子句中有效的任何语法。条件通常基于一个或多个先前步骤的结果。例如,如果前两个步骤成功,则可能要运行一个步骤,而如果前两个步骤中的任何一个失败,则希望运行另一个步骤。
- 该操作指定触发规则后要执行的操作。典型的操作是运行指定的步骤。可能的动作包括开始或停止步骤。您也可以选择结束作业链的执行,返回值或步骤名称和错误代码。
- 添加到链中的所有规则共同作用以定义链的整体行为。当作业开始且在每个步骤结束时,将评估所有规则,以查看下一步将发生哪些动作。您可以使用DEFINE_CHAIN_RULE过程将规则添加到链中。您对要添加到链中的每个规则调用一次此过程。
- 4.启动链涉及两个动作:
- 使用“启用”过程启用链。 (始终将链创建为禁用状态,因此您可以在任何作业执行链之前将步骤和规则添加到链中。)启用已启用的链不会返回错误。
- 要运行链,您必须创建“链”类型的作业。作业操作必须引用链名称。您可以为此作业使用基于事件的计划或基于时间的计划。
- 先运行程序A,然后运行程序B,但只有在程序A和B成功完成后才运行程序C,否则运行程序D。
十四、作业链的例子
十五、使用高级调度计划功能
-
使用高级计划程序功能,您可以对计划的各个方面进行更多控制,例如作业窗口和作业优先级。这些高级功能总结如下,
- WINDOW(窗口)由具有明确定义的开始和结束的时间间隔表示,并用于在不同时间激活不同的资源计划。这使您可以在一段时间内更改资源分配,例如一天中的时间或销售年份的时间。
- WINDOW-GROUP(窗口组)代表窗口列表,并允许更轻松地管理窗口。您可以使用窗口或窗口组作为作业的计划,以确保仅在窗口及其关联的资源计划处于活动状态时才运行该作业。
- JOB CLASS(作业类)定义了具有共同资源使用要求和其他特征的作业类别。作业类别将作业分为更大的实体。
- Resource consumer group(资源消费组) 确定分配给作业类别中的作业的资源。
- Resource plan(资源计划)使用户可以在资源消费组之间确定资源的优先级(最主要是CPU)。
注意:灰色对象不是Scheduler对象。
十六、Job Classes(作业类)
- 向成员作业分配相同的属性值集合
- 由CREATE_JOB_CLASS过程创建
- 在作业类中指定作业(使用SET_ATTRIBUTE过程)
- 属于SYS SCHEMA
- 设置成员作业的资源分配
- 将服务属性设置为目标数据库服务名称
- 分组作业以进行优先排序
十七、Windows(窗口)
- 调度器窗口:
- 可以在不同时间段开始作业或更改作业之间的资源分配
- One active at a time -> 一次一激活
- 用CREATE_WINDOW过程创建
十八、在窗口中的作业优先级
- 作业优先级:
- 在类级别(通过资源计划)
- 在作业级别(具有作业优先级属性)
- 不保证适用于不同作业类别的工作
十九、Creating a Job Array(创建作业队列)
-
1、声明类型为sys.job和sys.job_array的变量:
DECLARE
newjob sys.job;
newjobarr sys.job_array; -
2、初始化作业队列:
BEGIN
newjobarr := SYS.JOB_ARRAY(); -
3、调整作业队列的大小以容纳所需的作业数:
newjobarr.EXTEND(100);
-
4、将作业放入作业队列:
FOR i IN 1…100 LOOP
newjob := SYS.JOB(job_name => ‘LWTJK’||to_char(i),
job_style => ‘LIGHTWEIGHT’,
job_template => ‘MY_PROG’,
enabled => TRUE );
newjobarr(i) := newjob;
END LOOP; -
5、提交作业队列作为一项事务:
DBMS_SCHEDULER.CREATE_JOBS(newjobarr,
‘TRANSACTIONAL’);
操作实例:
DECLARE
newjob sys.job;
newjobarr sys.job_array;
BEGIN
-- Create an array of JOB object types
newjobarr := sys.job_array();
-- Allocate sufficient space in the array
newjobarr.extend(100);
-- Add definitions for jobs
FOR i IN 1..100 LOOP
-- Create a JOB object type
newjob := sys.job(job_name => 'LWTJK' || to_char(i),
job_style => 'LIGHTWEIGHT',
job_template => 'PROG_1',
enabled => TRUE );
-- Add job to the array
newjobarr(i) := newjob;
END LOOP;
-- Call CREATE_JOBS to create jobs in one transaction
DBMS_SCHEDULER.CREATE_JOBS(newjobarr, 'TRANSACTIONAL');
END;
/
二十、创建一个基于事件的文件监视器作业
-
执行以下任务:
- 创建一个Scheduler凭证对象,并授予EXECUTE权限。
- 创建一个文件监视程序,并授予EXECUTE权限。
- 创建一个带有引用事件消息的元数据参数的Scheduler程序对象。
- 创建一个引用文件监视器的基于事件的作业。 (可选地,在相关的实例上执行)
- 启用文件监视程序和作业。
-
创建一个基于事件的文件监视器作业。 您可以使用DBMS_SCHEDULER.SET_ATTRIBUTE过程来使作业针对的文件到达事件运行的每个实例,即使该作业已经在处理上一个事件。 将PARALLEL_INSTANCES属性设置为TRUE。
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE(’’,‘PARALLEL_INSTANCES’, TRUE);
END; -
这使该作业可以作为轻量级作业运行,以便可以快速启动该作业的多个实例。 如果将PARALLEL_INSTANCES设置为FALSE的默认值,则在基于事件的作业已经在处理另一个事件时发生的文件监视程序事件将被丢弃。
二十一、启用远程系统中的文件到达事件
- 执行以下任务,以在远程系统上引发文件到达事件:
- 设置数据库以运行远程外部作业。
- 在第一个远程系统上安装,配置,注册和启动Scheduler代理。
- 对每个其他远程系统重复步骤2。
二十二、调度计划远程数据库作业
- 创建一个作业,该作业在同一主机或远程主机上的另一个数据库实例上运行存储过程和匿名PL / SQL块。
- 目标数据库可以是任何版本的Oracle数据库。
- DBMS_SCHEDULER.CREATE_DATABASE_DESTINATION和DBMS_SCHEDULER.CREATE_CREDENTIAL可以用于远程数据库作业。
- 作业类型为PLSQL_BLOCK和STORED_PROCEDURE的作业可以是DESTINATION(目的地)和CREDENTIAL(凭证)属性的SET_ATTRIBUTE调用的主题。
二十三、创建远程数据库作业
-
执行以下任务以创建远程作业:
- 为远程作业设置原始数据库。
- 通过使用DBMS_SCHEDULER.CREATE_JOB创建作业。
- 通过使用DBMS_SCHEDULER.CREATE_CREDENTIAL创建证书。
- 通过使用DBMS_SCHEDULER.SET_ATTRIBUTE设置作业CREDENTIAL_NAME属性。
- 通过使用DBMS_SCHEDULER.SET ATTRIBUTE设置作业目的地属性。
- 通过使用DBMS_SCHEDULER.ENABLE启用作业。
-
要为远程作业设置原始数据库,请执行以下步骤:
-
1.确认已安装XML DB。
-
2.启用到数据库的HTTP连接。
BEGIN
DBMS_XDB.SETHTTPPORT(port);
END; -
3.执行prvtrsch.plb脚本。
-
4.设置调度程序代理端的密码。
BEGIN
DBMS_SCHEDULER.SET_AGENT_REGISTRATION_PASS(‘password’);
END;
有关详细示例,请参考《 Oracle数据库管理员指南》。
-
二十四、调度多个目标上的作业
- 这使您可以指定要执行作业的多个目标数据库
- 它提供了从创建作业的数据库中监视和控制作业的功能。
- 在运行时,多目标作业被视为作业的集合,它们彼此之间副本近乎差不多。
- 所有作业将根据作业开始日期中指定的时区执行,或使用源数据库的时区。
二十五、查看调度器元数据
- 调度器管理视图,显示:
- *_SCHEDULER_JOBS: 所有作业启用和禁用
- *_SCHEDULER_SCHEDULES: 所有调度计划
- *_SCHEDULER_PROGRAMS: 所有程序
- *_SCHEDULER_RUNNING_JOBS: 活动作业状态
- *_SCHEDULER_JOB_LOG: 所有状态更改
- *_SCHEDULER_JOB_RUN_DETAILS: 所有已运行过的作业
SELECT job_name, status, error#, run_duration
FROM user_scheduler_job_run_details;
JOB_NAME STATUS ERROR# RUN_DURATION
---------------- ------ ------ ------------
GATHER_STATS_JOB SUCCESS 0 +000 00:08:20
PART_EXCHANGE_JOB FAILURE 6576 +000 00:00:00
- 对于工作链:
- * _SCHEDULER_RUNNING_CHAINS:显示所有活动链
- * _SCHEDULER_CHAIN_STEPS:显示所有链的所有步骤
- * _SCHEDULER_CHAINS:显示所有链
- * _SCHEDULER_CHAIN_RULES:显示所有链的所有规则
- 对于Windows和其他高级对象:
- * _SCHEDULER_WINDOWS显示所有窗口。
- * _SCHEDULER_WINDOW_GROUPS显示所有窗口组。
- * _SCHEDULER_WINGROUP_MEMBERS显示所有窗口组的成员,每个组成员一行。
- * _SCHEDULER_JOB_LOG显示对作业进行的所有状态更改。
- * _SCHEDULER_JOB_ROLES按数据库角色显示所有作业。
- 轻量级作业通过与常规作业相同的视图可见:
- * _SCHEDULER_JOBS:显示所有作业,包括JOB_STYLE =‘LIGHTWEIGHT’
- * _SCHEDULER_JOB_ARGS:还显示轻量级作业的所有设置的参数值
因为轻量级作业不是数据库对象,所以它们无法通过* _OBJECTS视图看到。
- 从Oracle Database 11g第2版开始:
- * _SCHEDULER_NOTIFICATIONS显示已设置的电子邮件通知。
- * _SCHEDULER_FILE_WATCHERS显示文件监视程序的配置信息。
- 以下视图显示有关多个目标作业的信息:
- * _SCHEDULER_DESTS:显示可以安排远程作业的所有目标。该视图既包含外部目标(用于远程外部作业),又包含远程数据库作业的数据库目标。
- * _SCHEDULER_EXTERNAL_DESTS:显示所有已在数据库中注册并可用作远程外部作业目标的代理。
- * _SCHEDULER_DB_DESTS:显示可以安排远程数据库作业的所有数据库。
- * _SCHEDULER_GROUPS:显示架构中的组或数据库中的所有组。
- * _SCHEDULER_GROUP_MEMBERS:显示架构中的组成员或数据库中的所有组成员。
- * _SCHEDULER_JOB_DESTS:显示远程数据库上作业的状态。
注意:在上面列出的视图中,视图名称开头的星号可以替换为DBA,ALL或USER。