图文深入理解Oracle DB Scheduler(续)-调度的创建

  1. List item

今天是国庆假期最后一天。窗外,秋雨淅淅沥沥淅淅下个不停。继续深宅家中,闲来无事,就多写几篇博文。

本篇承接前一篇,继续图文深入介绍Oracle DB Scheduler。本篇主要介绍调度的创建。

1. 创建基于时间的作业

• 可以使用 DBMS_SCHEDULER 程序包的 CREATE_JOB 过程来创建作业。默认情况下将以禁用状态创建作业,仅当显式启用时,这些作业才生效并可以调度。

• 所有 Job 作业名称都采用以下形式:[schema.]name。默认情况下,将在当前方案中创建作业。作业将按作业所有者的权限来执行。

• 应该使用 SYSTIMESTAMP 并指定时区,这样当时间因夏时制更改时,作业能够自动调整其执行时间。

• 作业运行时使用的国家语言支持(NLS)环境与创建作业时的环境相同。

• job_type 参数指示作业将要执行的任务类型。可选的值包括:

--PLSQL_BLOCK:匿名 PL/SQL 块

--STORED_PROCEDURE:命名的 PL/SQL、Java 或外部过程

-- EXECUTABLE:可以从操作系统 (OS) 命令行执行的命令

• job_action 参数可以是要运行的过程的名称、脚本的名称或操作系统命令的名称,也可以是匿名的PL/SQL 代码块,具体取决于 job_type 参数的值。

• EXECUTABLE 类型的外部作业:是指在数据库外部运行的作业。所有外部作业均以低权限的来宾用户运行,所以应确保其有权访问必要的文件和资源。大多数(但不是所有)平台都支持外部作业。对于不支持外部作业的平台,如果将 Job 作业或

Program 程序的属性设置为 EXECUTABLE 类型,将返回错误。

例:创建一个 Job 作业,从今晚起在每晚10: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 10:00 PM */
comments => 'Nightly incremental backups');
END;
/

2. 创建基于事件的调度

要创建基于事件的作业,要将事件消息入队到 Oracle Streams 队列中。必须设置:

• 一个队列说明(应用程序可将消息入队以启动作业)

• 一个事件的触发条件(与 Oracle Streams AQ 规则条件的语法相同),如果为 TRUE 则启动作业。

调度程序都会运行基于事件的作业。但是,将忽略作业已经运行后发生的事件;事件不会触发作业再次运行。

2.1 使用 Oracle Enterprise Manager创建基于事件的调度

2.2 CMD创建基于事件的调度

在命令行使用 CREATE_JOB 过程创建事件 Job,则必须设置以下两个附加属性:

• queue_spec:对队列的指定,包括应用程序将消息放入其中以引发作业启动事件的队列的名称;对于安全队列,则为<queue_name>、<agent_name> 对。

• event_condition:基于消息属性的条件表达式,此表达式的求值结果必须为 TRUE,消息才能启动作业。

例:创建一个作业,如果成批装载的数据文件在上午 10:00 之前到达文件系统,则运行此作业。

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;
/

2. 3 Job 作业的事件类型:

  1. 用户或应用程序生成的事件。如:作业完成、文件到达、帐户被锁定、以及库存到达下限阈值等。
  2. 调度程序生成的事件。如:作业开始、作业结束、作业超出其分配的运行时间等。

2. 4 由调度程序作业引发的事件:

• JOB_STARTED

• JOB_SCH_LIM_REACHED

• JOB_SUCCEEDED

• JOB_DISABLED

• JOB_FAILED

• JOB_CHAIN_STALLED

• JOB_BROKEN

• JOB_ALL_EVENTS

• JOB_COMPLETED

• JOB_RUN_COMPLETED

• JOB_STOPPED

• JOB_OVER_MAX_DUR

例:

DBMS_SCHEDULER.SET_ATTRIBUTE('hr.do_backup',
'raise_events'
, DBMS_SCHEDULER.JOB_FAILED);
/

3.创建复杂调度

可以使用调度的组合来创建更复杂的调度。在组合调度中,可以向日历表达式中添加特定日期,或者从日历表达式中排除特定日期。定义调度的重复间隔时可以使用下列选项:

• INCLUDE:向日历表达式结果中添加日期列表

• EXCLUDE:从日历表达式结果中删除日期列表

• INTERSECT:只使用两个或多个调度共有的日期

3. 1 创建作业链(Job Chains)

• Chain(链)是为达到目标而组合链接在一起的一系列已命名的程序。被称为Dependency Scheduling(依存调度)。

• 在相互依赖的程序构成的链中,每个位置都称为一个 Steps(步骤)。通常情况下,链的一系列初始步骤启动之后,后续步骤的执行依赖于之前一个或多个步骤的完成。

• 例如:运行程序 A 然后运行程序 B,如果程序 A 和程序 B 成功完成,则只运行程序 C,否则运行程序 D。

• 要创建并使用链,要依次完成下列步骤,其中所有过程都是DBMS_SCHEDULER 程序包的一部分:

  1. 创建链对象
  2. 定义链步骤
  3. 定义链规则
  4. 启动链:
    -- 启用链
    -- 创建指向链的作业

• 使用 CREATE_CHAIN 过程创建链。链名称可以用方案名称来限定(如myschema.myname)。

