Oracle 并行执行(Parallel Execution)的协调机制是什么?

在这里插入图片描述
好的,我们将对 Oracle 数据库的并行执行(Parallel Execution)协调机制进行一场深入而全面的剖析。并行执行是 Oracle 处理海量数据的关键技术,理解其内部原理对于构建和优化数据仓库、BI 系统至关重要。


第一部分:官方技术详解

一、核心概念与作用

1. 什么是并行执行?
并行执行是一种** divide-and-conquer(分而治之)** 的技术。它将一个大型串行任务(如全表扫描、排序、连接)分解成多个较小的子任务,分配給多个从属进程(Parallel Execution Slaves) 同时处理,最后将结果整合。其核心目标是缩短单个大任务的响应时间,以牺牲更多硬件资源(CPU、I/O、内存)为代价。

2. 适用场景

  • 数据仓库(DWH)/决策支持系统(DSS):处理大量数据的查询(SELECT)、数据加载(INSERT /*+ APPEND */CREATE TABLE AS SELECT)、DML(UPDATEDELETE)和 DDL(CREATE INDEXMOVE TABLE)。
  • 大型批处理作业
  • OLTP 系统应谨慎使用,因其会消耗大量资源,可能影响其他并发操作。
二、内部架构与协调机制

并行执行的协调是一个经典的生产者-消费者模型,由以下核心组件协同完成:

1. 核心组件

  • 查询协调器 (Query Coordinator, QC)

    • 身份:即发起原始 SQL 语句的用户会话进程(如服务器进程)。
    • 职责
      1. 解析 SQL 语句,生成并行执行计划。
      2. 请求并分配从属进程(PX Slaves)。
      3. 指导从属进程执行任务(分发工作单元)。
      4. 接收从属进程返回的最终结果,并将其返回给用户。
  • 并行执行服务器进程 (Parallel Execution Server Processes, PX Slaves)

    • 来源:从并行从属进程池(由 PARALLEL_MIN_SERVERSPARALLEL_MAX_SERVERS 参数定义)中分配。通常由实例后台进程 Pnnn(如 P000, P001)或特定服务器进程充当。
    • 类型与角色
      • 生产者 (Producer) / 读取从属 (Reader Slaves):负责扫描数据块(如全表扫描)、应用过滤条件,并将处理后的数据行发送给消费者从属进程。一个从属进程可以同时是生产者和消费者。
      • 消费者 (Consumer) / 处理从属 (Processor Slaves):接收生产者发送的数据行,执行更复杂的操作,如排序(ORDER BY)、分组(GROUP BY)、哈希连接(HASH JOIN)等,最后将结果返回给 QC。
  • 并行执行消息缓冲区 (Buffer) / 表队列 (Table Queue, TQ)

    • 本质:这是进程间通信(IPC)的核心机制,通常是共享内存(Shared Memory) 中的一块区域,用于在生产者和消费者之间高效地传递数据行。
    • 管理:每个数据流在执行计划中都有一个唯一的 TQ ID(如 :TQ10000)来标识。

2. 协调过程详解(生产者-消费者模型)

