简体   繁体   English

Oracle dbms_job 在 5 秒内执行具有不同延迟的作业。 如何让它以指定的时间间隔无延迟地运行作业?

[英]Oracle dbms_job executes jobs with different delays in 5 secs. How make it to run job at specified interval without delays?

I have created simple job via DBMS_JOB package (Tested under oracle 12.2 and 11.2)我通过 DBMS_JOB package 创建了简单的工作(在 oracle 12.2 和 11.2 下测试)

begin
  sys.dbms_job.submit(job => :job,
                      what => 'null;',
                      next_date => to_date('19-06-2020 22:26:00', 'dd-mm-yyyy hh24:mi:ss'),
                      interval => 'trunc(sysdate,''MI'')+1/24/60');
  commit;
end;

It should be runned exactly every minute (no seconds delay)它应该每分钟运行一次(没有秒延迟)

Then I use然后我用

select last_date, last_sec, next_date, what,interval from all_jobs where job=:job

to monitor last start time and next start time I grabbed the output every minute and placed it to the table bellow.为了监控上次开始时间和下次开始时间,我每分钟抓起 output 并将其放在下表中。 Here are results of job runs:以下是作业运行的结果:

| LAST_DATE           | LAST_SEC | NEXT_DATE           | WHAT  | INTERVAL                    |
| 2020-06-19 22:33:02 | 22:33:02 | 2020-06-19 22:34:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:34:07 | 22:34:07 | 2020-06-19 22:35:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:35:13 | 22:35:13 | 2020-06-19 22:36:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:36:18 | 22:36:18 | 2020-06-19 22:37:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:37:24 | 22:37:24 | 2020-06-19 22:38:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:38:30 | 22:38:30 | 2020-06-19 22:39:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:39:05 | 22:39:05 | 2020-06-19 22:40:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:40:10 | 22:40:10 | 2020-06-19 22:41:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:41:16 | 22:41:16 | 2020-06-19 22:42:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:42:21 | 22:42:21 | 2020-06-19 22:43:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:43:27 | 22:43:27 | 2020-06-19 22:44:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:44:02 | 22:44:02 | 2020-06-19 22:45:00 | null; | trunc(sysdate,'MI')+1/24/60 |
| 2020-06-19 22:45:08 | 22:45:08 | 2020-06-19 22:46:00 | null; | trunc(sysdate,'MI')+1/24/60 |

Hmm... NEXT_DATE shows right time, but LAST_DATE / LAST_SEC shows time with delay.嗯... NEXT_DATE显示正确的时间,但LAST_DATE / LAST_SEC显示有延迟的时间。 The delay of start job time is constantly growing from zero to 30 seconds: 2, 7, 13, 18, 24, 30. Then again from zero: 5, 10, 16, 21, 27 Then again 2, 8, ... etc.开始作业时间的延迟不断从零增长到 30 秒:2、7、13、18、24、30。然后又从零开始:5、10、16、21、27,然后又是 2、8、...等等

Why does it starts every time not exactly at:00 sec and is constantly growing?为什么它每次都不完全在:00 秒开始并且不断增长? How to make start it exactly at desired time?如何在所需时间准确启动它?

Generally, I cannot use DBMS_SCHEDULER with calendar syntax.通常,我不能将 DBMS_SCHEDULER 与日历语法一起使用。 I need to calculate the next job time exactly with pl/sql function according to my complex algorithm.我需要根据我的复杂算法用 pl/sql function 精确计算下一个工作时间。

Addition: The same delay in starting a job can be seen if you set what parameter to something like:另外:如果您将what参数设置为以下内容,则可以看到启动作业的相同延迟:

insert into my_table(last_date) values(sysdate);

DBMS_JOB has always been subject to scheduling creep, because the interval is calculated from when the job ends , so the interval is what you specify plus the time it took to run the previous job execution . DBMS_JOB 一直受到调度蠕变的影响,因为间隔是从作业结束时开始计算的,所以间隔是您指定的时间加上运行前一个作业执行所花费的时间 If you need scheduling that precise, then you need to be using Oracle Scheduler (DBMS_SCHEDULER).如果您需要如此精确的调度,那么您需要使用 Oracle 调度程序 (DBMS_SCHEDULER)。 It will allow you to schedule executions to the second, with no creep.它将允许您将执行安排到第二个,而不会蠕动。 Here are some resources to help you get better acquainted with it:这里有一些资源可以帮助您更好地熟悉它:

Below is an example of DDL to create a job that runs once per minute:以下是创建每分钟运行一次的作业的 DDL 示例:

BEGIN
  -- Job defined entirely by the CREATE JOB procedure.
  DBMS_SCHEDULER.create_job (
    job_name        => 'test_full_job_definition',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN DBMS_STATS.gather_schema_stats(''SCOTT''); END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=minutely; bysecond=0',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job defined entirely by the CREATE JOB procedure.');
END;
/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM