我的并行PL / SQL作业经常会出现错误ORA-12842或语句的串行执行。每个作业都有固定的并行度(DOP)配额。
有没有办法破解它并保证每次运行的并行性?
答案 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;