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

Oracle 创建job容易出现的问题
以前没接触过job,job其实用起来比较简单,但也有一些容易犯错的地方,这里跟小伙伴们分享一下。

Oracle job用来完成定时的任务,比如定时更新数据,定义统计数据生成报表等等,这些都可以使用Oracle的Job来完成。

在执行一个job之前得做以下工作:

1.创建一个执行创建操作的存储过程

2.创建JOB

当然创建job可以写代码,也可以用图形化界面来进行操作。

例如下面代码:

begin
  sys.dbms_job.submit(job => :job,
                      what => 'PRC_CC_UPDATE_MARKETING_TICKET;',
                      next_date => to_date('01-01-4000', 'dd-mm-yyyy'),
                      interval => 'sysdate+1/1440');
  sys.dbms_job.broken(job => :job,
                      broken => true,
                      next_date => to_date('01-01-4000', 'dd-mm-yyyy'));
  commit;
end;
/

当然也可以用图形化界面:



在上图中,红色字体标注的是一些容易犯错的地方。

这里需要注意的是,

在submit方法的前面一定要先定义job这个变量(如果有需要,也可以用默认的:job),另外,submit方法的第二个参数是一个存储过程的名,记得在后面添加“:”号,在next_date是一个时间类型变量而不是一个字符串,所以需要注意不要把它当成字符串,不需要对该参数加引号。最后一个参数interval是一个字符串类型,记得添加引号。

3.执行job

在运行job的过程中,会有一些异常情况,可以通过以下方法进行排查:

1.先来了解一下JOB的参数说明:与job相关的参数一个是job_queue_processes,这个是运行JOB时候所起的进程数,当然系统里面JOB

大于这个数值后,就会有排队等候的,最小值是0,表示不运行JOB,最大值是36,在OS上对应的进程时SNPn,9i以后OS上管理JOB的进程叫CJQn.可以使用下面这个SQL确定目前有几个SNP/CJQ在运行。


select * from v$bgprocess,这个paddr不为空的snp/cjq进程就是目前空闲的进程,有的表示正在工作的进程。另外一个是job_queue_interval,范围在1——3600之间,单位是秒,这个是唤醒JOB的process,因为每次snp运行完他就休息了,需要定期唤醒他,这个值不能太小,太小会影响数据库的性能。
2.诊断:先确定上面这两个参数设置是否正确,特别是第一个参数,设置为0了,所有JOB就不会跑,确认无误后,我们继续向下。


3.

使用下面的SQL察看JOB的broken,last_date和next_date,last_date是指最近一次job运行成功的结束时间,next_date是根据设置的频率计算的下次执行时间,根据这个信息就可以判断JOB上次是否正常,还可以判断下次的时间对不对,SQL如下:select * from dba_jobs 有时候我们发现他的next_date是4000年1月1日,说明job要不就是在running,要不就是状态是break(broken=Y),如果发现JOB的broken值为Y,找用户了解一下,确定该JOB是否可以broken,如果不能broken,那就把broken值修改成N,修改再使用上面的SQL察看就发现他的last_date已经变了,JOB即可正常运行,修改broken状态的SQL如下:

declare

begin


DBMS_JOB.BROKEN(,FALSE)


end


4.使用下面的SQL查询是否JOB还在Running

select * from dba_jobs_running


如果发现JOB已经Run了很久了还没有结束,就要查原因了。一般的JOB running时会锁定相关的相关的资源,可以查看一下v$access和v$locked_object这两个

view,如果发现其他进程锁定了与JOB相关的Object,包括PKG/Function/Procedure/Table等资源,那么就要把其他进程删除,有必要的话,把JOB的进程也删除,再重新跑看看结果.


5.如果上面都正常,但是JOB还不run,怎么办?那我们要考虑把JOB进程重启一次,防止是SNP进程死了造成JOB不跑,指令如下:


alter system set job_queue_processes=0 ——关闭job进程,等待5-10秒钟


alter system set job_quene_processes=5 ——恢复原来的值