初始化参数job_queue_processes与Job的关系

---前面讨论过dbms_job这个包了
---现在就job_queue_processes这个参数与Job的一些关系,
---以及参数job_queue_process如何 发挥作用进行一些讨论。
 
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
SQL> select this_date,next_date,interval
  2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
2006-04-27 08:59:10 2006-04-27 08:59:06                                        
sysdate+2/1440                                                                 
                                                                               
SQL> set time on
08:59:43 SQL>
---在Job正在运行的时候修改next_date参数。
09:00:02 SQL> begin
09:00:05   2  dbms_job.next_date(21,'2006-04-27 10:00:00');
09:00:31   3  commit;
09:00:33   4  end;
09:00:36   5  /
PL/SQL 过程已成功完成。
---看到在设置完成之后,next_date被修改。
09:00:37 SQL> select this_date,next_date,interval
09:00:43   2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
2006-04-27 08:59:10 2006-04-27 10:00:00                                        
sysdate+2/1440
---确认Job还在运行.                                                              
09:00:44 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:02:30 SQL> show parameter job
NAME                                 TYPE                                      
------------------------------------ ----------------------                    
VALUE                                                                          
------------------------------                                                 
job_queue_processes                  integer                                   
2                                                                              
---修改job_queue_processes参数。
09:02:34 SQL> alter system set job_queue_processes=0 scope=both;
系统已更改。
---看到没,正在运行的Job不受影响,因为它在运行前就获得了ora_jXXX进程。
---修改后的参数只对:修改完成之后,要执行的Job有影响,因为之后的Job在执行前要获得Job的调度进程.
---由于我们这里设置job_queue_processes=0,所以之后不会再有Job执行。
09:02:49 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:02:57 SQL> select * from test_jobs where rdate > trunc(sysdate);
NO                   RDATE                                                     
-------------------- -------------------                                       
job1                 2006-04-27 08:59:06                                       
09:03:12 SQL> select this_date,next_date,interval
09:03:27   2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
2006-04-27 08:59:10 2006-04-27 10:00:00                                        
sysdate+2/1440                                                                 
---Job运行结束。
09:05:27 SQL> select * from test_jobs where rdate > trunc(sysdate);
NO                   RDATE                                                     
-------------------- -------------------                                       
job1                 2006-04-27 08:59:06                                       
job1                 2006-04-27 09:04:17                                       
---看到没,next_date是在本次Job执行完成之后再进行的修改。
---修改next_date的原则是这样的:
---假如由this_date + interval计算出来的结果 > sysdate的时候,这时以 this_date + interval ==> next_date
---假如由this_date + interval计算出来的结果 < sysdate的时,将Job结束运行时的 sysdate ==> next_date
---并且此时Job会马上开始执行,因为它要赶上“理想的 next_date “,它要完成这个任务。
09:05:35 SQL> select this_date,next_date,interval
09:05:39   2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
                    2006-04-27 09:04:17                                        
sysdate+2/1440                                                                 
---看到没,由于我们设置job_queue_processes = 0,所以,之后的Job没有Job调度进程,是不会 run的。
09:05:40 SQL> select job from dba_jobs_running;
未选定行
09:06:12 SQL> select job from dba_jobs_running;
未选定行
---我们把job_queue_processes修改为1.
09:09:40 SQL> alter system set job_queue_processes = 1 scope=both;
系统已更改。
---看到没,Job马上运行。(所以有时候,我们将job 的Session kill之后,它又会Run,原因是没有将它broken(当然 也到了它的next_date))
09:09:55 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:10:01 SQL> select this_date,next_date,interval
09:10:04   2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
2006-04-27 09:09:58 2006-04-27 09:04:17                                        
sysdate+2/1440                                                               
09:10:04 SQL> show user
USER 为"SYS"
09:10:49 SQL> conn kingping/kingping
已连接。
---当我们去broken(或者进行别的设置: interval,next_date...)不属于自己的Job时,会出现下面这个错误.
09:10:54 SQL> begin
09:10:56   2  dbms_job.broken(21,true);
09:11:04   3  commit;
09:11:06   4  end;
09:11:07   5  /
begin
*
ERROR 位于第 1 行:
ORA-23421: 作业编号21在作业队列中不是一个作业
ORA-06512: 在"SYS.DBMS_SYS_ERROR", line 86
ORA-06512: 在"SYS.DBMS_IJOB", line 529
ORA-06512: 在"SYS.DBMS_JOB", line 245
ORA-06512: 在line 2
09:11:10 SQL> conn sys/kk as sysdba
已连接。
---owner身份去broken,OK没有问题。
---注意:在停止一个正在运行的Job时,一定先要将其Broken。
---避免kill session后,Job满足运行条件,又运行起来。
09:11:19 SQL> begin
09:11:23   2  dbms_job.broken(21,true);
09:11:23   3  commit;
09:11:24   4  end;
09:11:24   5  /
PL/SQL 过程已成功完成。
09:11:25 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:11:45 SQL> select sid from v$lock where type = 'JQ';
       SID                                                                     
----------                                                                     
        10                                                                     
09:12:13 SQL> select serial# from v$session where sid = 10;
   SERIAL#                                                                     
----------                                                                     
        43                                                                     
