Oracle数据库——Scheduler Job

简介:

日常的运维工作中,我们经常使用Linux Server的anacron服务来使得服务器执行一下计划之内的任务,可以按照特定的时间间隔,重复的执行相关的命令或者相关的脚本,来完成预期的目标,能够节省相关的人力,使得运维变得更加容易。

对于Oracle数据库来说,当然也提供了相关的功能来实现定时的,重复的完成PL/SQL Block,Shell Scripts(其实是External Executables,在这里简单用shell脚本代替),以及Oracle本身已经编写好的Storage Procedure或者用户自定义Function。

在早期的Oracle Database中,Job就是实现了该功能的主力军,通过DBMS_JOB包就可以完成对Job的定义,修改,删除。从Oracle 10g的版本开始,Oracle提供了更强大的功能--Scheduler Job,随着功能的强大,那么定义的方式也会变的相对更加的复杂,下面我们就开始对相关的知识进行一下探讨:

 

一、Scheduler Job Concepts

这里对Scheduler Job暂且简称为Job,如果后面有对之前版本使用的Job的对比,我会把其称之为“旧版的Job”。

对于Job的概念,为了严谨,我会从官方手册上进行摘录和翻译。

详情请参照官方手册“Administrator’s Guide”文档,28章节“Oracle scheduler Concepts”。

The Scheduler provides sophisticated, flexible enterprise scheduling functionality, which you can use to:

Run database program units

 

1.You can run program units, that is, PL/SQL anonymous blocks, PL/SQL stored procedures, and Java stored procedures on the local database or on one or more remote Oracle databases.

 

2.Run external executables, (executables that are external to the database)

 

You can run external executables, such as applications, shell scripts, and batch files, on the local system or on one or more remote systems. Remote systems do not require an Oracle Database installation; they require only a Scheduler agent. Scheduler agents are available for all platforms supported by Oracle Database and some additional platforms.

 

这里详细说明了,Oracle的Scheduler不仅仅可以提供自动运行本地Oracle程序单元(包括PL/SQL匿名块,PL/SQL存储过程,JAVA存储过程),还可以运行Oracle数据库之外的本地或者远程服务器上的可以执行程序,例如应用,shell脚本或者批处理文件。甚至在远程服务器上不需要安装Oracle数据库软件。远程主机仅仅需要Oracle Scheduler的代理软件,Oracle Scheduler代理软件能部署在任何支持Oracle软件安装的平台上,还有一些附加的平台之上。

 

对于Scheduler的定义方式,Oracle提供了以下三种方式:

1.基于时间(Time-based scheduling)的日程

这种方式就是我们最常见到的,功能类似于anacron的定义方式,它可以通过指定一段时间,甚至永久的日程,来重复的在指定的时间点完成某项特定的任务。

2.基于事件(Events-based scheduling)的日程

你可以在发生系统事件或者业务事件的时候,对它们进行回应来触发相关的计划任务,在我看来,就像触发器,满足特定条件,或者发生指定事件,就可以触发相关的任务。这也是通过anacron没有办法完成的一种强大功能。

3.独立(Dependency scheduling)日程

这一类的日程是可以通过上一件日程的完成来触发的,上一次的Job完成之后,则会触发下一个Job,这样就形成了一条“作业链”(Job Chain),需要和基于事件的日程区分的是,系统事件和业务事件并不是一丁是之前的Job。

 

二、Scheduler Data Dictionary Views

 

既然需要Job来替我们完成计划任务,我们就需要对其进行监控以防止中断的进程,无效的进程以及一些始料未及的情况,下面就来介绍一下相关的数据字典表。

 

View Description

--------------------------------------------------

*_SCHEDULER_CHAIN_RULES

These views show all rules for all chains.

*_SCHEDULER_CHAIN_STEPS

These views show all steps for all chains.

*_SCHEDULER_CHAINS

These views show all chains.

*_SCHEDULER_CREDENTIALS

These views show all credentials.

*_SCHEDULER_DB_DESTS

These views show all database destinations.

*_SCHEDULER_DESTS

These views show all destinations, both database and external.

*_SCHEDULER_EXTERNAL_DESTS

These views show all external destinations.

*_SCHEDULER_FILE_WATCHERS

These views show all file watchers.

*_SCHEDULER_GLOBAL_ATTRIBUTE

These views show the current values of Scheduler attributes.

