Skip to Main Content
  • Questions
  • dbms_parallel_execute.run_task error when parallel_level > 1

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Dinakar.

Asked: August 15, 2016 - 4:50 pm UTC

Last updated: August 20, 2016 - 3:17 am UTC

Version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production

Viewed 10K+ times! This question is

You Asked

Hi,
I am trying to use dbms_parallel_execute to execute a procedure in multiple threads. when the value of parallel_level = 1, the below code just works fine, but when the value of parallel_level > 1 then this below code fails with the error shown below, please suggest what we are missing, Thanks a lot.

dbms_parallel_execute.run_task
( task_name => 'TEST_PARALLEL_ORACLE',
sql_stmt => 'BEGIN TEST_PARALLEL_PKG.MULTI_THREAD(:START_ID, :END_ID); END;',
language_flag => DBMS_SQL.NATIVE,
parallel_level => 5 );
end;

======= error ===========
*
ERROR at line 1:
ORA-27486: insufficient privileges
ORA-06512: at "SYS.DBMS_ISCHED", line 146
ORA-06512: at "SYS.DBMS_SCHEDULER", line 288
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 357
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 418
ORA-06512: at line 3

and Connor said...

dbms_parallel_execute uses the scheduler infrastructure to build concurrent processes to run your work.

Does your user have the CREATE JOB privilege ?


Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

dbms_parallel_execute parallel_level > 1 error

Dinakar Ullas, August 16, 2016 - 11:28 am UTC

Queried dba_tab_privs, the user has execute privilege on DBMS_SCHEDULER. And besides, with parallel_level = 1, it just works fine, so the user has all privileges. with parallel_level=1, the process took 17hrs for 250M records to merge data from stage to target, and I could see the status of the jobs in dba_parallel_execute_chunks.
Please let me know if you need any more info, the dba's have provided the user with all possible grants since they were unable to find out what the issue is. Based on what I saw I guess its a misleading error, its just that some database parameter is not allowing parallel_level > 1.
Thanks,
Dinakar Ullas
Connor McDonald
August 17, 2016 - 2:18 pm UTC

What is your code doing? Can you post all the code you have related to this?

Or (even better) a test case we can copy-paste and reproduce the error ourselves?

dbms_parallel_execute.run_task error when parallel_level > 1

Dinakar Ullas, August 17, 2016 - 2:35 pm UTC

The code was initially(before we modified) selecting data from stage via a cursor, forall bulk collect and merge into target. But it was written to work for one date, meaning, target is partitioned by date. And in a normal scenario the stage also has data for only one date and hence the merge was working perfectly fine.
And then there was this scenario where the stage had data for the last 13 years and the cursor selected data in random and the merge was doing a full table scan, because data for multiple partitions were in the collection during merge, and the data in stage was > 200M.
Hence, we modified the code in dev, made it accept parameters, divided the data into chunks using the date field in the stage, which divided the whole data into 160 chunks(160 distinct dates) and ran it for parallel_level = 1, just worked fine, took 17 hrs. But with parallel_levl = 2 or anything beyond 1 was failing with the above error.

since the procedure has a lot of logic, I am thinking how to modify the procedure to put it in here. The cursor has some amount of joins and inserts into audit tables for those records which do not satisfy certain data requirements etc etc....
I am working on it, will paste the code as soon as I make it simple enough.

dbms_parallel_execute.run_task error when parallel_level > 1

Dinakar Ullas, August 17, 2016 - 3:11 pm UTC

Alright, here's the test code:

CREATE TABLE PARALLEL_STAGE(EFFDT DATE, ID NUMBER, SALARY NUMBER);

INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100000, 200256);
INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 200259);
INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 20025);
INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 20027);
INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 200227);
INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 20027);
INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 20257);
INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 212257);
INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 32257);
INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 120257);

COMMIT;

CREATE TABLE PARALLEL_TARGET(EFFDT DATE, ID NUMBER, SALARY NUMBER);
ALTER TABLE PARALLEL_TARGET ADD CONSTRAINT pt_pk PRIMARY KEY (EFFDT, ID);


CREATE OR REPLACE PROCEDURE PARALLEL_MERGE(PV_IN_DT NUMBER, PV_IN_DT1 NUMBER)
AS
CURSOR C1
IS
SELECT * FROM PARALLEL_STAGE WHERE EFFDT = TO_DATE(PV_IN_DT,'YYYYMMDD');

TYPE T1 IS TABLE OF C1%ROWTYPE INDEX BY PLS_INTEGER;
T2 T1;
BEGIN

OPEN C1;
FETCH C1 BULK COLLECT INTO T2;
CLOSE C1;

