- 浏览: 898995 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1095)
- 大数据存储 (76)
- 编程语言(Java&Scala) (46)
- 大数据建模 (33)
- 开发与管理 (8)
- 操作系统 (13)
- 实用代码集合 (25)
- 新技术研究 (15)
- 前端技术研究 (22)
- 物联网 (18)
- 兴趣探索 (15)
- 编程语言(Groovy&Grails) (92)
- 编程语言(RubyOnRails) (153)
- 个人收藏 (153)
- 技术管理 (12)
- 编程语言(Flex) (8)
- 架构和框架(GWT) (4)
- 数学和算法 (6)
- 人工智能(TensorFlow) (11)
- 编程语言(Python) (6)
- 移动开发 (4)
- 软件工程实践 (54)
- 个人感悟 (6)
- 职场感悟 (5)
- 行业经验 (23)
- 产品和运营 (10)
- 生活与随想 (155)
- 简单生活 (70)
- 天空的云 (53)
- 秋月春风 (14)
- 东逝水 (59)
- 浪花淘 (35)
- 白发渔樵 (4)
最新评论
-
cljhyjs:
今天看看在研究,已经安装好了,请问怎么一步一步使用呢?
Thingsboard -
yx200404:
说一下十维空间 -
Clear_Love:
设置了也报错
Xcode 7遇到 App Transport Security has blocked a cleartext HTTP 错误 -
wang263574375:
我想问的是,如果防火墙的设置不能改变,那么要怎么处理呢?
ORA-12571:TNS包写入程序失败 -
ralflsb:
SmartSVN 8.6
SmartSVN破解包
DBMS_JOB系统包是Oracle“任务队列”子系统的API编程接口。DBMS_JOB包对于任务队列提供了下面这些功能:提交并且执行一个任务、改变任务的执行参数以及删除或者临时挂起任务等。
DBMS_JOB包是由ORACLE_HOME目录下的rdbms/admin子目录下的DBMSJOB.SQL和PRVTJOB.PLB 这两个脚本文件创建的。这两个文件被CATPROC.SQL脚本文件调用,而CATPROC.SQL这个文件一般是在数据库创建后立即执行的。脚本为DBMS_JOB包创建了一个公共同义词,并给该包授予了公共的可执行权限,所以所有的Oracle用户均可以使用这个包。
下面几个数据字典视图是关于任务队列信息的,主要有DBA_JOBS, USER_JOBS和DBA_JOBS_RUNNING。这些字典视图是由名为CATJOBQ.SQL的脚本文件创建的。该脚本文件和创建DBMS_JOB包的脚本文件一样在ORACLE_HOME目录的rdbms/admin子目录中,同样也是由脚本文件CATPROC.SQL调用。
最后,要使任务队列能正常运行,还必须启动它自己专有的后台过程。启动后台过程是通过在初始化文件init*.ora(实例不同,初始化文件名也略有不同)中设置初始化参数来进行的。下面就是该参数:
JOB_QUEUE_PROCESSES = n
其中,n可以是0到36之间的任何一个数。除了该参数以外,还有几个关于任务队列的初始化参数,本文后面将会对其进行详细讨论。
DBMS_JOB包中包含有许多过程,见表1所示。
表1 DBMS_JOB包
名称 类型 描述
DBMS_JOB.ISUBMIT 过程 提交一个新任务,用户指定一个任务号
DBMS_JOB.SUBMIT 过程 提交一个新任务,系统指定一个任务号
DBMS_JOB.REMOVE 过程 从队列中删除一个已经存在的任务
DBMS_JOB.CHANGE 过程 更改用户设定的任务参数
DBMS_JOB.WHAT 过程 更改PL/SQL任务定义
DBMS_JOB.NEXT_DATE 过程 更改任务下一次运行时间
DBMS_JOB.INTERVAL 过程 更改任务运行的时间间隔
DBMS_JOB.BROKEN 过程 将任务挂起,不让其重复运行
DBMS_JOB.RUN 过程 在当前会话中立即执行任务
DBMS_JOB.USER_EXPORT 过程 创建文字字符串,用于重新创建一个任务
三、DBMS_JOB包参数
DBMS_JOB包中所有的过程都有一组相同的公共参数,用于定义任务,任务的运行时间以及任务定时运行的时间间隔。这些公共任务定义参数见表2所示。
表2 DBMS_JOB过程的公共参数
名称 类型 注释
Job BINARY_INTEGER 任务的唯一识别号
What VARCHAR2 作为任务执行的PL/SQL代码
Next_date VARCHAR2 任务下一次运行的时间
Interval VARCHAR2 日期表达式,用来计算下一次任务运行的时间
下面我们来详细讨论这些参数的意义及用法。
1、job
参数job是一个整数,用来唯一地标示一个任务。该参数既可由用户指定也可由系统自动赋予,这完全取决于提交任务时选用了那一个任务提交过程。DBMS_JOB.SUBMIT过程通过获得序列SYS.JOBSEQ的下一个值来自动赋予一个任务号。该任务号是作为一个OUT参数返回的,所以调用者随后可以识别出提交的任务。而DBMS_JOB.ISUBMIT过程则由调用者给任务指定一个识别号,这时候,任务号的唯一性就完全取决于调用者了。
除了删除或者重新提交任务,一般来说任务号是不能改变的。即使当数据库被导出或者被导入这样极端的情况,任务号也将被保留下来。所以在执行含有任务的数据的导入/导出操作时很可能会发生任务号冲突的现象。
2、what
what参数是一个可以转化为合法PL/SQL调用的字符串,该调用将被任务队列自动执行。在what参数中,如果使用文字字符串,则该字符串必须用单引号括起来。 what参数也可以使用包含我们所需要字符串值的VARCHAR2变量。实际的PL/SQL调用必须用分号隔开。在PL/SQL调用中如果要嵌入文字字符串,则必须使用两个单引号。
what参数的长度在Oracle7.3中限制在2000个字节以内,在Oracle 8.0以后,扩大到了4000个字节,这对于一般的应用已完全足够。该参数的值一般情况下都是对一个PL/SQL存储过程的调用。在实际应用中,尽管可以使用大匿名Pl/SQL块,但建议大家最好不要这样使用。还有一个实际经验就是最好将存储过程调用封装在一个匿名块中,这样可以避免一些比较莫名错误的产生。我来举一个例子,一般情况下,what参数可以这样引用:
what =>’my_procedure(parameter1);’
但是比较安全的引用,应该这样写:
what =>’begin my_procedure(parameter1); end;’
任何时候,我们只要通过更改what参数就可以达到更改任务定义的目的。但是有一点需要注意,通过改变what参数来改变任务定义时,用户当前的会话设置也被记录下来并成为任务运行环境的一部分。如果当前会话设置和最初提交任务时的会话设置不同,就有可能改变任务的运行行为。意识到这个潜在的副作用是非常重要的,无论何时只要应用到任何DBMS_JOB过程中的what参数时就一定要确保会话设置的正确。
3、next_date
Next_date参数是用来调度任务队列中该任务下一次运行的时间。这个参数对于DBMS_JOB.SUBMIT和DBMS_JOB.BROKEN这两个过程确省为系统当前时间,也就是说任务将立即运行。
当将一个任务的next_date参数赋值为null时,则该任务下一次运行的时间将被指定为4000年1月1日,也就是说该任务将永远不再运行。在大多数情况下,这可能是我们不愿意看到的情形。但是,换一个角度来考虑,如果想在任务队列中保留该任务而又不想让其运行,将next_date设置为null却是一个非常简单的办法。
Next_date也可以设置为过去的一个时间。这里要注意,系统任务的执行顺序是根据它们下一次的执行时间来确定的,于是将next_date参数设置回去就可以达到将该任务排在任务队列前面的目的。这在任务队列进程不能跟上将要执行的任务并且一个特定的任务需要尽快执行时是非常有用的。
4、Interval
Internal参数是一个表示Oracle合法日期表达式的字符串。这个日期字符串的值在每次任务被执行时算出,算出的日期表达式有两种可能,要么是未来的一个时间要么就是null。这里要强调一点:很多开发者都没有意识到next_date是在一个任务开始时算出的,而不是在任务成功完成时算出的。
当任务成功完成时,系统通过更新任务队列目录表将前面算出的next_date值置为下一次任务要运行的时间。当由interval表达式算出next_date是null时,任务自动从任务队列中移出,不会再继续执行。因此,如果传递一个null值给interval参数,则该任务仅仅执行一次。
通过给interval参数赋各种不同的值,可以设计出复杂运行时间计划的任务。本文后面的“任务间隔和日期算法”将对interval表达式进行详细讨论,并给出一个实际有用interval表达式的例子。
四、任务队列架构和运行环境
任务队列在Oracle系统中其实是一个子系统,它具有自己特定的后台过程和目录表。该子系统设计的目的是为了能不在用户干预下自动运行PL/SQL过程。
1、任务队列后台过程
任务队列(SNP)后台过程随着Oracle实例的启动而同时启动。在文章前面已经谈到初始化文件init.ora中的参数JOB_QUEUE_PROCESSES,用来设置有几个队列过程。这里设置了几个过程,系统中就会有几个SNP过程被启动。JOB_QUEUE_PROCESSES这个参数,可以是0到36中的任何一个数,也就是说对于每个Oracle实例最多可以有36个SNP过程,也可以不支持队列过程(=0)。在大多数操作系统中,SNP三个字母常作为过程名的一部分出现。如,在unix系统中,如果该Oracle实例名为ora8,有三个任务队列过程,则这三个任务队列过程名称为:
ora_ora8_snp0
ora_ora8_snp1
ora_ora8_snp2
SNP后台过程和其他的Oracle后台过程的一个重要区别就是杀掉一个SNP过程不会影响到Oracle实例。当一个任务队列过程失控或者消耗太多的资源时,就可以将其杀掉,当然这种情况不是经常遇到的。当一个SNP过程被杀掉或者失败时,Oracle就自动启动一个新的SNP过程来代替它。
2、有关任务队列的初始化参数
初始化文件init.ora中的几个参数控制着任务队列后台的运行,下面我们将对其进行详细讨论。
(1)、JOB_QUEUE_INTERVAL
任务队列过程定期唤醒并检查任务队列目录表是否有任务需要执行。参数JOB_QUEUE_INTERVAL决定SNP过程两次检查目录表之间“休眠”多长时间(单位为秒)。间隔设的太小会造成由于SNP过程不断检查目录表而导致不必要的系统吞吐量。相反如果间隔设得太大,SNP过程在特定的时间没有被唤醒,那个时间的任务就不会能被运行。最佳的时间间隔设置要综合考虑系统环境中不同的任务,60秒的确省设置可以满足大多数的应用。
(2)、JOB_QUEUE_KEEP_CONNECTIONS
除了前面介绍的JOB_QUEUE_PROCESS和JOB_QUEUE_INTERVAL两个参数以外,影响SNP后台过程行为的第三个参数是JOB_QUEUE_KEEP_CONNECTIONS。当该参数为TRUE时,SNP过程在两个任务的运行期间(也就是休眠期间),仍然和Oracle保持开放的连接。相反,如果为FALSE时,SNP过程将和数据库断开连接,当唤醒时刻到来时又重新连接并检查任务队列。
选择这两种方法中的那一种,主要是考虑任务队列的有效性和数据库关闭方法。长期保持连接的效率比较高,但任务队列会受到正常关闭数据库的影响。这是因为任务队列过程对于服务器管理器看来和一个普通用户的过程没有什么不同,而正常的关闭数据库需要让所有的用户都断开连接。而断开连接和重新连接又给数据库增加了负荷,但是可定期地使数据库没有可连接SNP过程,也就可以使数据库正常关闭。对于有很多任务或者是任务重复执行的时间间隔较短(一个小时或者更少)的环境,一般将JOB_QUEUE_KEEP_CONNECTIOONS设置为TRUE,并修改关闭数据库的脚本为立即关闭。对于严格要求采用正常方式关闭的数据库或者是任务较少,重复间隔较长的环境,一般将该参数设置为FALSE。最好,要提醒一句,SNP过程仅在没有任何任务运行时才断开,这种情况下,那些需要比较长时间运行的任务SNP将在它们的生命周期内一致保持开放的连接,这就延迟了正常关闭数据库的时间。
3、建立运行环境
当SNP过程唤醒时,它首先查看任务队列目录中所有的任务是否当前的时间超过了下一次运行的日期时间。SNP检测到需要该时间立即执行的任务后,这些任务按照下一次执行日期的顺序依次执行。当SNP过程开始执行一个任务时,其过程如下:
以任务所有者的用户名开始一个新的数据库会话。
当任务第一次提交或是最后一次被修改时,更改会话NLS设置和目前就绪的任务相匹配。
通过interval日期表达式和系统时间,计算下一次执行时间。
执行任务定义的PL/SQL
如果运行成功,任务的下一次执行日期(next_date)被更新,否则,失败计数加1。
经过JOB_QUEUS_INTERVAL秒后,又到了另一个任务的运行时间,重复上面的过程。
在前两步中,SNP过程创建了一个模仿用户运行任务定义的PL/SQL的会话环境。然而,这个模仿的运行环境并不是和用户实际会话环境完全一样,需要注意以下两点:第一,在任务提交时任何可用的非确省角色都将在任务运行环境中不可用。因此,那些想从非确省角色中取得权限的任务不能提交,用户确省角色的修改可以通过在任务未来运行期间动态修改来完成。第二,任何任务定义本身或者过程执行中需要的数据库联接都必须完全满足远程的用户名和密码。SNP过程不能在没有显式指明口令的情况下初始化一个远程会话。显然,SNP过程不能假定将本地用户的口令作为远程运行环境会话设置的一部分。
提交的任务如果运行失败会怎么样呢?当任务运行失败时,SNP过程在1分钟后将再次试图运行该任务。如果这次运行又失败了,下一次尝试将在2分钟后进行,再下一次在4分钟以后。任务队列每次加倍重试间隔直到它超过了正常的运行间隔。在连续16次失败后,任务就被标记为中断的(broken),如果没有用户干预,任务队列将不再重复执行。
五、任务队列字典表和视图
任务队列中的任务信息可以通过表3所示的几个字典视图来查看,这些视图是由CATJOBQ.sql脚本创建的。表4和5是各个视图每个字段的含义。
表3. 任务队列中关于任务的数据字典视图
视图名 描述
DBA_JOBS 本数据库中定义到任务队列中的任务
DBA_JOBS_RUNNING 目前正在运行的任务
USER_JOBS 当前用户拥有的任务
表4. DBA_JOBS 和 USER_JOBS.字典视图的字段含义
字段(列) 类型 描述
JOB NUMBER 任务的唯一标示号
LOG_USER VARCHAR2(30) 提交任务的用户
PRIV_USER VARCHAR2(30) 赋予任务权限的用户
SCHEMA_USER VARCHAR2(30) 对任务作语法分析的用户模式
LAST_DATE DATE 最后一次成功运行任务的时间
LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATE DATE 正在运行任务的开始时间,如果没有运行任务则为null
THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小时,分钟和秒
NEXT_DATE DATE 下一次定时运行任务的时间
NEXT_SEC VARCHAR2(8) 如HH24:MM:SS格式的next_date日期的小时,分钟和秒
TOTAL_TIME NUMBER 该任务运行所需要的总时间,单位为秒
BROKEN VARCHAR2(1) 标志参数,Y标示任务中断,以后不会运行
INTERVAL VARCHAR2(200) 用于计算下一运行时间的表达式
FAILURES NUMBER 任务运行连续没有成功的次数
WHAT VARCHAR2(2000) 执行任务的PL/SQL块
CURRENT_SESSION_LABEL RAW MLSLABEL 该任务的信任Oracle会话符
CLEARANCE_HI RAW MLSLABEL 该任务可信任的Oracle最大间隙
CLEARANCE_LO RAW MLSLABEL 该任务可信任的Oracle最小间隙
NLS_ENV VARCHAR2(2000) 任务运行的NLS会话设置
MISC_ENV RAW(32) 任务运行的其他一些会话参数
表 5. 视图DBA_JOBS_RUNNING的字段含义
列 数据类型 描述
SID NUMBER 目前正在运行任务的会话ID
JOB NUMBER 任务的唯一标示符
FAILURES NUMBER 连续不成功执行的累计次数
LAST_DATE DATE 最后一次成功执行的日期
LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATE DATE 目前正在运行任务的开始日期
THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小时,分钟和秒
六、任务重复运行间隔和间隔设计算法
任务重复运行的时间间隔取决于interval参数中设置的日期表达式。下面就来详细谈谈该如何设置interval参数才能准确满足我们的任务需求。一般来讲,对于一个任务的定时执行,有三种定时要求。
在一个特定的时间间隔后,重复运行该任务。
在特定的日期和时间运行任务。
任务成功完成后,下一次执行应该在一个特定的时间间隔之后。
第一种调度任务需求的日期算法比较简单,即'SYSDATE+n',这里n是一个以天为单位的时间间隔。表6给出了一些这种时间间隔设置的例子。
表6 一些简单的interval参数设置例子
描述 Interval参数值
每天运行一次 'SYSDATE + 1'
每小时运行一次 'SYSDATE + 1/24'
每10分钟运行一次 'SYSDATE + 10/(60*24)'
每30秒运行一次 'SYSDATE + 30/(60*24*60)'
每隔一星期运行一次 'SYSDATE + 7'
不再运行该任务并删除它 NULL
表6所示的任务间隔表达式不能保证任务的下一次运行时间在一个特定的日期或者时间,仅仅能够指定一个任务两次运行之间的时间间隔。例如,如果一个任务第一次运行是在凌晨12点,interval指定为'SYSDATE + 1',则该任务将被计划在第二天的凌晨12点执行。但是,如果某用户在下午4点手工(DBMS_JOB.RUN)执行了该任务,那么该任务将被重新定时到第二天的下午4点。还有一个可能的原因是如果数据库关闭或者说任务队列非常的忙以至于任务不能在计划的那个时间点准时执行。在这种情况下,任务将试图尽快运行,也就是说只要数据库一打开或者是任务队列不忙就开始执行,但是这时,运行时间已经从原来的提交时间漂移到了后来真正的运行时间。这种下一次运行时间的不断“漂移”是采用简单时间间隔表达式的典型特征。
第二种调度任务需求相对于第一种就需要更复杂的时间间隔(interval)表达式,表7是一些要求在特定的时间运行任务的interval设置例子。
表 7. 定时到特定日期或时间的任务例子
描述 INTERVAL参数值
每天午夜12点 'TRUNC(SYSDATE + 1)'
每天早上8点30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
每星期二中午12点 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
每个月第一天的午夜12点 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
每个季度最后一天的晚上11点 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
每星期六和日早上6点10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'
第三种调度任务需求无论通过怎样设置interval日期表达式也不能满足要求。这时因为一个任务的下一次运行时间在任务开始时才计算,而在此时是不知道任务在何时结束的。遇到这种情况怎么办呢?当然办法肯定是有的,我们可以通过为任务队列写过程的办法来实现。这里我只是简单介绍以下,可以在前一个任务队列执行的过程中,取得任务完成的系统时间,然后加上指定的时间间隔,拿这个时间来控制下一个要执行的任务。这里有一个前提条件,就是目前运行的任务本身必须要严格遵守自己的时间计划。
结论
Oracle中的定时任务是在Oracle系统中是一个非常重要的子系统,运用得当,可以极大的提高我们的系统运行和维护能力。而Oracle数据复制的延迟事务队列管理完全是基于Oracle的队列任务,对其的深刻理解有助于我们更好地管理数据复制。
DBMS_JOB包是由ORACLE_HOME目录下的rdbms/admin子目录下的DBMSJOB.SQL和PRVTJOB.PLB 这两个脚本文件创建的。这两个文件被CATPROC.SQL脚本文件调用,而CATPROC.SQL这个文件一般是在数据库创建后立即执行的。脚本为DBMS_JOB包创建了一个公共同义词,并给该包授予了公共的可执行权限,所以所有的Oracle用户均可以使用这个包。
下面几个数据字典视图是关于任务队列信息的,主要有DBA_JOBS, USER_JOBS和DBA_JOBS_RUNNING。这些字典视图是由名为CATJOBQ.SQL的脚本文件创建的。该脚本文件和创建DBMS_JOB包的脚本文件一样在ORACLE_HOME目录的rdbms/admin子目录中,同样也是由脚本文件CATPROC.SQL调用。
最后,要使任务队列能正常运行,还必须启动它自己专有的后台过程。启动后台过程是通过在初始化文件init*.ora(实例不同,初始化文件名也略有不同)中设置初始化参数来进行的。下面就是该参数:
JOB_QUEUE_PROCESSES = n
其中,n可以是0到36之间的任何一个数。除了该参数以外,还有几个关于任务队列的初始化参数,本文后面将会对其进行详细讨论。
DBMS_JOB包中包含有许多过程,见表1所示。
表1 DBMS_JOB包
名称 类型 描述
DBMS_JOB.ISUBMIT 过程 提交一个新任务,用户指定一个任务号
DBMS_JOB.SUBMIT 过程 提交一个新任务,系统指定一个任务号
DBMS_JOB.REMOVE 过程 从队列中删除一个已经存在的任务
DBMS_JOB.CHANGE 过程 更改用户设定的任务参数
DBMS_JOB.WHAT 过程 更改PL/SQL任务定义
DBMS_JOB.NEXT_DATE 过程 更改任务下一次运行时间
DBMS_JOB.INTERVAL 过程 更改任务运行的时间间隔
DBMS_JOB.BROKEN 过程 将任务挂起,不让其重复运行
DBMS_JOB.RUN 过程 在当前会话中立即执行任务
DBMS_JOB.USER_EXPORT 过程 创建文字字符串,用于重新创建一个任务
三、DBMS_JOB包参数
DBMS_JOB包中所有的过程都有一组相同的公共参数,用于定义任务,任务的运行时间以及任务定时运行的时间间隔。这些公共任务定义参数见表2所示。
表2 DBMS_JOB过程的公共参数
名称 类型 注释
Job BINARY_INTEGER 任务的唯一识别号
What VARCHAR2 作为任务执行的PL/SQL代码
Next_date VARCHAR2 任务下一次运行的时间
Interval VARCHAR2 日期表达式,用来计算下一次任务运行的时间
下面我们来详细讨论这些参数的意义及用法。
1、job
参数job是一个整数,用来唯一地标示一个任务。该参数既可由用户指定也可由系统自动赋予,这完全取决于提交任务时选用了那一个任务提交过程。DBMS_JOB.SUBMIT过程通过获得序列SYS.JOBSEQ的下一个值来自动赋予一个任务号。该任务号是作为一个OUT参数返回的,所以调用者随后可以识别出提交的任务。而DBMS_JOB.ISUBMIT过程则由调用者给任务指定一个识别号,这时候,任务号的唯一性就完全取决于调用者了。
除了删除或者重新提交任务,一般来说任务号是不能改变的。即使当数据库被导出或者被导入这样极端的情况,任务号也将被保留下来。所以在执行含有任务的数据的导入/导出操作时很可能会发生任务号冲突的现象。
2、what
what参数是一个可以转化为合法PL/SQL调用的字符串,该调用将被任务队列自动执行。在what参数中,如果使用文字字符串,则该字符串必须用单引号括起来。 what参数也可以使用包含我们所需要字符串值的VARCHAR2变量。实际的PL/SQL调用必须用分号隔开。在PL/SQL调用中如果要嵌入文字字符串,则必须使用两个单引号。
what参数的长度在Oracle7.3中限制在2000个字节以内,在Oracle 8.0以后,扩大到了4000个字节,这对于一般的应用已完全足够。该参数的值一般情况下都是对一个PL/SQL存储过程的调用。在实际应用中,尽管可以使用大匿名Pl/SQL块,但建议大家最好不要这样使用。还有一个实际经验就是最好将存储过程调用封装在一个匿名块中,这样可以避免一些比较莫名错误的产生。我来举一个例子,一般情况下,what参数可以这样引用:
what =>’my_procedure(parameter1);’
但是比较安全的引用,应该这样写:
what =>’begin my_procedure(parameter1); end;’
任何时候,我们只要通过更改what参数就可以达到更改任务定义的目的。但是有一点需要注意,通过改变what参数来改变任务定义时,用户当前的会话设置也被记录下来并成为任务运行环境的一部分。如果当前会话设置和最初提交任务时的会话设置不同,就有可能改变任务的运行行为。意识到这个潜在的副作用是非常重要的,无论何时只要应用到任何DBMS_JOB过程中的what参数时就一定要确保会话设置的正确。
3、next_date
Next_date参数是用来调度任务队列中该任务下一次运行的时间。这个参数对于DBMS_JOB.SUBMIT和DBMS_JOB.BROKEN这两个过程确省为系统当前时间,也就是说任务将立即运行。
当将一个任务的next_date参数赋值为null时,则该任务下一次运行的时间将被指定为4000年1月1日,也就是说该任务将永远不再运行。在大多数情况下,这可能是我们不愿意看到的情形。但是,换一个角度来考虑,如果想在任务队列中保留该任务而又不想让其运行,将next_date设置为null却是一个非常简单的办法。
Next_date也可以设置为过去的一个时间。这里要注意,系统任务的执行顺序是根据它们下一次的执行时间来确定的,于是将next_date参数设置回去就可以达到将该任务排在任务队列前面的目的。这在任务队列进程不能跟上将要执行的任务并且一个特定的任务需要尽快执行时是非常有用的。
4、Interval
Internal参数是一个表示Oracle合法日期表达式的字符串。这个日期字符串的值在每次任务被执行时算出,算出的日期表达式有两种可能,要么是未来的一个时间要么就是null。这里要强调一点:很多开发者都没有意识到next_date是在一个任务开始时算出的,而不是在任务成功完成时算出的。
当任务成功完成时,系统通过更新任务队列目录表将前面算出的next_date值置为下一次任务要运行的时间。当由interval表达式算出next_date是null时,任务自动从任务队列中移出,不会再继续执行。因此,如果传递一个null值给interval参数,则该任务仅仅执行一次。
通过给interval参数赋各种不同的值,可以设计出复杂运行时间计划的任务。本文后面的“任务间隔和日期算法”将对interval表达式进行详细讨论,并给出一个实际有用interval表达式的例子。
四、任务队列架构和运行环境
任务队列在Oracle系统中其实是一个子系统,它具有自己特定的后台过程和目录表。该子系统设计的目的是为了能不在用户干预下自动运行PL/SQL过程。
1、任务队列后台过程
任务队列(SNP)后台过程随着Oracle实例的启动而同时启动。在文章前面已经谈到初始化文件init.ora中的参数JOB_QUEUE_PROCESSES,用来设置有几个队列过程。这里设置了几个过程,系统中就会有几个SNP过程被启动。JOB_QUEUE_PROCESSES这个参数,可以是0到36中的任何一个数,也就是说对于每个Oracle实例最多可以有36个SNP过程,也可以不支持队列过程(=0)。在大多数操作系统中,SNP三个字母常作为过程名的一部分出现。如,在unix系统中,如果该Oracle实例名为ora8,有三个任务队列过程,则这三个任务队列过程名称为:
ora_ora8_snp0
ora_ora8_snp1
ora_ora8_snp2
SNP后台过程和其他的Oracle后台过程的一个重要区别就是杀掉一个SNP过程不会影响到Oracle实例。当一个任务队列过程失控或者消耗太多的资源时,就可以将其杀掉,当然这种情况不是经常遇到的。当一个SNP过程被杀掉或者失败时,Oracle就自动启动一个新的SNP过程来代替它。
2、有关任务队列的初始化参数
初始化文件init.ora中的几个参数控制着任务队列后台的运行,下面我们将对其进行详细讨论。
(1)、JOB_QUEUE_INTERVAL
任务队列过程定期唤醒并检查任务队列目录表是否有任务需要执行。参数JOB_QUEUE_INTERVAL决定SNP过程两次检查目录表之间“休眠”多长时间(单位为秒)。间隔设的太小会造成由于SNP过程不断检查目录表而导致不必要的系统吞吐量。相反如果间隔设得太大,SNP过程在特定的时间没有被唤醒,那个时间的任务就不会能被运行。最佳的时间间隔设置要综合考虑系统环境中不同的任务,60秒的确省设置可以满足大多数的应用。
(2)、JOB_QUEUE_KEEP_CONNECTIONS
除了前面介绍的JOB_QUEUE_PROCESS和JOB_QUEUE_INTERVAL两个参数以外,影响SNP后台过程行为的第三个参数是JOB_QUEUE_KEEP_CONNECTIONS。当该参数为TRUE时,SNP过程在两个任务的运行期间(也就是休眠期间),仍然和Oracle保持开放的连接。相反,如果为FALSE时,SNP过程将和数据库断开连接,当唤醒时刻到来时又重新连接并检查任务队列。
选择这两种方法中的那一种,主要是考虑任务队列的有效性和数据库关闭方法。长期保持连接的效率比较高,但任务队列会受到正常关闭数据库的影响。这是因为任务队列过程对于服务器管理器看来和一个普通用户的过程没有什么不同,而正常的关闭数据库需要让所有的用户都断开连接。而断开连接和重新连接又给数据库增加了负荷,但是可定期地使数据库没有可连接SNP过程,也就可以使数据库正常关闭。对于有很多任务或者是任务重复执行的时间间隔较短(一个小时或者更少)的环境,一般将JOB_QUEUE_KEEP_CONNECTIOONS设置为TRUE,并修改关闭数据库的脚本为立即关闭。对于严格要求采用正常方式关闭的数据库或者是任务较少,重复间隔较长的环境,一般将该参数设置为FALSE。最好,要提醒一句,SNP过程仅在没有任何任务运行时才断开,这种情况下,那些需要比较长时间运行的任务SNP将在它们的生命周期内一致保持开放的连接,这就延迟了正常关闭数据库的时间。
3、建立运行环境
当SNP过程唤醒时,它首先查看任务队列目录中所有的任务是否当前的时间超过了下一次运行的日期时间。SNP检测到需要该时间立即执行的任务后,这些任务按照下一次执行日期的顺序依次执行。当SNP过程开始执行一个任务时,其过程如下:
以任务所有者的用户名开始一个新的数据库会话。
当任务第一次提交或是最后一次被修改时,更改会话NLS设置和目前就绪的任务相匹配。
通过interval日期表达式和系统时间,计算下一次执行时间。
执行任务定义的PL/SQL
如果运行成功,任务的下一次执行日期(next_date)被更新,否则,失败计数加1。
经过JOB_QUEUS_INTERVAL秒后,又到了另一个任务的运行时间,重复上面的过程。
在前两步中,SNP过程创建了一个模仿用户运行任务定义的PL/SQL的会话环境。然而,这个模仿的运行环境并不是和用户实际会话环境完全一样,需要注意以下两点:第一,在任务提交时任何可用的非确省角色都将在任务运行环境中不可用。因此,那些想从非确省角色中取得权限的任务不能提交,用户确省角色的修改可以通过在任务未来运行期间动态修改来完成。第二,任何任务定义本身或者过程执行中需要的数据库联接都必须完全满足远程的用户名和密码。SNP过程不能在没有显式指明口令的情况下初始化一个远程会话。显然,SNP过程不能假定将本地用户的口令作为远程运行环境会话设置的一部分。
提交的任务如果运行失败会怎么样呢?当任务运行失败时,SNP过程在1分钟后将再次试图运行该任务。如果这次运行又失败了,下一次尝试将在2分钟后进行,再下一次在4分钟以后。任务队列每次加倍重试间隔直到它超过了正常的运行间隔。在连续16次失败后,任务就被标记为中断的(broken),如果没有用户干预,任务队列将不再重复执行。
五、任务队列字典表和视图
任务队列中的任务信息可以通过表3所示的几个字典视图来查看,这些视图是由CATJOBQ.sql脚本创建的。表4和5是各个视图每个字段的含义。
表3. 任务队列中关于任务的数据字典视图
视图名 描述
DBA_JOBS 本数据库中定义到任务队列中的任务
DBA_JOBS_RUNNING 目前正在运行的任务
USER_JOBS 当前用户拥有的任务
表4. DBA_JOBS 和 USER_JOBS.字典视图的字段含义
字段(列) 类型 描述
JOB NUMBER 任务的唯一标示号
LOG_USER VARCHAR2(30) 提交任务的用户
PRIV_USER VARCHAR2(30) 赋予任务权限的用户
SCHEMA_USER VARCHAR2(30) 对任务作语法分析的用户模式
LAST_DATE DATE 最后一次成功运行任务的时间
LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATE DATE 正在运行任务的开始时间,如果没有运行任务则为null
THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小时,分钟和秒
NEXT_DATE DATE 下一次定时运行任务的时间
NEXT_SEC VARCHAR2(8) 如HH24:MM:SS格式的next_date日期的小时,分钟和秒
TOTAL_TIME NUMBER 该任务运行所需要的总时间,单位为秒
BROKEN VARCHAR2(1) 标志参数,Y标示任务中断,以后不会运行
INTERVAL VARCHAR2(200) 用于计算下一运行时间的表达式
FAILURES NUMBER 任务运行连续没有成功的次数
WHAT VARCHAR2(2000) 执行任务的PL/SQL块
CURRENT_SESSION_LABEL RAW MLSLABEL 该任务的信任Oracle会话符
CLEARANCE_HI RAW MLSLABEL 该任务可信任的Oracle最大间隙
CLEARANCE_LO RAW MLSLABEL 该任务可信任的Oracle最小间隙
NLS_ENV VARCHAR2(2000) 任务运行的NLS会话设置
MISC_ENV RAW(32) 任务运行的其他一些会话参数
表 5. 视图DBA_JOBS_RUNNING的字段含义
列 数据类型 描述
SID NUMBER 目前正在运行任务的会话ID
JOB NUMBER 任务的唯一标示符
FAILURES NUMBER 连续不成功执行的累计次数
LAST_DATE DATE 最后一次成功执行的日期
LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATE DATE 目前正在运行任务的开始日期
THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小时,分钟和秒
六、任务重复运行间隔和间隔设计算法
任务重复运行的时间间隔取决于interval参数中设置的日期表达式。下面就来详细谈谈该如何设置interval参数才能准确满足我们的任务需求。一般来讲,对于一个任务的定时执行,有三种定时要求。
在一个特定的时间间隔后,重复运行该任务。
在特定的日期和时间运行任务。
任务成功完成后,下一次执行应该在一个特定的时间间隔之后。
第一种调度任务需求的日期算法比较简单,即'SYSDATE+n',这里n是一个以天为单位的时间间隔。表6给出了一些这种时间间隔设置的例子。
表6 一些简单的interval参数设置例子
描述 Interval参数值
每天运行一次 'SYSDATE + 1'
每小时运行一次 'SYSDATE + 1/24'
每10分钟运行一次 'SYSDATE + 10/(60*24)'
每30秒运行一次 'SYSDATE + 30/(60*24*60)'
每隔一星期运行一次 'SYSDATE + 7'
不再运行该任务并删除它 NULL
表6所示的任务间隔表达式不能保证任务的下一次运行时间在一个特定的日期或者时间,仅仅能够指定一个任务两次运行之间的时间间隔。例如,如果一个任务第一次运行是在凌晨12点,interval指定为'SYSDATE + 1',则该任务将被计划在第二天的凌晨12点执行。但是,如果某用户在下午4点手工(DBMS_JOB.RUN)执行了该任务,那么该任务将被重新定时到第二天的下午4点。还有一个可能的原因是如果数据库关闭或者说任务队列非常的忙以至于任务不能在计划的那个时间点准时执行。在这种情况下,任务将试图尽快运行,也就是说只要数据库一打开或者是任务队列不忙就开始执行,但是这时,运行时间已经从原来的提交时间漂移到了后来真正的运行时间。这种下一次运行时间的不断“漂移”是采用简单时间间隔表达式的典型特征。
第二种调度任务需求相对于第一种就需要更复杂的时间间隔(interval)表达式,表7是一些要求在特定的时间运行任务的interval设置例子。
表 7. 定时到特定日期或时间的任务例子
描述 INTERVAL参数值
每天午夜12点 'TRUNC(SYSDATE + 1)'
每天早上8点30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
每星期二中午12点 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
每个月第一天的午夜12点 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
每个季度最后一天的晚上11点 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
每星期六和日早上6点10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'
第三种调度任务需求无论通过怎样设置interval日期表达式也不能满足要求。这时因为一个任务的下一次运行时间在任务开始时才计算,而在此时是不知道任务在何时结束的。遇到这种情况怎么办呢?当然办法肯定是有的,我们可以通过为任务队列写过程的办法来实现。这里我只是简单介绍以下,可以在前一个任务队列执行的过程中,取得任务完成的系统时间,然后加上指定的时间间隔,拿这个时间来控制下一个要执行的任务。这里有一个前提条件,就是目前运行的任务本身必须要严格遵守自己的时间计划。
结论
Oracle中的定时任务是在Oracle系统中是一个非常重要的子系统,运用得当,可以极大的提高我们的系统运行和维护能力。而Oracle数据复制的延迟事务队列管理完全是基于Oracle的队列任务,对其的深刻理解有助于我们更好地管理数据复制。
发表评论
-
期货交易的秘密
2022-09-28 12:31 20期货交易盈利的逻辑,简单来说就是4个字:大赚小亏。 赚钱的时 ... -
一个未了的心结
2022-09-27 14:16 87我有一个未了的心结, 就是攻克癌症, 我后面不管做啥, 挣了钱 ... -
生是一场自我实现的预言
2022-03-15 15:21 0术力之限要靠道力突破, 道力之限要靠心力突破, 人生是一场自我 ... -
人生是一场自我实现的预言
2022-03-15 14:25 533术力之限要靠道力突破, 道力之限要靠心力突破, 人生是一场自我 ... -
物联网大数据平台
2021-01-28 15:29 310TDengine是专为物联网、车联网、工业互联网、IT运维等设 ... -
大数据平台CDH搭建指南
2021-01-28 15:26 285CDH和CM介绍及搭建 http://www.fblinux. ... -
使用Flume+Logstash+Kafka+Spark Streaming进行实时日志处理分析【公安大数据】
2018-09-20 16:53 1138使用Flume+Logstash+Kafka+Spark St ... -
Cloudera Hadoop运维管理与性能调优
2018-09-17 18:53 635Cloudera Hadoop运维管理与性能调优 -
CIO
2018-08-30 11:34 339一个企业的运营过程,不论其身处哪个行业,其实都是一个信 ... -
Hadoop与MPP是什么关系?有什么区别和联系?
2018-08-29 11:17 1599Hadoop与MPP是什么关系?有什么区别和联系? -
大数据资料
2018-05-25 09:44 245大数据资料 -
大数据相关的一些内容和知识
2018-04-22 20:38 354一、大数据通用处理平 ... -
难念的经
2018-03-27 12:13 421“笑你我枉花光心计 爱 ... -
办公室里面小屁就没有掌握自己命运的资格
2018-02-07 10:03 437办公室里面小屁就没有掌握自己命运的资格。 -
一个成熟的自动化运维系统具备什么功能?
2018-02-05 16:57 348一个成熟的自动化运维系统具备什么功能? -
我国“十三五”国家大数据战略离不开专业的数据中心基础设施运维服务
2017-11-21 15:35 496我国“十三五”国家大数据战略离不开专业的数据中心基础设施运维服 ... -
千万级记录的Discuz论坛导致MySQL CPU 100%的优化笔记
2016-07-08 12:15 819千万级记录的Discuz论坛导致MySQL CPU 100%的 ... -
Oralce表被锁了,咋办?
2015-11-02 10:27 6431.下面的语句用来查询哪些对象被锁: select objec ... -
id oracle
2013-11-21 13:14 681SQL> startup ORA-27125: una ... -
一个sql简单关于分组的sql
2013-05-14 16:36 766select * from ( select aa.pe ...
相关推荐
Oracle 定时任务不能自动执行的检查修复步聚 Oracle 定时任务是 Oracle 数据库中的一种功能,可以根据设置的计划执行某些任务。但是,在某些情况下,Oracle 定时任务可能不能自动执行。这可能是由于某个版本的 BUG...
通过合理地利用Oracle定时任务,可以极大地提高系统的运行效率和维护能力。 #### 二、Oracle定时任务的基础概念 在深入探讨Oracle定时任务之前,我们需要先了解几个基础的概念: - **Job**:Oracle定时任务的基本...
### Oracle定时任务实现方法 #### 一、使用`DBMS_JOB` 在Oracle数据库中,`DBMS_JOB`包提供了一种简单的方式来安排周期性或一次性的工作。以下将详细介绍如何使用`DBMS_JOB`来创建、运行和管理定时任务。 ##### ...
5. **文件名称列表**:`oracle定时任务`和`存储过程`这两个文件名可能是指包含有关如何在实际环境中设置和使用这些功能的文档或脚本。在学习和实践中,可以参考这些文件以获取更具体的步骤和示例。 综上所述,...
Oracle定时任务,是数据库管理中的一个重要组成部分,它允许系统管理员或开发者按照预定义的时间间隔执行特定的任务,如数据备份、清理、报表生成等。在Oracle中,这种功能通常通过DBMS_SCHEDULER或以前的DBMS_JOB包...
-- job 创建 begin dbms_scheduler.create_job ( job_name => 'AGENT_LIQUIDATION_JOB', ... job_type => 'STORED_PROCEDURE', ... job_action => 'AGENT_LIQUIDATION.LIQUIDATION', --存储过程名 ...
Oracle定时任务,也被称为Oracle调度(Oracle Scheduler),是Oracle数据库系统中的一个重要组件,用于安排数据库内的作业自动执行。这些作业可以包括数据备份、清理过期记录、运行统计分析等日常维护任务。Oracle ...
Oracle的定时任务,通常被称为“Jobs”,是数据库管理系统中的一个重要组成部分,主要用于自动化执行数据库操作,如数据备份、数据清理、报告生成等。Job界面管理工具则为这些任务提供了图形化的配置和管理界面,...
Oracle定时任务详解主要涉及到Oracle数据库中的DBMS_JOB包,这是一个用于在数据库级别执行定时任务的工具,特别适合处理大量表级别的操作,以提高效率并减少系统级别的编程工作和潜在错误。Oracle的作业队列管理器...
Oracle定时任务机制主要依赖于`DBMS_JOB`系统包,它是Oracle数据库提供的任务调度API,允许用户提交、修改、删除和控制定时任务。`DBMS_JOB`包在Oracle数据库安装后,通过`ORACLE_HOME/rdbms/admin`目录下的`DBMSJOB...
根据提供的文件信息,本文将详细解释Oracle定时任务的创建与管理方法,并且这些步骤和示例均已在Oracle 817版本下进行了测试。 ### 一、创建表 首先,我们需要创建一个表来存储定时任务处理的数据。在这个例子中,...
Oracle定时任务,通常被称为DBMS_JOB,是一种在Oracle数据库中实现定时执行任务的机制。它允许用户安排PL/SQL代码块在预设的时间点或按照特定的间隔执行,无需依赖操作系统级别的定时任务如Windows的任务计划程序或...
### DBMS_JOB包创建Oracle定时任务详解 在Oracle数据库中,`DBMS_JOB`包提供了一种机制,用于创建和管理后台作业(Job),这些作业可以在特定的时间或按一定的时间间隔执行。这对于需要定期执行的任务非常有用,...
#### 一、Oracle定时任务概述 Oracle定时任务是数据库管理系统中的一个强大特性,允许用户在预设的时间点自动执行特定的数据库操作,如数据备份、数据清洗、报告生成等。这一功能主要通过Oracle的`DBMS_JOB`包实现...
Oracle的Job Queue是数据库级别的定时任务管理工具,它允许用户在数据库内部定义并调度任务,无需依赖操作系统级别的定时任务如Windows的任务计划程序或Unix的cron。这种机制在处理大量数据库操作时尤其有效,因为它...
Oracle 定时 EXP 文件到 FTP 服务器(Solaris) 一、Oracle 数据备份概述 在企业中的数据库管理中,数据备份是非常重要的一步骤。 Oracle 数据库作为一个强大的关系数据库管理系统,它提供了多种方式来备份数据。...
Oracle Job 定时任务 Oracle Job 定时任务是 Oracle 数据库中的一种定时执行任务的机制,它允许用户在指定的时间点或每天的某个时间点自行执行任务。 一、查询系统中的 Job 可以通过以下视图查询系统中的 Job: *...