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

Posted

技术标签:

【中文标题】有没有办法保证 PL/SQL 工作的 DOP?【英文标题】:Is there a way to guarante DOP for PL/SQL job? 【发布时间】:2016-05-25 20:24:23 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

您可以抑制 ORA-12842 并静默重启您的 PL/SQL 作业。

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

Procedure exec_insert(来自下面的示例)将尝试执行您的 DML。 它将以 16 的最大 DOP 开始,失败后以 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;

【讨论】:

以上是关于有没有办法保证 PL/SQL 工作的 DOP?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Oracle 中刷新 PL/SQL 的输出?

有没有办法在 Oracle 中刷新 PL/SQL 的输出?

远程调试 PL/SQL 包

PL/SQL FETCH 到数据字符串

错误恢复 PL/SQL oracle 中的下一种错误处理类型

PL/SQL 过程和 Toad 执行?