*_SCHEDULER_GROUP_MEMBERS

These views show all group members in all groups.

*_SCHEDULER_GROUPS

These views show all groups.

*_SCHEDULER_JOB_ARGS

These views show all set argument values for all jobs.

*_SCHEDULER_JOB_CLASSES

These views show all job classes.

*_SCHEDULER_JOB_DESTS

These views show the state of both local jobs and jobs at remote destinations, including child jobs of multiple-destination jobs. You obtain job destination IDs (job_dest_id) from these views.

*_SCHEDULER_JOB_LOG

These views show job runs and state changes, depending on the logging level set.

*_SCHEDULER_JOB_ROLES

These views show all jobs by Oracle Data Guard database role.

*_SCHEDULER_JOB_RUN_DETAILS

These views show all completed (failed or successful) job runs.

*_SCHEDULER_JOBS

These views show all jobs, enabled as well as disabled.

*_SCHEDULER_NOTIFICATIONS

These views show all job state e-mail notifications.

*_SCHEDULER_PROGRAM_ARGS

These views show all arguments defined for all programs as well as the default values if they exist.

*_SCHEDULER_PROGRAMS

These views show all programs.

*_SCHEDULER_RUNNING_CHAINS

These views show all chains that are running.

*_SCHEDULER_RUNNING_JOBS

These views show state information on all jobs that are currently being run.

*_SCHEDULER_SCHEDULES

These views show all schedules.

*_SCHEDULER_WINDOW_DETAILS

These views show all completed window runs.

*_SCHEDULER_WINDOW_GROUPS

These views show all window groups.

*_SCHEDULER_WINDOW_LOG

These views show all state changes made to windows.

*_SCHEDULER_WINDOWS

These views show all windows.

*_SCHEDULER_WINGROUP_MEMBERS

These views show the members of all window groups, one row for each group member.

--------------------------------------------------

 

在这里我们经常使用的视图有

*_SCHEDULER_RUNNING_JOBS:描述正在运行的Job的相关信息

*_SCHEDULER_JOB_RUN_DETAILS:描述已经完成的Job是否成功,记录相关日志的视图,这里记录着所有已经执行完毕的日程

*_SCHEDULER_SCHEDULES:描述当前数据库所有已知的日程。

*_SCHEDULER_PROGRAMS:描述当前数据库已经定义完毕的程序。

*_SCHEDULER_JOBS:描述当前数据库已经定义完毕的作业。

对于日程,程序,作业的概念会在稍后介绍,请耐心往下看。

 

三、Schedule、Program、Job Concepts

 

对于它们的概念,可以从文字的字面意思上进行理解。

首先从Job这个最核心的部分开始理解吧,Job意为作业,也就是计划任务的本质,之前说过之前版本的Oracle Database也是通过Job来定义计划任务的,只不过这里的Job和旧版本的Job不太一样,他支持更多的功能。

Job作为整个Scheduler Job的核心,他是用来描述如何完成一个作业的。

它将会定义如下内容:

1.When

何时完成该项作业,指定时间,这也是计划任务中“计划”的含义,指定确定的时间完成确定的操作或者事件。当然,该项也可以不定义,通过在Schedule(日程)中指定时间和时间间隔更加合理,之后会有相应的解释。

2.Where(Destination)

究竟Job在哪里完成,之前在Scheduler Concepts我就介绍过,Job也可以在远程的主机上完成,当然需要进行Agent的部署,如果不对该项进行定义,那么该任务默认在本地完成。

3.How

这个很重要,因为你总要知道你在特定的时间点需要做什么事情吧?在之前的Scheduler Concepts我也提到,Scheduler Job可以定义多种任务实现方式。

1)PL/SQL anonymous  Block

2)Shell Scripts

3)External Executables

我们可以在Job中定义这些Action(动作),当然也可以在Program中定义,我们稍后会讲解program。

 

 

现在我们来介绍一下schedule,日程,也就是用来定义今天或者截下来的几天,甚至今后的时间需要在某个特定的时间完成什么样的事情。

它仅仅用来定义时间和时间间隔,这样的说法比较抽象,下面用一个例子来说明:

我现在对Oracle非常感兴趣,想要对Oracle技术进行学习,那么我每天看Oracle的时间为固定1小时,不会被其他事情打扰,且必须要在17:00-20:00之间抽出一个小时,因为还有别的安排。那么我就会抽出最合理的一小时进行定义。

