日期:2014-05-16  浏览次数:20418 次

JOB执行时间不断推后的问题

作者:iamlaosong

 

工作中我们经常用Oracle的JOB执行一些定时任务,实践中我们发现,设定执行时间和间隔后,每次执行的时间都会有点延迟,经过一段时间后,推迟累计的效应就相当明显,必须要重新调整时间才能满足要求,为什么会出现这种现象呢?经过研究,我们发现了问题所在。下面举例说明这个问题。

建立一个JOB,内容为插入系统时间到数据库,执行间隔为1分钟,即inteval是sysdate+1/(24*60),我们发现记录的时间是不断推迟的,即:

2012-06-27 12:32:08
2012-06-27 12:33:13
2012-06-27 12:34:18
2012-06-27 12:35:23
2012-06-27 12:36:28
2012-06-27 12:37:33
2012-06-27 12:38:38

检查JOB的执行时间,发现也是不断推后的,发生这种现象的原因是什么呢?

原因是计算下次执行时间用的间隔是sysdate+1/(24*60),可能是JOB的启动要时间或者是扫描精度的原因,计算下次执行时间时用的标准时间已经不是启动JOB的时间,而是推迟几秒,所以下次执行时间会不断推迟,找到问题所在,解决起来也就简单了,那就是选一个标准时间计算下次执行时间。如果每分钟执行一次,我们可以将当前时间截取到分钟作为标准时间,

inteval 取trunc(sysdate,'mi')+1/(24*60),这样就不会有累积效应了。看执行结果:
2012-06-27 12:42:03
2012-06-27 12:43:03
2012-06-27 12:44:03
2012-06-27 12:45:03
2012-06-27 12:46:03
2012-06-27 12:47:03
2012-06-27 12:48:03

对于不同的间隔,时间截取可以采用不同的精度,比如每天执行一次,可以用trunc(sysdate,'dd')将时间截取到00:00:00,如每天2:00执行,inteval 取trunc(sysdate,'dd')+2/24+1或者trunc(sysdate)+2/24+1就可以了。

关于trunc截断日期的用法,可以查相关资料。JOB的执行时间有以下实验结论:

1、JOB在运行结束之后才会更新next_date,但是计算的方法是JOB刚开始的时间加上interval设定的间隔。

2、如果interval的时长短于JOB执行的时间,作业仍然会继续进行,只是执行间隔变为了JOB真实运行的时长。

3、用于计算next_date的JOB启动时间总是比设定的时间推迟几秒,原因可能是JOB的启动时间或者是扫描精度。

4、如果JOB因为某些原因延迟执行了一次,就会导致下一次的执行时间也同样顺延了,如本文所描述的延迟累积。因此用正确的时间间隔就很重要。比如,我们要JOB在每天的凌晨2:30执行而不管上次执行到底是几点,设置interval为trunc(sysdate)+2.5/24+1就可以了。

 

 

附:oracle JOB常见的执行时间 

1、每分钟执行
TRUNC(sysdate,'mi')+1/(24*60)

2、每天定时执行