--- disconnect 此session.
09:12:24 SQL> alter system disconnect session '10,43' immediate;
alter system disconnect session '10,43' immediate
*
ERROR 位于第 1 行:
ORA-00031: 标记要删去的会话
09:13:39 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:14:04 SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
会话已更改。
09:14:26 SQL> select * from test_jobs where rdate > trunc(sysdate);
NO                   RDATE                                                     
-------------------- -------------------                                       
job1                 2006-04-27 08:59:06                                       
job1                 2006-04-27 09:04:17                                       
09:14:27 SQL> select job from dba_jobs_running;
       JOB                                                                     
----------                                                                     
        21                                                                     
09:14:37 SQL> select this_date,next_date,interval
09:14:52   2  from dba_jobs where job = 21;
THIS_DATE           NEXT_DATE                                                  
------------------- -------------------                                        
INTERVAL                                                                       
--------------------------------------------------------------------------------
2006-04-27 09:09:58 4000-01-01 00:00:00                                        
sysdate+2/1440                                                                 
---已经disconnect掉了。
09:14:53 SQL> alter system kill session '10,43';
alter system kill session '10,43'
*
ERROR 位于第 1 行:
ORA-00030: 用户会话 ID 不存在。
09:15:08 SQL> select job from dba_jobs_running;
未选定行
09:15:23 SQL> select * from test_jobs where rdate > trunc(sysdate);
NO                   RDATE                                                     
-------------------- -------------------                                       
job1                 2006-04-27 08:59:06                                       
job1                 2006-04-27 09:04:17                                       
09:15:47 SQL> show user
USER 为"SYS"
---下面通过os上的kill process停止Job.
SQL> select sid from v$lock where type = 'JQ' and id2 = 433;
       SID
----------
       682
---先标志为broken。
SQL> begin
  2  dbms_job.broken(433,true);
  3  commit;
  4  end;
  5  /
PL/SQL procedure successfully completed.
SQL> select serial# from v$session where sid = 682;
   SERIAL#
----------
     12133
---Oracle上处理不了
SQL> alter system disconnect session '682,12133' immediate;
alter system disconnect session '682,12133' immediate
*
ERROR at line 1:
ORA-00031: session marked for kill
SQL> select sid from v$lock where type = 'JQ' and id2 = 433;
       SID
----------
       682
SQL> select serial# from v$session where sid = 682;
   SERIAL#
----------
     12133
---找到OS级别的process id
SQL> select spid from v$process
  2   where addr = (select paddr from v$session where sid = 682);
SPID
------------
13801
---在OS上kill process.
---Win 下用orakill ice(instance_id) 13801
---Linux 下kill -9 13801
SQL> select serial# from v$session where sid = 682;
   SERIAL#
----------
     12133
---Job 已停止。
SQL> select spid from v$process
  2  where addr = (select paddr from v$session where sid = 682);
no rows selected
SQL> select serial# from v$session where sid = 682;
no rows selected
 
 
Oracle 文档关于job_queue_processes的描述:
 

You can schedule routines (jobs) to be run periodically using the job queue. To schedule a job you submit it to the job queue, using the Oracle supplied DBMS_JOB package, and specify the frequency at which the job is to be run. Additional functionality enables you to alter, disable, or delete a job that you previously submitted.

Job queue (Jnnn) processes execute jobs in the job queue. For each instance, these job queue processes are dynamically spawned by a coordinator job queue (CJQ0) background process. The coordinator periodically selects jobs that are ready to run from the jobs shown in the DBA_JOBS view. It orders them by time, and then spawns Jnnn processes to run the selected jobs. Each Jnnn process executes one of the selected jobs.

The JOB_QUEUE_PROCESSES initialization parameter controls whether a coordinator job queue process is started by an instance. If this parameter is set to 0, no coordinator job queue process is started at database startup, and consequently no job queue jobs are executed. The JOB_QUEUE_PROCESSES initialization parameter also specifies the maximum number of Jnnn processes that can concurrently run on an instance. The maximum number of processes that can be specified is 1000.

The following initialization parameter setting causes the coordinator job queue process to start at database startup, and allows the spawning of a maximum of 60 concurrent Jnnn processes.

JOB_QUEUE_PROCESSES = 60

In any given period that the coordinator job queue process scans the jobs shown in the DBA_JOBS view,

 it spawns at most only the number of Jnnn processes required to execute the jobs it has selected. While the above example allows for 60 concurrent Jnnn processes, if only 20 jobs are selected for execution, then the coordinator spawns, or reuses, only the number of Jnnn processes necessary to execute the 20 jobs (at least, 20). Any idle existing Jnnn processes are considered available for reuse.

When a Jnnn process finishes execution of a job, it polls for another job to execute. If there are no jobs selected for execution, it enters an idle state, but wakes up periodically to poll again. If, after a predetermined number of tries, it still finds no jobs to execute, it terminates.

The JOB_QUEUE_PROCESSES initialization parameter is dynamic and it can be modified by an ALTER SYSTEM statement. For example, the following statement sets the maximum number of concurrent Jnnn processes allowed to 20.

ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 20;

If the new value is lower than the previous setting and less than the number of

 currently executing Jnnn processes, the excess processes are allowed to complete before they are terminated.

Jnnn processes will not execute jobs if the instance is running in restricted mode.


转自:http://skygodblue.spaces.live.com/blog/cns!D18CEE1DB3D21A07!404.entry?sa=917427371


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9466564/viewspace-622516/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9466564/viewspace-622516/

你可能感兴趣的:(初始化参数job_queue_processes与Job的关系)