例如,我要在每周一到周五的19:00-20:00完成Oracle的学习,这是学习本身的时间,不能由我们定义,所以这里19-20点既不是指的时间也不是指的时间间隔,而是完成作业本身所需要的固定时间。

而19:00则是我所说的时间,也就是作业开始的时间,也就是说我会定义19点为作业的start_time。

那时间间隔是什么呢?我之前说了那就是每个周一到周五中的每一天,到了周五完成Job之后又需要72小时的等待才能进行下一次的任务。

那这里的每周一到周五的17点,就是我的Scheduler设置的时间间隔和开始时间。

那如何创建一个schedule呢?使用DBMS_SCHEDULER包就可以完成了。创建好的Job如果没有定义时间,那么就可以指定一个schedule,使用它定义的时间来完成Job。简单的来说,就是Job调用了Schedule来获取它要进行Job的时间并且参照该时间执行。

 

介绍完了schedule,那么program大家应该也就可以联想到了,也就是定义做什么事情,当Job没有定义做Action的时候则可以调用program中定义的action进行Job。

 

好了,说了那么多,究竟Oracle为什么要在新版本的Job中添加这么多的定义?最简单的例子,如果我想在同一时间做不同的很多事情,我就需要定义很多Job,那么这个Job需要定义很多次重复的时间。

如果我定义了schedule,我是否只需要将Job1~Jobn都调用同一个Schedule就好了呢?这样做事情的时间就统一了。

对于program就不用多说了吧?再简单不过的就是在不同的时间做同一间事情了,难不成你要把几百行的shell脚本定义好多遍?敲死你你也写不完。

 

四、Example

 

那么我现在想要在每天的13点对数据库进行一个全库的备份,下面就来演示一下如何去做。

首先我们需要去定义一下做什么,我们有一个备份脚本,叫做full_backup01.sh,它位于/home/oracle下。我们来查看一下它的内容。

$ cat /home/oracle/full_backup01.sh

#!/bin/bash

export ORACLE_SID=ora11g

export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1

#由于Linux执行脚本的时候会开启新的shell,不继承parent shell的环境变量,所以需要定义

export DATE=`date +%Y-%m-%d_%H:%M:%S`

export LOG=full_backup_$DATE.log

export DIR=/home/oracle/backup_log

 

if  [  ! -d “$DIR”  ]; then

mkdir -p $DIR

echo ‘Create Directory $DIR successful …’ > $DIR/$LOG

else 

$ORACLE_HOME/bin/rman  target /  << EOF

run {

spool to /home/oracle/configuration.log;

show all;

spool off;

configure retention policy to redundancy 1;

configure backup optimization on;

configure controlfile autobackup on;

spool to “$DIR/$LOG”

allocate channel c1 type disk;

allocate channel c2 type disk;

backup incremental level 0 database plus archivelog;

release channel c1;

release channel c2;

spool off;

exit;

    }

EOF

fi

这是一个非常简单的备份脚本,进行了一次0级增量备份,并且备份了archivelog,该脚本应该能够被Oracle用户执行。

$ chown oracle:oinstall /home/oracle/full_backup_01.sh

$ chmod u+x /home/oracle/full_backup_01.sh

 

首先我们来定义一个program,这个program描述了我们做什么,也就是执行该shell脚本

SQL>  BEGIN

2 DBMS_SCHEDULER.CREATE_PROGRAM(

3 program_name => ‘my_program’,

4 program_type => ‘executable’,

5 program_action => ‘/home/oracle/full_backup_01.sh’,

6 enabled => true);

7 END;

8 /

 

PL/SQL procedure successfully completed.

这里有多个参数可以定义,但是最主要的是以上四个,有了它们,这个program就可以正常运行,首先是program的名字,既然作为数据库对象,就需要一个名字,这里不再赘述。

program type。这里有三种选项:

1.PLSQL_BlOCK 

2.EXECUTABLE

3.STORED_PROCEDURE

也就对应着我之前写的三种情况,大家如果忘记了,请自行翻阅前面的内容。

program_type则对应着如何执行,对于shell脚本,执行绝对路径即可,对于其他两种,参照PLSQL语法进行写入即可。

enabled,是否开启该program,只有enabled的program才可以被Job调用,如果设置的false,想要手动启用的时候需要使用过程dbms_scheduler.enable()。