FORALL INDX IN 1..T2.COUNT
MERGE INTO PARALLEL_TARGET PT
USING
(
SELECT
T2(INDX).EFFDT EFFDT,
T2(INDX).ID PID,
T2(INDX).SALARY SAL
FROM
DUAL
) INQ
ON
(INQ.EFFDT = PT.EFFDT
AND INQ.PID = PT.ID)
WHEN MATCHED THEN
UPDATE SET
PT.SALARY = INQ.SAL
WHEN NOT MATCHED THEN
INSERT (EFFDT,
ID,
SALARY)
VALUES (INQ.EFFDT,
INQ.PID,
INQ.SAL);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERR DURING MERGE IS ' || SQLERRM);
ROLLBACK;
END;

declare
l_stmt VARCHAR2(100);
begin
dbms_parallel_execute.drop_task('ASK_TOM_PARALLEL' );
dbms_parallel_execute.create_task('ASK_TOM_PARALLEL');
l_stmt := 'SELECT DISTINCT TO_CHAR(EFFDT,''YYYYMMDD''), TO_CHAR(EFFDT,''YYYYMMDD'') FROM PARALLEL_STAGE';
DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(task_name => 'ASK_TOM_PARALLEL', sql_stmt => l_stmt, by_rowid => FALSE);
end;

select *
from dba_parallel_execute_chunks
where task_name = 'ASK_TOM_PARALLEL'
order by end_ts

CHUNK_ID TASK_OWNER TASK_NAME STATUS START_ROWID END_ROWID START_ID END_ID JOB_NAME START_TS END_TS ERROR_CODE ERROR_MESSAGE
962 VENDOR_LOCAL_REFERENCE ASK_TOM_PARALLEL UNASSIGNED 20160201 20160201
961 VENDOR_LOCAL_REFERENCE ASK_TOM_PARALLEL UNASSIGNED 20160101 20160101

/* Now run the multi thread process with parallel_lel = 1 */

begin
dbms_parallel_execute.run_task
( task_name => 'ASK_TOM_PARALLEL',
sql_stmt => 'begin PARALLEL_MERGE(:start_id, :end_id); end;',
language_flag => DBMS_SQL.NATIVE,
parallel_level => 1 );
end;

PL/SQL procedure successfully completed.

/* Data in the target */
select * from PARALLEL_TARGET

EFFDT ID SALARY
Jan-01-2016 12:00:00 AM 100000 200256
Jan-01-2016 12:00:00 AM 100001 200227
Feb-01-2016 12:00:00 AM 100001 120257

/* Now create a new task and run with parallel_level = 1*/


declare
l_stmt VARCHAR2(100);
begin
dbms_parallel_execute.drop_task('ASK_TOM_PARALLEL' );
dbms_parallel_execute.create_task('ASK_TOM_PARALLEL');
l_stmt := 'SELECT DISTINCT TO_CHAR(EFFDT,''YYYYMMDD''), TO_CHAR(EFFDT,''YYYYMMDD'') FROM PARALLEL_STAGE';
DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(task_name => 'ASK_TOM_PARALLEL', sql_stmt => l_stmt, by_rowid => FALSE);
end;

select *
from dba_parallel_execute_chunks
where task_name = 'ASK_TOM_PARALLEL'
order by end_ts


CHUNK_ID TASK_OWNER TASK_NAME STATUS START_ROWID END_ROWID START_ID END_ID JOB_NAME START_TS END_TS ERROR_CODE ERROR_MESSAGE
964 VENDOR_LOCAL_REFERENCE ASK_TOM_PARALLEL UNASSIGNED 20160201 20160201
963 VENDOR_LOCAL_REFERENCE ASK_TOM_PARALLEL UNASSIGNED 20160101 20160101


/* execute the merge with parallel_level =2 */

begin
dbms_parallel_execute.run_task
( task_name => 'ASK_TOM_PARALLEL',
sql_stmt => 'begin PARALLEL_MERGE(:start_id, :end_id); end;',
language_flag => DBMS_SQL.NATIVE,
parallel_level => 2 );
end;

===================== ERROR ========================
>> begin
dbms_parallel_execute.run_task
( task_name => 'ASK_TOM_PARALLEL',
sql_stmt => 'begin PARALLEL_MERGE(:start_id, :end_id); end;',
language_flag => DBMS_SQL.NATIVE,
parallel_level => 2 );
end;
Error at line 1
ORA-27486: insufficient privileges
ORA-06512: at "SYS.DBMS_ISCHED", line 146
ORA-06512: at "SYS.DBMS_SCHEDULER", line 288
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 357
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 418
ORA-06512: at line 2

Chris Saxon
August 19, 2016 - 2:51 am UTC

A job is an database object, so you need privileges to *create* it. This is *not* the same as execute privs on dbms_scheduler.

But thanks for the test case - we love it when people provide them. We can use it to demonstrate the issue.

SQL> create user demo identified by demo;

User created.

SQL> grant create session, create table, create procedure to demo;

