How to determine the correct setting for JOB_QUEUE_PROCESSES (Doc ID 578831.1)

In this Document

  Goal
  Solution

APPLIES TO:

Oracle Database - Enterprise Edition - Version 7.3.2.0 to 11.2.0.2 [Release 7.3.2 to 11.2]
Information in this document applies to any platform.
***Checked for relevance on 16-Feb-2011***


GOAL

Determine the proper setting for the Oracle initialization parameter JOB_QUEUE_PROCESSES

SOLUTION

The ideal setting for JOB_QUEUE_PROCESSES should be set to the maximum number of jobs that would ever be run concurrently on a system PLUS a few more.

1) Initially set JOB_QUEUE_PROCESSES higher than the most number of jobs that could ever run concurrently 

     Be careful not to set this too high as it can effect database performance or even exhaust OS resources should some process generate a lot of running jobs ... or jobs that are caught in a long or infinte loop

     A fair estimate can be done by looking at DBA_JOBS ... NEXT_DATE and NEXT_SEC columns

        The reason that this is a fair estimate is the JOB SCHEDULER submits one time execute jobs to the queue 
            for execution when it chooses to run a job ... so it is possible that the above estimate would be a good bit
            off ... Example ... Running or UTLRP.sql ... on a system with multiple CPU's ... will cause he SCHEDULER
            to submit multiple jobs ... at the same time ... to the job queue 

     NOTE: Add one more to your estimate for the job that will be created below 

2)  Use the job queue to monitor itself 

a) Login as SYS 

b) Create the table to do the monitoring 

CREATE TABLE MAX_CONCURRENT_JOBS (
    SAMPLE_DATE DATE,
    JOBS_RUNNING NUMBER);


c) Create the job to do the monitoring 

CREATE OR REPLACE PROCEDURE MAX_CONCURRENT_JOBS_MONITOR IS
BEGIN
     INSERT INTO MAX_CONCURRENT_JOBS
            SELECT SYSDATE, COUNT(*) FROM DBA_JOBS_RUNNING;
     COMMIT;
END;
/


d) Create the job queue job to do the monitoring 

DECLARE 
  v_jobno number;
BEGIN
DBMS_JOB.SUBMIT(
JOB => v_jobno,
WHAT => 'MAX_CONCURRENT_JOBS_MONITOR;',
NEXT_DATE => SYSDATE,
INTERVAL => 'SYSDATE + (5/1440)');
COMMIT;
END;
/


NOTE : 
The example above uses a 5 minute interval (5/1440) ... this can be adjusted as needed 

e) Monitor MAX_CONCURRENT_JOBS 

SELECT MAX(JOBS_RUNNING) FROM MAX_CONCURRENT_JOBS;


The length of time for monitoring depends on the INTERVAL in the job queue for ALL jobs ... It is recommended that at least two (2) executions of every job in the job queue be monitored with this process

3) Set JOB_QUEUE_PROCESSES to the appropriate setting 

ALTER SYSTEM SET JOB_QUEUE_PROCESSES = <Results from 2e + what is felt is needed for ad hoc jobs> SCOPE = ...


4) Remove the monitoring system 

SELECT JOB FROM DBA_JOBS WHERE WHAT='MAX_CONCURRENT_JOBS_MONITOR;';

EXEC DBMS_JOB.REMOVE(<JOB # from above>);

DROP PROCEDURE MAX_CONCURRENT_JOBS_MONITOR;

DROP TABLE MAX_CONCURRENT_JOBS;





NOTE : this process needs to be done periodically ... especially if new jobs are being added to the job queue




EXAMPLE #1 
(Hypothetical real world example)

A system is running with the following:

      * A job queue with 50 jobs ...

      * JOB_QUEUE_PROCESSES = 50

      The DBA monitors the job queue over the period of a week ... taking and recording periodic samples of the count from DBA_JOBS_RUNNING

       It is found that the most number of jobs to be running concurrently is 6

       At this point JOB_QUEUE_PROCESSES is changed to be 8 (6 from above + 2 for ad hoc jobs) 


EXAMPLE #2 
(Tested example) 

SQL> CREATE TABLE MAX_CONCURRENT_JOBS (
SAMPLE_DATE DATE,
JOBS_RUNNING NUMBER);

  
Table created.

SQL> CREATE OR REPLACE PROCEDURE MAX_CONCURRENT_JOBS_MONITOR IS
BEGIN
INSERT INTO MAX_CONCURRENT_JOBS
SELECT SYSDATE, COUNT(*) FROM DBA_JOBS_RUNNING;
COMMIT;
END;



Procedure created.

SQL> DECLARE
v_jobno number;
BEGIN
DBMS_JOB.SUBMIT(
JOB => v_jobno,
WHAT => 'MAX_CONCURRENT_JOBS_MONITOR;',
NEXT_DATE => SYSDATE,
INTERVAL => 'SYSDATE + (5/1440)');
COMMIT;
END;



PL/SQL procedure successfully completed.

<WAITED FOR SEVERAL RUNS OF THE JOB QUEUE >

SQL> SELECT MAX(JOBS_RUNNING) FROM MAX_CONCURRENT_JOBS;

MAX(JOBS_RUNNING)
-----------------
2

SQL> SELECT JOB FROM DBA_JOBS WHERE WHAT='MAX_CONCURRENT_JOBS_MONITOR;';

JOB
----------
55

SQL> EXEC DBMS_JOB.REMOVE(55);

PL/SQL procedure successfully completed.

SQL> DROP PROCEDURE MAX_CONCURRENT_JOBS_MONITOR;

Procedure dropped.

SQL> DROP TABLE MAX_CONCURRENT_JOBS;

Table dropped.

你可能感兴趣的:(How to determine the correct setting for JOB_QUEUE_PROCESSES (Doc ID 578831.1))