以一个简单的并行全表扫描和排序为例:
SELECT /*+ PARALLEL(emp, 4) */ * FROM emp ORDER BY sal DESC;
假设并行度(DOP, Degree of Parallelism)为 4。

  1. QC 生成计划与分配进程

    • QC 解析语句,优化器生成一个并行执行计划。计划中会包含 PX COORDINATOR, PX SEND, PX RECEIVE 等操作。
    • QC 从进程池中请求 4 个从属进程。通常,这 4 个进程会被分成两组:一组主要作为生产者负责扫描,另一组作为消费者负责排序。但在简单查询中,角色可能重叠。
  2. 工作单元分配 - Granule(粒度)

    • QC 需要决定如何将大表 EMP 分成小块(称为 Granules)分配给生产者进程。
    • 两种Granule类型
      • Block Range Granules (最常见):将表划分为多个连续的块范围(如 blocks 1-1000, 1001-2000…)。每个生产者进程处理一个范围。适用于大多数操作。
      • Partition Granules:如果表已分区,则直接按分区分配。一个生产者处理一个或多个完整分区。效率更高,因为消除了分区内的再分配。
  3. 生产者阶段

    • 每个生产者进程并行地、独立地扫描分配给它的那些数据块(Granules)。
    • 它们应用 WHERE 子句中的任何过滤条件(本例中没有)。
    • 扫描出的数据行被立即放入表队列(TQ) 中,准备发送给消费者进程。数据在放入 TQ 前可能会被哈希分区广播,以满足后续操作(如 JOINGROUP BY)的需求。在本例的 ORDER BY 中,数据需要根据 sal 的值进行重新分布,以便相同的 sal 值由同一个消费者处理进行排序。
  4. 消费者阶段

    • 消费者进程从 TQ 中取出数据行。
    • 每个消费者进程对自己收到的数据子集进行局部排序(Partial Sort)。
    • 完成局部排序后,消费者将有序的数据子集返回给 QC。
  5. QC 最终处理

    • QC 从所有消费者进程那里接收已经局部排序的数据流。
    • QC 执行最终归并排序(Merge Sort),将多个有序流合并成一个最终的有序结果集。
    • QC 将最终结果返回给客户端。

3. 关键参数与管理机制

  • 并行度 (DOP)

    • 定义参与操作的从属进程数量。可以通过 Hint(/*+ PARALLEL(table_name, degree) */)、表/索引级别设置(ALTER TABLE emp PARALLEL 4;)或会话/系统参数(ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;)来指定。
    • PARALLEL_THREADS_PER_CPU 参数帮助 Oracle 计算默认 DOP。
    • PARALLEL_DEGREE_POLICY 参数控制是否启用自动 DOP(AUTO)、并行语句排队(QUEUING)和内存优化(ADAPTIVE)。
  • 自适应并行PARALLEL_DEGREE_POLICY=ADAPTIVE):

    • 优化器可能根据系统负载和对象大小动态调整 DOP。
    • 如果预计执行时间很短,可能会选择串行执行以避免启动进程的开销。
  • 并行语句排队PARALLEL_DEGREE_POLICY= AUTO | QUEUING):

    • 当请求的并行进程总数超过 PARALLEL_SERVERS_TARGET 限制时,新的并行语句不会立即执行,而是进入一个队列等待资源可用。这防止了系统因过度并行化而崩溃。

第二部分:场景、争用、排查与解决

四、性能争用与排查

并行执行虽然强大,但会显著增加系统资源的消耗,从而引发多种争用。

1. 场景:CPU 争用

  • 原理:并行查询会尝试使用所有可用的 CPU 资源。如果多个高 DOP 的查询同时运行,或者 DOP 设置过高,会导致 CPU 利用率达到 100%,进程在运行队列中等待调度。
  • 等待事件resmgr:cpu quantum(如果启用了资源管理器)或简单的 CPU time 在 AWR 报告中占比极高。
  • 排查
    • 查看 AWR 报告的 Load Profile,观察 CPU cores 使用情况。
    • 查看 Top 10 Foreground Events,如果 CPU time 是第一等待事件,说明 CPU 是瓶颈。
  • 解决
    • 合理设置 PARALLEL_MAX_SERVERS,防止系统创建过多从属进程。
    • 使用 DBMS_RESOURCE_MANAGER 来限制特定用户或组的 CPU 使用率和并行度。
    • 调整 PARALLEL_DEGREE_POLICYAUTOLIMITED,让优化器更保守地选择 DOP。
    • 优化 SQL 和减少 DOP,减少单个查询的 CPU 消耗。