Grant succeeded.

SQL> alter user demo quota 100m on users;

User altered.

SQL>
SQL> conn demo/demo
Connected.

SQL> CREATE TABLE PARALLEL_STAGE(EFFDT DATE, ID NUMBER, SALARY NUMBER);

Table created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100000, 200256);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 200259);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 20025);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 20027);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-JAN-2016', 100001, 200227);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 20027);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 20257);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 212257);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 32257);

1 row created.

SQL> INSERT INTO PARALLEL_STAGE VALUES ('01-FEB-2016', 100001, 120257);

1 row created.

SQL>

SQL> COMMIT;

Commit complete.

SQL> CREATE TABLE PARALLEL_TARGET(EFFDT DATE, ID NUMBER, SALARY NUMBER);

Table created.

SQL> ALTER TABLE PARALLEL_TARGET ADD CONSTRAINT pt_pk PRIMARY KEY (EFFDT, ID);

Table altered.

SQL> CREATE OR REPLACE PROCEDURE PARALLEL_MERGE(PV_IN_DT NUMBER, PV_IN_DT1 NUMBER)
  2  AS
  3  CURSOR C1
  4  IS
  5  SELECT * FROM PARALLEL_STAGE WHERE EFFDT = TO_DATE(PV_IN_DT,'YYYYMMDD');
  6
  7  TYPE T1 IS TABLE OF C1%ROWTYPE INDEX BY PLS_INTEGER;
  8  T2 T1;
  9  BEGIN
 10
 11  OPEN C1;
 12  FETCH C1 BULK COLLECT INTO T2;
 13  CLOSE C1;
 14
 15  FORALL INDX IN 1..T2.COUNT
 16  MERGE INTO PARALLEL_TARGET PT
 17  USING
 18  (
 19  SELECT
 20  T2(INDX).EFFDT EFFDT,
 21  T2(INDX).ID PID,
 22  T2(INDX).SALARY SAL
 23  FROM
 24  DUAL
 25  ) INQ
 26  ON
 27  (INQ.EFFDT = PT.EFFDT
 28  AND INQ.PID = PT.ID)
 29  WHEN MATCHED THEN
 30  UPDATE SET
 31  PT.SALARY = INQ.SAL
 32  WHEN NOT MATCHED THEN
 33  INSERT (EFFDT,
 34  ID,
 35  SALARY)
 36  VALUES (INQ.EFFDT,
 37  INQ.PID,
 38  INQ.SAL);
 39  COMMIT;
 40  EXCEPTION
 41  WHEN OTHERS THEN
 42  DBMS_OUTPUT.PUT_LINE('ERR DURING MERGE IS ' || SQLERRM);
 43  ROLLBACK;
 44  END;
 45  /

Procedure created.

SQL> declare
  2  l_stmt VARCHAR2(100);
  3  begin
  4  dbms_parallel_execute.drop_task('ASK_TOM_PARALLEL' );
  5  dbms_parallel_execute.create_task('ASK_TOM_PARALLEL');
  6  l_stmt := 'SELECT DISTINCT TO_CHAR(EFFDT,''YYYYMMDD''), TO_CHAR(EFFDT,''YYYYMMDD'') FROM PARALLEL_STAGE';
  7  DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(task_name => 'ASK_TOM_PARALLEL', sql_stmt => l_stmt, by_rowid => FALSE);
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL> begin
  2  dbms_parallel_execute.run_task
  3  ( task_name => 'ASK_TOM_PARALLEL',
  4  sql_stmt => 'begin PARALLEL_MERGE(:start_id, :end_id); end;',
  5  language_flag => DBMS_SQL.NATIVE,
  6  parallel_level => 2 );
  7  end;
  8  /
begin
*
ERROR at line 1:
ORA-27486: insufficient privileges
ORA-06512: at "SYS.DBMS_ISCHED", line 146
ORA-06512: at "SYS.DBMS_SCHEDULER", line 288
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 357
ORA-06512: at "SYS.DBMS_PARALLEL_EXECUTE", line 418
ORA-06512: at line 2



SQL> conn system/system
Connected.

SQL> grant create job to demo;

Grant succeeded.

SQL> conn demo/demo
Connected.


SQL> begin
  2  dbms_parallel_execute.run_task
  3  ( task_name => 'ASK_TOM_PARALLEL',
  4  sql_stmt => 'begin PARALLEL_MERGE(:start_id, :end_id); end;',
  5  language_flag => DBMS_SQL.NATIVE,
  6  parallel_level => 2 );
  7  end;
  8  /

PL/SQL procedure successfully completed.


SQL>

SQL>


it worked

Dinakar Ullas, August 19, 2016 - 4:20 pm UTC

Thanks a lot, it worked, appreciate your help.
Connor McDonald
August 20, 2016 - 3:17 am UTC

glad we could help

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library