3

Oracle 定时任务job实际应用 - xiezhr

 1 year ago
source link: https://www.cnblogs.com/xiezhr/p/17343566.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、Oracle定时任务简介

Oracle定时任务是在oracle系统中一个非常重要的子系统,运用得当,可以大大提高我们系统运行和维护能力。oracle定时任务的功能,可以在指定的时间点自行执行任务。

那么在实际工作中,什么样的场景会用到定时任务呢?下面是在实际工作中用到的真实业务场景举例

  • 在生成环境中,有时候需要在表中记录一些业务日志,系统运行时间长了之后,表中日志会越来越多,导致系统性能下降,这时候就需要用到定时任务,定时去删除表中一些时间年代比较久远垃圾数据。
  • 在某些业务场景中,明细表的数据量特别大,而需要查询明细表一下汇总数据,就需要将明细表中的数据【某天的业务产生的金额、人数等】通过计算汇总到另外表中,这样在查询的时候就能优化查询效率。而以上操作需要在业务量比较少的情况下进行【一般都在凌晨之后】,这是就需要用到定时任务。

二、dbms_job涉及到的知识点

  • 创建job脚本
variable jobno number;
dbms_job.submit(:jobno,       —-job号 
'your_procedure;',            —-执行的存储过程, ';'不能省略 
next_date,                    —-下次执行时间 
'interval'                    —-每次间隔时间,
interval                      以天为单位);

上面是通过脚本创建,当然也可以通过plsql图形化工具来创建,具体创建过程如下

2381533-20230422173235663-1532300189.png
2381533-20230422173235606-1292456343.png

**系统会自动分配一个任务号jobno ** ,根据jobno 可以进行如下定时任务操作

  • 删除job: dbms_job.remove(jobno);

  • 修改要执行的操作: job:dbms_job.what(jobno, what);

  • 修改下次执行时间:dbms_job.next_date(jobno, next_date);

  • 修改间隔时间:dbms_job.interval(jobno, interval);

  • 启动job: dbms_job.run(jobno);

  • 停止job: dbms.broken(jobno, broken, nextdate); –broken为boolean值

三、初始化相关参数job_queue_processes

  • job_queue_process表示oracle能够并发的job的数量,当job_queue_process值为0时表示全部停止oracle的job
  • 查看job_queue_processes参数
show parameter job_queue_process;
或者
select * from v$parameter where name='job_queue_processes';
  • 修改job_queue_processes参数
alter system set job_queue_processes = 10;

四、实际创建一个定时任务(一分钟执行一次),实现定时一分钟往表中插入数据

4.1 创建需要定时插入数据的目标表

create table t_test (id varchar2(30),
                  name varchar2(30)
                 );

4.2 创建定时执行的存储过程

create or replace procedure proce_t is
begin
  insert into t_test
    (id, name)
  values
    ('1', to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'));
  commit;
end proce_t;
/

4.3 创建定时一分钟定时任务job

variable jobno number;
begin 
dbms_job.submit(:jobno,
'proce_t;',
 sysdate, 
 'sysdate+1/24/60'); 
 commit;
end;

4.5 可以根据以下语句查询刚创建好的job

select job, next_date, next_sec, failures, broken from user_jobs where job = '1424'

查询结果如下

SQL> select job, next_date, next_sec, failures, broken from user_jobs where job = '1424'
  2  /
 
       JOB NEXT_DATE   NEXT_SEC           FAILURES BROKEN
---------- ----------- ---------------- ---------- ------
      1424 2020-12-30  13:07:14                  0 N

其中broken = N 表示该job已经生效

我们再来查看目标表中有没有定时插入数据

SQL> select * from t_test;
 
ID                             NAME
------------------------------ ------------------------------
1                              2020-12-30 13:05:14
1                              2020-12-30 13:03:14
1                              2020-12-30 13:04:14
1                              2020-12-30 13:08:14
1                              2020-12-30 13:06:14
1                              2020-12-30 13:07:14
 
6 rows selected

可以看到,定时一分钟插入了一条数据。

4.6 如果我们不需要这个定时任务了,那要怎么停止呢?

1、根据jobno,执行以下脚本可以停止job

SQL> begin
  2    dbms_job.broken(1424, true, sysdate);
  3    commit;
  4  end;
  5  /
 
PL/SQL procedure successfully completed

再来查看定时任务是否停用成功

SQL> select job, next_date, next_sec, failures, broken from user_jobs where job = '1424';
 
       JOB NEXT_DATE   NEXT_SEC           FAILURES BROKEN
---------- ----------- ---------------- ---------- ------
      1424 4000-01-01  00:00:00                  0 Y

我们发现BROKEN=Y 说明定时任务已经停止成功了

4.7 启用刚才停用的定时任务

SQL> begin
  2   dbms_job.run(1424);
  3   commit;
  4  end;
  5  /
 
PL/SQL procedure successfully completed

SQL> select job, next_date, next_sec, failures, broken from user_jobs where job = '1424';
 
       JOB NEXT_DATE   NEXT_SEC           FAILURES BROKEN
---------- ----------- ---------------- ---------- ------
      1424 2020-12-30  13:20:53                  0 N

BROKEN = N ,刚才的定时任务又启动了

五、定时任务中job运行时间

下面总计了一些定时任务中常用的运行时间

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

  • 半个小时: sysdate+30/(24*60)

  • 每天凌晨1点执行:TRUNC(sysdate) + 1 +1/(24)

  • 每周一凌晨1点执行: TRUNC(next_day(sysdate,'星期一'))+1/24

  • 每月1日凌晨1点执行: TRUNC(LAST_DAY(SYSDATE))+1+1/24

  • 每季度的第一天凌晨1点执行: TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24

  • 每年7月1日和1月1日凌晨1点: ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24

  • 每年1月1日凌晨1点执行: ADD_MONTHS(trunc(sysdate,'yyyy'), 12)+1/24

  • 每个小时的第15分钟运行,比如:8:15,9:15,10:15…:trunc(sysdate,'hh')+(60+15)/(24*60)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK