有没有办法保证DOP的PL / SQL工作?

时间:2016-05-25 20:24:24

标签: oracle performance plsql parallel-processing sqlplus

我的并行PL / SQL作业经常会出现错误ORA-12842或语句的串行执行。每个作业都有固定的并行度(DOP)配额。

有没有办法破解它并保证每次运行的并行性?

1 个答案:

答案 0 :(得分:2)

我认为你不能真正破解它,但你绝对可以避免ORA-12842和串行执行。

您可以禁止使用ORA-12842并以静默方式重启PL / SQL作业。

给出可配置的尝试次数,并在最终尝试失败时串行。

程序exec_insert(来自下面的示例)将尝试执行您的DML。 它将以最大DOP 16开始,一旦失败,将以DOP 8,然后是4,然后是2以静默方式重新启动您的作业,如果2失败,它将会串行。

设置并行执行DML的环境:

procedure parallel_on(p_dop INT:=10) as
begin
  --rollback;
EXECUTE IMMEDIATE 'ALTER SESSION ENABLE PARALLEL DML';
EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL QUERY PARALLEL '||p_dop;
EXECUTE IMMEDIATE 'ALTER SESSION SET PARALLEL_MIN_PERCENT=100';
end;--

设置DML串行执行的环境:

procedure parallel_off as
begin
  --rollback;
EXECUTE IMMEDIATE 'ALTER SESSION DISABLE PARALLEL DML';
EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL QUERY PARALLEL 1';

end;

通用DML执行程序的示例。

procedure exec_insert(p_sql varchar2, p_dop IN OUT INT)
as
  v_pn varchar2(32):='EXEC_INSERT';
  insufficient_parallel_q_slaves EXCEPTION;
  PRAGMA EXCEPTION_INIT( insufficient_parallel_q_slaves, -12827 );
  v_max_dop INT:=16;
  c_dop INT:=CASE WHEN p_dop>v_max_dop THEN v_max_dop ELSE p_dop END ; --//constant
  v_dop INT:=c_dop; 
begin
--p_start(v_pn);
--p(v_sql);
FOR dop in REVERSE 1..p_dop  LOOP
    if MOD(dop,2)=1 then CONTINUE; end if;
    --p('Trying DOP: '||dop);
    if dop>1 then parallel_on(dop); else parallel_off(); end if;
    begin
      EXECUTE IMMEDIATE v_sql;
      --inserted();
      p_dop:=dop;
      commit;
      exit when true;
    exception
      when insufficient_parallel_q_slaves then
        rollback;
        NULL; --//pass
      when others then
        raise;
    end;
    --commit;

  END LOOP;
--p_end(v_pn);
end;