2. 场景:I/O 争用

  • 原理:多个从属进程同时全表扫描或执行并行排序,会发出大量并发 I/O 请求,可能超过存储系统的 I/O 带宽(IOPS 或吞吐量)。
  • 等待事件
    • db file scattered read:常见于全表扫描的多块读操作。
    • db file sequential read:索引查找或单块读。
    • direct path read / direct path write:常见于并行扫描和并行排序的临时段 I/O,它 bypasses the buffer cache。
  • 排查
    • AWR 报告中 Top 10 Foreground Events 出现上述事件且平均等待时间很长。
    • I/O Profile 部分显示高物理读/写。
  • 解决
    • 确保存储系统有足够的 I/O 能力(如更多磁盘、更快的 SSD)。
    • 使用分区和智能扫描来减少物理 I/O 量。
    • 优化 SORT_AREA_SIZEPGA_AGGREGATE_TARGET 以减少排序到磁盘的操作。

3. 场景:并行执行服务器进程争用

  • 原理:当系统并发执行的并行语句过多时,可用的并行从属进程(PARALLEL_MAX_SERVERS)可能被耗尽。新的并行语句将无法获得资源,或者已运行的语句可能因为等待进程而挂起。
  • 等待事件
    • PX Deq: Execute Reply:一个从属进程已完成工作,正在等待 QC 分配新任务。长时间的等待可能意味着 QC 或消费者进程是瓶颈。
    • enq: PS - contention:保护并行从属进程池分配的锁争用。当进程频繁分配和释放时可能发生。
    • PX Queuing: statement queue:当 PARALLEL_DEGREE_POLICY 设置为 AUTOQUEUING 时,语句在等待进入执行队列时出现此等待。
  • 排查
    • 查询 V$PX_PROCESS_SYSSTAT 查看已分配和空闲的进程数。
      SELECT * FROM V$PX_PROCESS_SYSSTAT WHERE STATISTIC LIKE 'Servers%';
      
    • 查询 V$SQL 或 AWR 找到高 DOP 的 SQL。
    • 检查 V$RSRC_CONSUMER_GROUP 查看资源组的使用情况。
  • 解决
    • 适度增加 PARALLEL_MAX_SERVERS(需谨慎,避免过度配置)。
    • 启用并行语句排队(PARALLEL_DEGREE_POLICY=QUEUING)来平滑负载。
    • 优化 SQL,降低其所需的 DOP。

4. 场景:倾斜(Skew)导致的负载不均

  • 原理:在生产者和消费者模型中,如果数据分布严重倾斜(例如,基于一个具有极不均匀值的列进行哈希连接或分组),会导致某些从属进程收到远超其他进程的数据量,形成“短板效应”,其他进程早已完工,却要等待那个忙碌的进程。
  • 影响:并行执行效率远低于预期,资源利用不均。
  • 排查:很难直接观察,需要通过执行计划推断,或使用 SQL 监控报告(DBMS_SQLTUNE.REPORT_SQL_MONITOR)查看每个从属进程的工作量。
  • 解决
    • 选择数据分布更均匀的连接键或分组键。
    • 使用 /*+ PQ_DISTRIBUTE(table_name, HASH, HASH) */ 等 Hint 尝试不同的数据分发方法。
五、常用查询与管理 SQL
  • 监控当前并行执行的语句

    SELECT sid, serial#, username, sql_id, degree, req_degree
    FROM v$session 
    WHERE sid IN (SELECT qc_session_id FROM v$px_session);
    
  • 查看并行从属进程的详细会话信息

    -- 找出所有并行从属进程及其对应的 QC(查询协调器)
    SELECT s.sid, s.serial#, s.username, s.sql_id, s.status,
           pxs.qcsid AS QC_SID, pxs.server_group, pxs.server_set, pxs.degree
    FROM v$session s, v$px_session pxs
    WHERE s.sid = pxs.sid
    ORDER BY pxs.qcsid, pxs.server_group, pxs.server_set;
    
  • 查看并行进程池状态

    SELECT statistic, value FROM v$px_process_sysstat;
    
  • 生成 SQL 监控报告(极其强大,用于深入分析)

    -- 首先从 V$SESSION 或 V$SQL 中找到要分析的 SQL_ID
    SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
      sql_id => '&sql_id', 
      type => 'TEXT', 
      report_level => 'ALL') 
    AS report 
    FROM dual;
    -- 该报告会显示并行执行计划的每个步骤、每个从属进程的工作量、时间线等信息。
    
  • 调整对象的并行度

    ALTER TABLE sales PARALLEL 8;
    ALTER INDEX sales_idx PARALLEL 4;
    ALTER TABLE sales NOPARALLEL; -- 禁用并行
    