SQL> exec  DBMS_SCHEDULER.ENABLE(‘MY_PROGRAM’)

PL/SQL procedure successfully completed.

这一步对于Job也是一样的,不再赘述。

 

 

好,完成了“做什么”,下面我们来定义一下何时去做。

也就是说我们现在要定义一个schedule,对于schedule的定义相对难一些,因为要考虑如何写时间间隔。

我们下面来定义一下,每天的下午3点执行备份脚本:

SQL> BEGIN

2 DBMS_SCHEDULER.CREATE_SCHEDULE(

3 schedule_name => ‘my_schedule’,

4 start_date => systimestamp,

5 end_date => systimestamp + interval ’30’ day,

6 repeat_interval => ‘FREQ=DAILY,BYHOUR=15’,

7 comments => ‘my test backup schedule’);

8 END;

9 /

PL/SQL procedure successful completed.

这里就有一些东西要交代了,每每涉及时间的时候,大家可能会很头疼,因为不清楚,这里似乎有三个参数是关于时间的,究竟该如何设置呢。 

首先来讲一下start_date参数把。

start_date

This attribute specifies the first date and time on which this schedule becomes valid. For a repeating schedule, the value for start_date is a reference date. In this case, the start of the schedule is not the start_date; it depends on the repeat interval specified. start_date is used to determine the first instance of the schedule.

If start_date is specified in the past and no value for repeat_interval is specified, the schedule is invalid. For a repeating job or window, start_date can be derived from the repeat_interval if it is not specified.

If start_date is null, then the date that the job or window is enabled is used. start_date and repeat_interval cannot both be null.

官方文档对这个参数进行了合理的描述,这个参数指定了这个日程开始有效的时间和日期,对于一个可重复的日程,start_date是一个参考日期。

在这个例子当中,这个schedule的开始日期取决于repeat_interval的值,而不是start_date的值。

如果start_date在之前指定了,但是repeat  interval没有指定,那么这个计划是无效的,对于一个重复执行的job,start_date如果没有被设置则可以由repeat interval来决定。

如果start_date是null值,那么Job开始的时间就是Job被enable的时间,所以说,start_date和repeat_interval不能是null值。

也就是说这个Job将会在指定时间以后的第一次符合repeat interval时间间隔的时间运作。

 

所以如果创建的语句写成以下的形式:

SQL> BEGIN

2 DBMS_SCHEDULER.CREATE_SCHEDULE(

3 schedule_name => ‘my_schedule’,

4 repeat_interval => ‘FREQ=DAILY,BYHOUR=15’,

5 comments => ‘my test backup schedule’);

6 END;

7 /

PL/SQL procedure successfully completed.

则Job在调用该schedule的时候立马生效,而且永远都将不过期,而何时过期是由end_date来决定的,所以第一个例子的计划任务将会在30天以内有效。

关于repeat_interval参数就要好好的解释一下了:

这个参数有很多的字句,这里我去官方文档进行摘取子句的内容,大家大概了解一下其中的写法,有一个初步的了解。

The following examples illustrate simple repeat intervals. For simplicity, it is assumed that there is no contribution to the evaluation results by the start date.

 

Run every Friday. (All three examples are equivalent.)

 

FREQ=DAILY; BYDAY=FRI;        每个周五都运行一遍(下面两条一样)

FREQ=WEEKLY; BYDAY=FRI;

FREQ=YEARLY; BYDAY=FRI;

Run every other Friday.   

 

FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI;(每两个周五运行一次)

Run on the last day of every month.

 

FREQ=MONTHLY; BYMONTHDAY=-1;(每个月的上一天搞一下!)

Run on the next to last day of every month.

 

FREQ=MONTHLY; BYMONTHDAY=-2;(每个月的前两天搞一下!)

Run on March 10th. (Both examples are equivalent)

 

FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY=10;(每年的三月十号运行)

FREQ=YEARLY; BYDATE=0310;

Run every 10 days.

 

FREQ=DAILY; INTERVAL=10;

Run daily at 4, 5, and 6PM.

 

FREQ=DAILY; BYHOUR=16,17,18;

Run on the 15th day of every other month.

 

FREQ=MONTHLY; INTERVAL=2; BYMONTHDAY=15;

Run on the 29th day of every month.

 

FREQ=MONTHLY; BYMONTHDAY=29;

Run on the second Wednesday of each month.

 

FREQ=MONTHLY; BYDAY=2WED;