• 使用 DEFINE_CHAIN_EVENT_STEP 过程定义链的步骤。可以指定步骤中发生的操作为下列项之一:

--程序

-- 另一个链(嵌套链)

-- 事件

• 使用 DEFINE_CHAIN_RULE 过程向链中添加规则。链规则定义各步骤运行的时间、以及各步骤之间的依赖关系。每个规则都有一个"条件"和一个"操作":

--如果条件的求值结果为TRUE,则执行操作。条件中可以包含在 SQL WHERE 子句中有效的任何语法。条件通常基于前面一个或多个步骤的结果。

--操作是指定在触发规则时要执行的内容。可能的操作包括:启动或停止步骤、可以选择结束作业链的执行、返回一个值或者返回步骤名和错误代码。

•. 启动链包括两个操作:

--用 ENABLE 过程启用链。(链总是以禁用状态创建,在执行该链之前可向其中添加步骤和规则。)启用一个已启用的链不会返回错误。

-- 要运行链,必须创建 'CHAIN' 类型的作业。作业的操作必须引用链名称。

例:

在上图中,要考虑在批量数据加载期间出现的所有任务和条件:

  1. 必须有要加载的数据;
  2. 然后加载数据;
  3. 在数据加载完成后,需要重建在更新后的表上
    定义的索引;
  4. 然后针对新加载数据运行报表;
  5. 同时观察文件系统以确保在加载期间不会发生空间不足的情况;

4. 高级调度程序

注:灰色对象不是调度程序对象

4.1 作业类(Job Classes)

• 属于 SYS schema

• 可为类中的作业成员分配一组相同的属性值

• 使用 CREATE_JOB_CLASS 过程创建

• 使用 SET_ATTRIBUTE 过程指定作业的作业类(默认类:DEFAULT_JOB_CLASS)

• 可为作业成员设置资源使用者组(默认组:DEFAULT_CONSUMER_GROUP)

• 可将服务属性设置为所需的数据库服务名称,以便分配系统资源。

• 如果同时设置了 resource_consumer_group 和服务属性,并且指定的服务映射到资源使用者组,则优先使用 resource_consumer_group 属性中指定的资源使用者组。

• 可将作业分组以区分优先级,同一作业类中的单个作业可分配 1 到 5 之间的优先级值。

-- 如果该类中的两个作业在同一时间启动,优先级较高的作业优先。

--如果为两个作业指定的优先级值相同,则启动较早的作业优先。

-- 如果作业没有指定优先级值,则默认为 3。

4.2 窗口(Windows)

调度程序窗口:

• 可使用 CREATE_WINDOW 过程创建

• 可以在不同时间段启动 Job 或更改资源在 Job 之间的分配。Job 可以在 Window打开时启动,也可以设定在 Window 关闭时强制结束 Job 的运行。

• 多个 Window 的时间段设置可以互相重叠,但同一时间内只能启用一个 Window。可以为每个 Window 设置优先等级,当多个 Window 重叠时能够令最高等级的Window 优先启用。

区分作业优先级:

• 在类级别(通过资源计划分级)

• 在类内的作业级别(使用作业优先级的属性分级)

• 不同作业类中的作业的优先级,无法区分及保证优先执行次序。

4.3 创建作业数组(Job Array)

使用 Job Array(作业数组)是一种效率较高的创建作业集的方式,也适用于轻量作业。使用流程示例如下:

  1. 声明用于存储作业定义的变量 sys.job 和一个作业数组变量 sys.job_array;

  2. 使用 SYS.JOB_ARRAY 构造器初始化作业数组,为数组中的每个作业创建一个位置;

  3. 调整作业数组大小以存储所需的作业数量;

  4. 创建每个作业,并将作业放入作业数组中。start_time 变量被省略并默认为 NULL,表示将立即运行该作业;

  5. 使用 CREATE_JOBS 过程将数组中的所有作业作为一个事务处理提交;
    创建 Job Array示例全部代码:

    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;
    /

本篇完结。
码字不易,宝贵经验分享不易,请各位支持原创,转载注明出处,多多关注作者,后续不定期分享DB基本知识和排障案例及经验、性能调优等。

相关推荐
小han的日常23 分钟前
接口自动化环境搭建
运维·自动化
小扳25 分钟前
Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
运维·spring boot·后端·mysql·spring cloud·docker·容器
运维小文29 分钟前
服务器硬件介绍
运维·服务器·计算机网络·缓存·硬件架构
小周不摆烂35 分钟前
丹摩征文活动 | 丹摩智算平台:服务器虚拟化的璀璨明珠与实战秘籍
大数据·服务器
中云DDoS CC防护蔡蔡37 分钟前
为什么海外服务器IP会被封
服务器·经验分享
是安迪吖39 分钟前
nfs服务器
运维·服务器
鱼骨不是鱼翅41 分钟前
模拟回显服务器
运维·服务器
日里安1 小时前
8. 基于 Redis 实现限流
数据库·redis·缓存
EasyCVR1 小时前
ISUP协议视频平台EasyCVR视频设备轨迹回放平台智慧农业视频远程监控管理方案
服务器·网络·数据库·音视频
Elastic 中国社区官方博客2 小时前
使用真实 Elasticsearch 进行更快的集成测试
大数据·运维·服务器·数据库·elasticsearch·搜索引擎·集成测试