暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle DBMS_PARALLEL_EXECUTE.RUN_TASK正在连续运行

askTom 2017-08-17
930

问题描述

您好,我正在使用用户提供的子集在两个数据库之间进行一些迁移。

问题是,parallel_level,似乎不工作。它总是一次运行一大块。

首先,该过程引发了一个错误,说我需要Create_job授予。

因此,dba给了我这些赠款:
GRANT CREATE JOB TO GEOPUB;
 GRANT SCHEDULER_ADMIN TO GEOPUB;
 GRANT MANAGE SCHEDULER TO GEOPUB;
 GRANT ADM_PARALLEL_EXECUTE_TASK TO GEOPUB;


现在它在parallel_level> 1的情况下运行良好。

这里是我的代码:



dbms_utility.comma_to_table
      ( list   => FOLHAS
      , tablen => l_count
      , tab    => v_array
     );
select ... into maxRowNum
v_sqlChunk := 'select min(rownum) start_id, max(rownum) end_id from(
                        select rownum, ntile(' || ROUND(maxRowNum/CHUNK_SIZE + 1) || ') over (order by ID1) nt from ' || TABELA || '@prdgeoedt.world where ';
    for i in 1..l_count
    loop    
        v_sqlChunk := v_sqlChunk || ' CD_FCIM = ''' || v_array(i) || ''' OR';
    end loop;
    v_sqlChunk := SUBSTR(v_sqlChunk, 1, (LENGTH(v_sqlChunk) - 2));                    
    v_sqlChunk := v_sqlChunk || ') group by nt';

dbms_parallel_execute.create_chunks_by_sql
            (
                task_name => c_task_name,
                sql_stmt  => v_sqlChunk,
                by_rowid => false   
            );


任务:
v_sqlInsert := 'insert into ' || TABELA || '( ' || v_columns || ')  
                        select ' || v_columns || ' 
                            from ( select t.*, ROWNUM AS rn 
                                        FROM ( SELECT * FROM ' || TABELA || '@prdgeoedt.world where ';
                                                for i in 1..l_count
                                                loop
                                                    v_sqlInsert := v_sqlInsert || ' CD_FCIM = ''' || v_array(i) || ''' OR';
                                                end loop;
                                                v_sqlInsert := SUBSTR(v_sqlInsert, 1, (LENGTH(v_sqlInsert) - 2));
    v_sqlInsert := v_sqlInsert || ' order by ID1) t ) WHERE rn  >= :start_id AND rownum <= LEAST (' || CHUNK_SIZE || ',(:end_id - :start_id + 1))';

DBMS_PARALLEL_EXECUTE.RUN_TASK(c_task_name, v_sqlInsert, DBMS_SQL.NATIVE,
                                  parallel_level => 4);



一切正常,除了并行性。它总是一大块时间:

select count(*) FROM   user_parallel_execute_chunks WHERE STATUS = 'ASSIGNED'


它总是给我1。

查看chunks表,我可以看到它们一个接一个地运行:

1987 Atualiza_Bloco_T_GM_AREA PROCESSED   51301 51400 TASK$_9352_1 17/08/17 14:20:58,331062000 17/08/17 14:21:24,375098000  
1988 Atualiza_Bloco_T_GM_AREA PROCESSED   52401 52500 TASK$_9352_1 17/08/17 14:21:24,388782000 17/08/17 14:21:39,550440000  
1989 Atualiza_Bloco_T_GM_AREA PROCESSED   53901 54000 TASK$_9352_1 17/08/17 14:21:39,561615000 17/08/17 14:21:54,785039000  
1990 Atualiza_Bloco_T_GM_AREA PROCESSED   54401 54500 TASK$_9352_1 17/08/17 14:21:54,795799000 17/08/17 14:22:08,870095000  
1991 Atualiza_Bloco_T_GM_AREA PROCESSED   55801 55900 TASK$_9352_1 17/08/17 14:22:08,880978000 17/08/17 14:22:21,343356000  
1992 Atualiza_Bloco_T_GM_AREA PROCESSED   56201 56300 TASK$_9352_1 17/08/17 14:22:21,352776000 17/08/17 14:22:34,610168000  
1993 Atualiza_Bloco_T_GM_AREA PROCESSED   56701 56800 TASK$_9352_1 17/08/17 14:22:34,623940000 17/08/17 14:22:46,582006000  
1994 Atualiza_Bloco_T_GM_AREA PROCESSED   57401 57500 TASK$_9352_1 17/08/17 14:22:46,594983000 17/08/17 14:22:58,181511000  
1995 Atualiza_Bloco_T_GM_AREA PROCESSED   58401 58500 TASK$_9352_1 17/08/17 14:22:58,195566000 17/08/17 14:23:09,096338000  
1996 Atualiza_Bloco_T_GM_AREA PROCESSED   58901 59000 TASK$_9352_1 17/08/17 14:23:09,113248000 17/08/17 14:23:22,524784000  


首先,我认为问题可能是dblink,但我看到了这个问题:

https://asktom.oracle.com/pls/apex/f?p=100:11:111277586747378::NO:::

他说成功了。我不只是确定是并行还是串行。

我试图搜索任何关于parallel_level的文档,但没有什么有趣的出现。

我还搜索了所有并行参数:

SELECT name, value
    FROM   v$parameter
    WHERE  name LIKE '%parallel%'


看看结果:

parallel_server FALSE
parallel_server_instances 1
recovery_parallelism 0
fast_start_parallel_rollback LOW
parallel_min_percent 0
parallel_min_servers 0
parallel_max_servers 960
parallel_instance_group 
parallel_execution_message_size 2152
_parallel_broadcast_enabled TRUE
parallel_degree_policy MANUAL
parallel_adaptive_multi_user TRUE
parallel_threads_per_cpu 2
parallel_automatic_tuning FALSE
parallel_io_cap_enabled FALSE
parallel_min_time_threshold AUTO
parallel_degree_limit CPU
parallel_force_local FALSE
parallel_servers_target 384


我找不到任何对我有帮助的东西。

只是为了澄清,即使我不确定它是否相关:

* t_gm_area是正在处理的同一表。

explain plan for select /*+ PARALLEL (4) */ sum(id1)
 from t_gm_area;


结果:

   - Degree of Parallelism is 40 because of hint


所以我不确定这种行为是否是设计的,因为dblink或某些配置错误。有什么帮助吗?
谢谢!

专家解答

这里有几件事

1) dbms_parallel_execute通过利用调度程序进行并行性。因此,您需要确保相应地设置了job_queue_processes,并确保dbms_parallel_execute正在使用的作业类不受任何约束。所以我会尝试的第一件事是一个非常简单的例程,即,让v_sqlChunk = '选择rownum,rownum从双连接 <= 20',并使任务变得微不足道,如:

procedure long_running_task(p1 int, p2 int) is
begin
  dbms_lock.sleep(60);
end;


并确保这些可以并行完成。

2) 要确定范围,请使用昂贵的排序 (ntile) 操作扫描整个表。然后你的每个任务 (并行或其他) 也做了很多额外的工作来分配正确的块。似乎不是一种特别有效的方法来解决这个问题。

使用rowid系列可能会更好。现在,因为它是一个远程表,我认为您不能使用本机rowid雕刻,但是您可以手动使用此处的代码

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:10498431232211

从远程数据字典中获取rowid范围,并利用它们进行rowid范围扫描。或者,在远程节点上调用dbms_parallel_execute * just * 以完成rowid测距,然后在 * local * 节点上调用dbms_parallel_execute,然后将使用存储在 * remote * 任务中的信息来使用rowid范围。


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论