Run on the last Friday of the year.

 

FREQ=YEARLY; BYDAY=-1FRI;

Run every 50 hours.

 

FREQ=HOURLY; INTERVAL=50;

Run on the last day of every other month.

 

FREQ=MONTHLY; INTERVAL=2; BYMONTHDAY=-1;

Run hourly for the first three days of every month.

 

FREQ=HOURLY; BYMONTHDAY=1,2,3;

官方文档给了好多好多例子,这些例子确实看起来都有点厉害!真的有那么难写么?其实不是,FREQ代表的是频率,是每年,还是每个月,还是每天。

BYDAY,BYMONTH,BYMONTHDAY就代表着,哪一天,哪一个月,这个月的第几天。

而INTERVAL=n,就代表着每几个这样的间隔就执行一次。举个例子:

repeat_interval => ‘FREQ=DAILY;BYHOUR=15,16;INTERVAL=2’

那么频率就是每天,interval=2,就代表每两天,每两天的15点和16点运行一下Job。如果前面是MONTHLY,那么就是每两个月了。

不难理解吧?如果还有其他写法,在官方文档上都会有介绍。YEARLY这种表示时间间隔的词我就不在这里进行赘述了,大家可以参照官方文档的PL/SQL Packages and Types References,里面的DBMS_SCHEDULER文档阅读一下。

 

最后的核心内容则是创建一个Job了,如果运行的时间和运行的程序都在Job里进行定义,那么参数和之前的program还有schedule所定义的一样。下面我来创建一个调用之前创建的Schedule和Program的一个Job。

SQL> BEGIN

2 DBMS_SCHEDULER.CREATE_JOB(

3 job_name => ‘my_job’,

4 program_name => ‘my_program’,

5 schedule_name => ‘my_schedule’,

6 enabled => true);

7 END;

8 /

PL/SQL procedure successfully completed.

这里有个参数叫做destination_name和auto_drop,我并没有写入,第一个参数代表可以在远程数据库上或者远程主机执行,这个需要部署agent,之前提到过。

而auto_drop则代表,在这个Job在超过了自己定义的或者schedule里定义的end_date之后,会自动被drop掉,而不是被置为disable状态。

 

到此为止,我们创建和配置一个完整的Job就已经结束了。如果要对这些Job进行监控,很简单,如下视图和sql可以做到。

SQL> select schedule_name,start_date,repeat_interval,end_date 

2        from dba_scheduler_schedules

3        where lower(schedule_name) = ‘my_schedule’ ;

同理查询dba_scheduler_programs和dba_scheduler_jobs来查看program和job的相关信息。

 

如果想要看Job的执行后状态,可以使用以下SQL。

SQL> select log_id,log_date,status,additional_info 

2        from user_scheduler_job_run_details 

3        where lower(job_name)=‘my_job’;

 

转:http://blog.itpub.net/31401355/viewspace-2129311/

文章可以转载,必须以链接形式标明出处。


本文转自 张冲andy 博客园博客,原文链接:http://www.cnblogs.com/andy6/p/6158491.html    ,如需转载请自行联系原作者
相关文章
|
16天前
|
存储 Oracle 关系型数据库
数据库数据恢复—ORACLE常见故障的数据恢复方案
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。
62 11
|
29天前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。
|
1月前
|
存储 Oracle 关系型数据库
oracle数据恢复—Oracle数据库文件大小变为0kb的数据恢复案例
存储掉盘超过上限,lun无法识别。管理员重组存储的位图信息并导出lun,发现linux操作系统上部署的oracle数据库中有上百个数据文件的大小变为0kb。数据库的大小缩水了80%以上。 取出&并分析oracle数据库的控制文件。重组存储位图信息,重新导出控制文件中记录的数据文件,发现这些文件的大小依然为0kb。
|
22天前
|
存储 Oracle 关系型数据库
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
|
1月前
|
SQL Oracle 关系型数据库
Oracle数据库优化方法
【10月更文挑战第25天】Oracle数据库优化方法
54 7
|
1月前
|
Oracle 关系型数据库 数据库
oracle数据库技巧
【10月更文挑战第25天】oracle数据库技巧
32 6
|
1月前
|
存储 Oracle 关系型数据库
Oracle数据库优化策略
【10月更文挑战第25天】Oracle数据库优化策略
31 5
|
3天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
13 3
|
3天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
19 3
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2