第三部分:通俗易懂的解释

想象一下你是一个总包工头(Query Coordinator, QC),要负责打扫一个巨大的、有100个房间的酒店(处理海量数据)。

  • 串行执行:你一个人拿一把扫帚,从101房间开始,一个一个房间打扫下去。耗时极长。

  • 并行执行:你采用了“分而治之”的策略。

    1. 招募工人(PX Slaves):你从劳务市场(Parallel Server Pool)雇了10个清洁工(DOP=10)。
    2. 分配任务(Granules):你把酒店平面图撕成10份,每人分10个房间(Block Range Granules)。“你去打扫1-10号房,你去11-20…”
    3. 工人干活(Producer):工人们同时开始,各自打扫自己的房间(并行全表扫描)。
    4. 收集垃圾(Table Queue):每个工人把扫出的垃圾装袋,放到走廊上一个指定的集合点(Table Queue, TQ),这个集合点对应着“可回收垃圾”或“不可回收垃圾”(数据分发方式)。
    5. 处理垃圾(Consumer):另外一组专门负责运输的工人(Consumer Slaves)从集合点取走垃圾袋,进行下一步处理,比如把塑料瓶压扁(排序、分组、连接)。
    6. 最终汇总(QC Merge):运输工人们把处理好的垃圾运到你这里。你把所有压扁的塑料瓶堆在一起,形成一座整齐的小山(归并排序),然后交给回收站(返回给客户端)。

会出现什么问题?(争用场景)

  • CPU争用(工人累坏了):你雇了100个工人(DOP过高),但他们挤在走廊上,胳膊都抡不开了,大部分时间在互相躲让(上下文切换),效率反而下降。
  • I/O争用(走廊堵了):工人们都推着小车去扔垃圾,但垃圾通道只有一个,大家全堵在门口排队(direct path read 等待)。
  • 进程争用(招不到人):现在是保洁旺季,劳务市场里所有清洁工都被其他包工头雇走了(PARALLEL_MAX_SERVERS 耗尽),你找不到工人,你的工程只能干等着(PX Queuing)。
  • 负载不均(Skew):你有个工人分到了10个总统套房,面积巨大;而另一个工人分到的10个是储物间,5分钟就扫完了。扫完的工人无所事事,必须等那个扫总统套房的工人完工(倾斜)。

如何管理?

  • 作为一个聪明的包工头,你不会总是雇100个人。你会根据酒店大小(数据量)、当前酒店里其他包工头的活动(系统负载)、以及你的时间要求,来决定雇多少人(DOP)。
  • 你还会让来不及干的工程先拿个号排队(PARALLEL_DEGREE_POLICY=QUEUING),而不是一窝蜂冲进去把劳务市场挤垮。

总结
Oracle 并行执行是一个复杂但极其强大的协调系统。QC 是大脑,PX Slaves 是四肢,Table Queues 是神经系统。它的高效依赖于合理的资源分配(DOP)和均衡的工作负载。DBA 的角色就像是公司的调度总监,需要监控整个“工地”的资源使用情况,确保大型项目(并行查询)能高效完成,而不至于拖垮整个系统(资源争用)。通过 V$ 视图和 SQL 监控报告这些“监控摄像头”,你可以精准地定位到是哪个环节出现了拥堵,并采取相应的措施。

欢迎关注我的公众号《IT小Chen

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值