|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
平台即服务PaaS、基础设施即服务IaaS、软件即服务SaaS都是我们比较熟悉的MySQL学习教程,现在又出现了数据库即服务DBaaS,以基于云的方式存储结构化数据。oracle
Oracle功课(JOB)更新next_date的切磋
本文kamus(kamus@itpub.net)
择要:本文经由过程实行和事务跟踪来剖析OracleJob实行过程当中修正下次实行工夫的机制。
有些人问,Oracle的JOB在设定完next_date和interval以后,究竟是甚么时分决意下一次运转工夫的。能够归结成以下几个成绩。
1.假定我们的JOB设定第一次运转的工夫是12:00,运转的距离是1小时,JOB运转必要耗时30分钟,那末第二次运转是在13:00仍是13:30?
2.假如是在13:00那是否是申明只需JOB一入手下手运转,next_date就被从头盘算了?
3.JOB的下一次运转会遭到上一次运转工夫的影响吗?假如遭到影响,怎样能够制止这个影响而让JOB在天天的指准时刻运转?
本文经由过程一些实行和跟踪来注释下面的一切成绩。
起首我们选择一个测试用户,假定该用户名为kamus。
因为我们在实行用的存储过程当中会用到dbms_lock包,以是必要由sys用户先授与kamus用户利用dbms_lock包的权限。
d:Temp>sqlplus"/assysdba"
SQL*Plus:Release9.2.0.5.0-Productionon礼拜三12月123:56:322004
Copyright(c)1982,2002,OracleCorporation.Allrightsreserved.
毗连到:
Oracle9iEnterpriseEditionRelease9.2.0.5.0-Production
WiththePartitioning,OLAPandOracleDataMiningoptions
JServerRelease9.2.0.5.0-Production
SQL>grantexecuteondbms_locktokamus;
受权乐成。
然后用kamus用户登录数据库,创立我们测试利用的存储历程sp_test_next_date。
createorreplaceproceduresp_test_next_dateas
p_jobnonumber;
P_nextdatedate;
begin
--将挪用此存储历程的job的next_date设置为30分钟今后
selectjobintop_jobnofromuser_jobswherewhat=sp_test_next_date;;
executeimmediatebegindbms_job.next_date(||to_char(p_jobno)||,sysdate+1/48);commit;end;;
--修正终了今后反省user_jobs视图,输入job今朝的next_date
selectnext_date
intoP_nextdate
fromuser_jobs
wherewhat=sp_test_next_date;;
dbms_output.put_line(JOB实行中的next_date:||
to_char(p_nextdate,YYYY-MM-DDHH24:MI:SS));
--守候10秒再加入实行
dbms_lock.sleep(seconds=>10);
endsp_test_next_date;
创立挪用该存储历程的JOB,界说interval为天天一次,也就是此次实行今后,下次实行工夫应当在1天今后。
SQL>variablejobnonumber;
SQL>BEGIN
2DBMS_JOB.SUBMIT(job=>:jobno,
3what=>sp_test_next_date;,
4next_date=>SYSDATE,
5interval=>SYSDATE+1);
6COMMIT;
7END;
8/
PL/SQL历程已乐成完成。
jobno
---------
1
然后我们手工实行存储历程,实行终了今后再手工从user_jobs视图中取得JOB的下次实行工夫,能够看到在存储过程当中修正的JOB的下次实行工夫已失效,酿成了以后工夫的30分钟今后,而不是默许的1天今后。
SQL>connkamus
请输出口令:
已毗连。
SQL>setserverouton
SQL>execsp_test_next_date();
JOB实行中的next_date:2004-12-0200:44:11
PL/SQL历程已乐成完成。
SQL>colnext_datefora20
SQL>selectto_char(next_date,YYYY-MM-DDHH24:MI:SS)next_datefromuser_jobs
wherewhat=sp_test_next_date;;
NEXT_DATE
--------------------
2004-12-0200:44:11
我们再手工运转JOB,看看此次的了局,能够发明JOB没有运转终了之前被修正了的下次运转工夫跟JOB运转终了今后再次手工检索user_jobs视图取得的下次运转工夫已不不异了。由此我们能够得出一个结论,next_date是在JOB运转终了今后被Oracle主动修正的,而不是在JOB刚入手下手运转的时分,由于我们在存储过程当中修正的next_date在JOB运转停止以后又被修正为默许的1天今后了。
SQL>execdbms_job.run(1);
JOB实行中的next_date:2004-12-0200:54:52
PL/SQL历程已乐成完成。
SQL>selectto_char(next_date,YYYY-MM-DDHH24:MI:SS)next_datefromuser_jobs
wherewhat=sp_test_next_date;;
NEXT_DATE
--------------------
2004-12-0300:24:52
如今我们再次修正存储历程,输入存储历程入手下手实行的工夫,便于跟实行终了今后的JOB下次实行工夫举行对照。
createorreplaceproceduresp_test_next_dateas
p_jobnonumber;
P_nextdatedate;
begin
--输入JOB刚入手下手实行的工夫
dbms_output.put_line(JOB入手下手实行的工夫:||
to_char(sysdate,YYYY-MM-DDHH24:MI:SS));
--将挪用此存储历程的job的next_date设置为30分钟今后
selectjobintop_jobnofromuser_jobswherewhat=sp_test_next_date;;
executeimmediatebegindbms_job.next_date(||to_char(p_jobno)||,sysdate+1/48);commit;end;;
--修正终了今后反省user_jobs视图,输入job今朝的next_date
selectnext_date
intoP_nextdate
fromuser_jobs
wherewhat=sp_test_next_date;;
dbms_output.put_line(JOB实行中的next_date:||
to_char(p_nextdate,YYYY-MM-DDHH24:MI:SS));
--守候10秒再加入实行
dbms_lock.sleep(seconds=>10);
endsp_test_next_date;
从头举行测试,我们能够发明JOB的next_date是JOB入手下手实行工夫的1天今后,而不是JOB停止工夫的1天今后(由于JOB停止必要经由10秒钟)
SQL>execdbms_job.run(1);
JOB入手下手实行的工夫:2004-12-0200:38:24
JOB实行中的next_date:2004-12-0201:08:24
PL/SQL历程已乐成完成。
SQL>selectto_char(next_date,YYYY-MM-DDHH24:MI:SS)next_datefromuser_jobs
wherewhat=sp_test_next_date;;
NEXT_DATE
--------------------
2004-12-0300:38:24
至此,我们已申明了两个成绩。就是:JOB在运转停止以后才会更新next_date,可是盘算的办法是JOB刚入手下手的工夫加上interval设定的距离。
上面我们经由过程trace来再次求证这个结论。
SQL>ALTERSESSIONSETEVENTS10046tracenamecontextforever,level12;
会话已变动。
SQL>execdbms_job.run(1);
PL/SQL历程已乐成完成。
SQL>ALTERSESSIONSETEVENTS10046tracenamecontextoff;
会话已变动。
实行终了今后在udump目次中检察天生的trace文件。假如我们用tkprof来格局化这个trace文件然后再检察格局化后的了局,我们会感应很惊奇。由于在格局化终了的SQL实行按次中,更新job$表的语句呈现在dbms_job.next_date语句之前,也就是看上往是Oracle先依照interval主动更新了JOB的next_date,然后才持续往下实行存储过程当中界说的next_date更新语句,而如许明显没法注释我们在下面的实行中看到的了局。
可是当我们跳过tkprof而间接往检察天生的trace文件,就会名顿开,同时也印证了steveadams在ixora上提到的概念:tkprof格局化完的了局会省略一些信息,乃至在偶然候会给我们毛病的信息。
间接检察trace文件,我们能够看到以下的实行按次:
1.parsecursor#10(oracle依据interval和先前保留的this_date字段值更新job$表的语句,包含更新failures,last_date,next_date,total等)
2.parsecursor#15(存储过程当中的begindbms_job.next_date语句)
3.bindscursor#15(将加上了30分钟的工夫绑定到cursor#15上)
4.execcursor#15(实行cursor#15)
5.waitcursor#11(履历一个PL/SQLlocktimer事务,也就是存储过程当中实行的dbms_lock.sleep办法)
6.bindscursor#10(将JOB刚入手下手实行时分的工夫绑定到cursor#10上)
7.execcursor#10(实行cursor#10)
也就是说固然更新job$的语句被很早地剖析过了,可是直到JOB运转停止时这个被剖析过的游标才入手下手作变量绑定进而入手下手实行。
恰是由于剖析updatesys.job$语句的工夫早于剖析begindbms_job.next_date语句的工夫,以是tkprof的了局将前者放在了后面。
因为trace文件太长,以是不在本文中贴出了,假如有乐趣能够发邮件给我。我的邮件地点是:kamus@itpub.net
本文的最初一部分,解答本文开首提出的第三个成绩,也就是:
JOB的下一次运转会遭到上一次运转工夫的影响吗?假如遭到影响,怎样能够制止这个影响而让JOB在天天的指准时刻运转?
JOB的下一次运转工夫是会受上一次影响的,假如我们的interval仅仅是sysdate+1/24如许的情势的话,无疑,前次实行的工夫再加上1小时就是下次实行的工夫。那末假如JOB由于某些缘故原由提早实行了一次,如许就会招致下一次的实行工夫也一样顺延了,这一般不是我们但愿呈现的征象。
办理办法很复杂,只必要设定准确的interval就能够了。
好比,我们要JOB在天天的清晨3:30实行而不论前次实行究竟是几点,只必要设置interval为trunc(SYSDATE)+3.5/24+1便可。完全的SQL以下:
SQL>variablejobnonumber;
SQL>BEGIN
2DBMS_JOB.SUBMIT(job=>:jobno,
3what=>sp_test_next_date;,
4next_date=>SYSDATE,
5interval=>trunc(SYSDATE)+3.5/24+1);
6COMMIT;
7END;
8/
BTW:在trace文件中发明固然经由过程selectrowidfromtable前往的了局已是扩大ROWID格局(DataObjectnumber+File+Block+ROW)了,可是oracle外部检索数据仍旧在利用限定ROWID格局(Blocknumber.Rownumber.Filenumber)。
本文触及到的分外常识能够参看我的别的手艺文章:
1.经由过程事务跟踪SQL实行的背景步骤
2.Oracle守候事务,好比本文提到的PL/SQLlocktimer
3.ROWID格局
作者简介:
张乐奕,网名kamus
曾任ITPUBOracle认证版版主,现任itpubOracle办理版版主.
现任职于北京某年夜型软件公司,首席DBA,次要卖力证券行业的天下十数处中心买卖体系数据库办理及保护事情。
热切存眷Oracle手艺和别的相干手艺,出没于各年夜数据库手艺论坛,今朝是中国最年夜的Oracle手艺论坛www.itpub.net的数据库办理版版主,
浏览更多手艺文章和漫笔能够登录我的团体blog。
http://blog.cdsn.net/kamus。
DBaaS解决方案可以降低首次投入成本,对于那些小企业来说,他们往往认为内部部署的数据库成本太高,DBaaS的成本和灵活性优势对小企业吸引力更大,他们是云数据库解决方案的重点客户群体。 |
|