Tue Feb 7 10:19:24 CST 2023 重构, 不想文章变成无用的流水线

节点

refs

openGauss数据库源码解析系列文章——执行器解析(二
Postgresql查询执行模块README笔记

执行方式分为两大类,一类是 utility 执行,用于ddl等,底层直接对接某个函数,一类是 dml 算子执行,按树的形式执行,这里关注 dml 算子

总的四大类

  1. 控制节点
  2. 扫描节点
  3. 物化节点
  4. 链接节点

每一个算子分为

  1. 初始化
    对应函数以 ExecInitxxx 构造 state 结构体,执行时候使用,exestate 也是树形结构,和 plantree 一一对应,保存运行时的关键信息 打开表或者其他资源 初始化子节点 初始化表达式上下文 初始化表达式 初始化tuple type 初始化project
    • 这里其他的都好理解,但是tuple相关的操作每个算子调用的函数看起来大同小异,但是细节作用不一样
    • 一般 execstats 和 plan tree 是一一对应的,但是也是有例外的,如分区裁剪的时候,确定不需要的分区,init 的时候直接不生成对应的子树的 state
  2. 执行 主要的执行逻辑,其中会涉及到表达式的执行
  3. 清理 清理资源,之前初始化的时候申请的空间

Rescan command to reset a node and make it generate its output sequence over again.

一个简单总结

  CreateQueryDesc

  ExecutorStart
    CreateExecutorState
      creates per-query context
    switch to per-query context to run ExecInitNode
    AfterTriggerBeginQuery
    ExecInitNode --- recursively scans plan tree
      ExecInitNode
        recurse into subsidiary nodes
      CreateExprContext
        creates per-tuple context
      ExecInitExpr

  ExecutorRun
    ExecProcNode --- recursively called in per-query context
      ExecEvalExpr --- called in per-tuple context
      ResetExprContext --- to free memory

  ExecutorFinish
    ExecPostprocessPlan --- run any unfinished ModifyTable nodes
    AfterTriggerEndQuery

  ExecutorEnd
    ExecEndNode --- recursively releases resources
    FreeExecutorState
      frees per-query context and child contexts

  FreeQueryDesc

表达式

介绍了pg表达式的具体的运行机制
对比不同数据库中表达式机制的实现

  1. 表达式按照数组的形式组织的
  2. 表达式尽量在初始化的时候做完所有的准备工作,执行时候只需要执行即可
  • 重点函数和流程
  CreateExprContext  -- or use GetPerTupleExprContext(estate)
    creates per-tuple context

  ExecPrepareExpr
    temporarily switch to per-query context
    run the expression through expression_planner
    ExecInitExpr

  Repeatedly do:
    ExecEvalExprSwitchContext
      ExecEvalExpr --- called in per-tuple context
    ResetExprContext --- to free memory

  FreeExecutorState
    frees per-query context, as well as ExprContext
    (a separate FreeExprContext call is not necessary)

其中函数
  ExecInitExpr 用于初始化表达式,输出为 ExprState
  ExecEvalExprSwitchContext 用于 eval 表达式,输入为 ExprState
  表达式保存在 ExprState.ExprState 中,使用 evalfunc 执行,evalfunc 可以有解释和编译执行,当前大部分还是使用 ExecInterpExprStillValid 中函数解释执行,
  这里一般使用 ExecInterpExpr ,其他的用在特殊场景,不关注

  ExecInterpExpr 现在有两种执行逻辑,一种是使用 if 分支执行,一种是直接使用 goto 配合 swith 执行,具体在 EEO_USE_COMPUTED_GOTO 定义中
  goto:
    大意是先switch  分支,执行之后,然后 移动到下一个表达式,再 switch 到具体得分支执行,如此设计可能和 cpu 指令的 pipline 有关

  另一种执行方式是使用 llvm 进行编译执行, llvm_compile_expr 会编译表达式且设置 evalfunc = ExecRunCompiledExpr

pg 的 表达式 运行机制有次大改,主要是从 dfs 转换到 bfs ,具体的修改的目的及有点如下, 这里记录下来,熟记理解,然后在加上codegen和向量化,可以唬人

Faster expression evaluation and targetlist projection.
This replaces the old, recursive tree-walk based evaluation, with non-recursive, opcode dispatch based, expression evaluation. 
Projection is now implemented as part of expression evaluation.
This both leads to significant performance improvements, and makes future just-in-time compilation of expressions easier.

更快的表达式评估和目标列表投影。
这用非递归的、基于操作码分派的表达式求值取代了旧的、基于递归树遍历的求值。
投影现在作为表达式评估的一部分实现。
这既可以显着提高性能,也可以使将来的表达式即时编译变得更容易。

The speed gains primarily come from:
- non-recursive implementation reduces stack usage / overhead
- simple sub-expressions are implemented with a single jump, without function calls
- sharing some state between different sub-expressions
- reduced amount of indirect/hard to predict memory accesses by laying out operation metadata sequentially; including the avoidance of nearly all of the previously used linked lists
- more code has been moved to expression initialization, avoiding constant re-checks at evaluation time

速度增益主要来自:
- 非递归实现减少堆栈使用/开销
- 简单的子表达式通过单次跳转实现,无需函数调用
- 在不同的子表达式之间共享一些状态
- 通过按顺序排列操作元数据来减少间接/难以预测的内存访问量; 包括避免几乎所有以前使用的链表
- 更多代码已移至表达式初始化,避免在评估时不断重新检查


Future just-in-time compilation (JIT) has become easier, as demonstrated by released patches intended to be merged in a later release, for primarily two reasons: Firstly, due to a stricter split between expression initialization and evaluation, less code has to be handled by the JIT. Secondly, due to the non-recursive nature of the generated "instructions", less performance-critical code-paths can easily be shared between interpreted and compiled evaluation.

未来的即时编译 (JIT) 已经变得更加容易,正如旨在在以后的版本中合并的已发布补丁所证明的那样,主要有两个原因:首先,由于表达式初始化和评估之间的划分更加严格,因此需要更少的代码 由 JIT 处理。 其次,由于生成的“指令”的非递归性质,对性能不太重要的代码路径可以很容易地在解释和编译评估之间共享。


The new framework allows for significant future optimizations. E.g.:
- basic infrastructure for to later reduce the per executor-startup overhead of expression evaluation, by caching state in prepared statements.  That'd be helpful in OLTPish scenarios where initialization overhead is measurable.
- optimizing the generated "code". A number of proposals for potential work has already been made.
- optimizing the interpreter. Similarly a number of proposals have been made here too.

新框架允许在未来进行重大优化。 例如。:
- 用于稍后通过在准备好的语句中缓存状态来减少表达式评估的每个执行程序启动开销的基本基础架构。 这在初始化开销是可测量的 OLTP 场景中很有帮助。
- 优化生成的“代码”。 已经提出了一些关于潜在工作的建议。
- 优化解释器。 同样,这里也提出了一些建议。


The move of logic into the expression initialization step leads to some backward-incompatible changes:
- Function permission checks are now done during expression initialization, whereas previously they were done during execution. In edge cases this can lead to errors being raised that previously wouldn't have been, e.g. a NULL array being coerced to a different array type previously didn't perform checks.
- The set of domain constraints to be checked, is now evaluated once during expression initialization, previously it was re-built every time a domain check was evaluated. For normal queries this doesn't change much, but e.g. for plpgsql functions, which caches ExprStates, the old set could stick around longer.  The behavior around might still change.

将逻辑转移到表达式初始化步骤会导致一些向后不兼容的更改:
- 函数权限检查现在在表达式初始化期间完成,而以前它们是在执行期间完成的。 在边缘情况下,这可能会导致出现以前不会出现的错误,例如 一个 NULL 数组被强制转换为不同的数组类型,以前没有执行检查。
- 要检查的域约束集现在在表达式初始化期间评估一次,以前每次评估域检查时都会重新构建。 对于普通查询,这并没有太大变化,但是例如 对于缓存 ExprStates 的 plpgsql 函数,旧集合可能会保留更长时间。 周围的行为可能仍然会改变。
select * from a where a = $1 for update
 --99.51%--PortalRun
           |
            --99.51%--PortalRunSelect
                      |
                       --99.50%--standard_ExecutorRun
                                 |
                                  --99.47%--ExecLockRows
                                            |
                                             --98.45%--ExecScan
                                                       |
                                                       |--55.88%--ExecInterpExpr
                                                       |          |
                                                       |          |--32.43%--slot_getsomeattrs_int
                                                       |          |          |
                                                       |          |           --29.48%--tts_buffer_heap_getsomeattrs
                                                       |          |
                                                       |           --3.54%--ExecEvalParamExtern
                                                       |
                                                       |--34.60%--SeqNext
                                                       |          |
                                                       |           --29.53%--heap_getnextslot
                                                       |                     |
                                                       |                     |--21.52%--heapgettup_pagemode
                                                       |                     |          |
                                                       |                     |           --12.41%--heapgetpage
                                                       |                     |                     |
                                                       |                     |                     |--4.04%--HeapCheckForSerializableConflictOut
                                                       |                     |                     |          |
                                                       |                     |                     |           --2.12%--CheckForSerializableConflictOutNeeded
                                                       |                     |                     |
                                                       |                     |                      --1.12%--ReadBufferExtended
                                                       |                     |                                |
                                                       |                     |                                 --1.01%--ReadBuffer_common
                                                       |                     |
                                                       |                      --3.79%--ExecStoreBufferHeapTuple
                                                       |
                                                       |--1.70%--heap_getnextslot
                                                       |
                                                       |--1.65%--MemoryContextReset
                                                       |
                                                        --0.50%--int4eq


tpch q1 perf
简要分析可以看出,大部分操作在hash相关的运算上q1也确实有大量聚合运算,这里不知道使用 jit 能否有一定的提升

select
  s_acctbal,
  s_name,
  n_name,
  p_partkey,
  p_mfgr,
  s_address,
  s_phone,
  s_comment
from
  part,
  supplier,
  partsupp,
  nation,
  region
where
  p_partkey = ps_partkey
  and s_suppkey = ps_suppkey
  and p_size = 15
  and p_type like '%BRASS'
  and s_nationkey = n_nationkey
  and n_regionkey = r_regionkey
  and r_name = 'EUROPE'
  and ps_supplycost = (
    select
      min(ps_supplycost)
    from
      partsupp,
      supplier,
      nation,
      region
    where
      p_partkey = ps_partkey
      and s_suppkey = ps_suppkey
      and s_nationkey = n_nationkey
      and n_regionkey = r_regionkey
      and r_name = 'EUROPE'
  )
order by
  s_acctbal desc,
  n_name,
  s_name,
  p_partkey limit 100;

# Total Lost Samples: 0
#
# Samples: 99K of event 'cpu-clock:pppH'
# Event count (approx.): 100006005906
#
# Children      Self  Command   Shared Object                                 Symbol                                                        
# ........  ........  ........  ............................................  ..............................................................
#
   100.00%     0.00%  postgres  /usr/lib/x86_64-linux-gnu/libc-2.31.so        0x7fe4b684e083     D [.] putenv
            |
            ---putenv
               startup_hacks
               PostmasterMain
               ServerLoop
               BackendStartup
               ExitPostmaster
               PostgresMain
               exec_simple_query
               PortalRun
               PortalRunSelect
               ExecutorRun
               standard_ExecutorRun
               ExecutePlan
               ExecProcNode
               ExecProcNodeFirst
               ExecSort
               ExecProcNode
               ExecProcNodeFirst
               ExecAgg
               |          
                --99.98%--agg_fill_hash_table
                          |          
                          |--67.56%--advance_aggregates
                          |          |          
                          |           --67.35%--ExecEvalExprSwitchContext
                          |                     |          
                          |                      --66.93%--ExecInterpExpr
                          |                                |          
                          |                                |--26.72%--numeric_mul
                          |                                |          |          
                          |                                |          |--23.48%--numeric_mul_opt_error
                          |                                |          |          |          
                          |                                |          |          |--14.06%--mul_var
                          |                                |          |          |          |          
                          |                                |          |          |          |--2.89%--pfree
                          |                                |          |          |          |          |          
                          |                                |          |          |          |           --1.63%--AllocSetFree
                          |                                |          |          |          |                     |          
                          |                                |          |          |          |                      --0.54%--__nss_database_lookup2
                          |                                |          |          |          |          
                          |                                |          |          |          |--2.43%--alloc_var
                          |                                |          |          |          |          |          
                          |                                |          |          |          |           --1.82%--palloc
                          |                                |          |          |          |                     |          
                          |                                |          |          |          |                      --1.15%--AllocSetAlloc
                          |                                |          |          |          |          
                          |                                |          |          |          |--1.98%--palloc0
                          |                                |          |          |          |          |          
                          |                                |          |          |          |           --1.14%--AllocSetAlloc
                          |                                |          |          |          |          
                          |                                |          |          |          |--1.03%--round_var
                          |                                |          |          |          |          
                          |                                |          |          |          |--0.85%--__nss_database_lookup2
                          |                                |          |          |          |          
                          |                                |          |          |           --0.51%--strip_var
                          |                                |          |          |          
                          |                                |          |          |--3.57%--make_result_opt_error
                          |                                |          |          |          |          
                          |                                |          |          |           --1.80%--palloc
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.30%--AllocSetAlloc
                          |                                |          |          |          
                          |                                |          |          |--3.34%--free_var
                          |                                |          |          |          |          
                          |                                |          |          |           --2.91%--pfree
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.74%--AllocSetFree
                          |                                |          |          |                                |          
                          |                                |          |          |                                 --0.56%--__nss_database_lookup2
                          |                                |          |          |          
                          |                                |          |          |--1.10%--__nss_database_lookup2
                          |                                |          |          |          
                          |                                |          |           --0.51%--__nss_disable_nscd
                          |                                |          |          
                          |                                |          |--2.13%--pg_detoast_datum
                          |                                |          |          |          
                          |                                |          |           --1.67%--detoast_attr
                          |                                |          |                     |          
                          |                                |          |                      --1.13%--palloc
                          |                                |          |                                |          
                          |                                |          |                                 --0.75%--AllocSetAlloc
                          |                                |          |          
                          |                                |           --0.61%--__nss_database_lookup2
                          |                                |          
                          |                                |--13.61%--numeric_sub
                          |                                |          |          
                          |                                |          |--10.80%--numeric_sub_opt_error
                          |                                |          |          |          
                          |                                |          |          |--4.12%--sub_var
                          |                                |          |          |          |          
                          |                                |          |          |           --3.20%--sub_abs
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.26%--palloc
                          |                                |          |          |                                |          
                          |                                |          |          |                                 --0.91%--AllocSetAlloc
                          |                                |          |          |          
                          |                                |          |          |--2.76%--make_result_opt_error
                          |                                |          |          |          |          
                          |                                |          |          |           --1.43%--palloc
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.10%--AllocSetAlloc
                          |                                |          |          |          
                          |                                |          |          |--2.29%--free_var
                          |                                |          |          |          |          
                          |                                |          |          |           --1.92%--pfree
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.25%--AllocSetFree
                          |                                |          |          |          
                          |                                |          |           --0.76%--__nss_database_lookup2
                          |                                |          |          
                          |                                |           --2.02%--pg_detoast_datum
                          |                                |                     |          
                          |                                |                      --1.55%--detoast_attr
                          |                                |                                |          
                          |                                |                                 --1.05%--palloc
                          |                                |                                           |          
                          |                                |                                            --0.78%--AllocSetAlloc
                          |                                |          
                          |                                |--13.50%--ExecAggPlainTransByVal
                          |                                |          |          
                          |                                |          |--10.34%--numeric_avg_accum
                          |                                |          |          |          
                          |                                |          |          |--5.83%--do_numeric_accum
                          |                                |          |          |          |          
                          |                                |          |          |          |--2.07%--accum_sum_add
                          |                                |          |          |          |          
                          |                                |          |          |          |--1.95%--__nss_database_lookup2
                          |                                |          |          |          |          
                          |                                |          |          |           --0.71%--__nss_disable_nscd
                          |                                |          |          |          
                          |                                |          |          |--3.04%--pg_detoast_datum
                          |                                |          |          |          |          
                          |                                |          |          |           --2.46%--detoast_attr
                          |                                |          |          |                     |          
                          |                                |          |          |                      --1.62%--palloc
                          |                                |          |          |                                |          
                          |                                |          |          |                                 --1.13%--AllocSetAlloc
                          |                                |          |          |          
                          |                                |          |           --0.58%--__nss_database_lookup2
                          |                                |          |          
                          |                                |          |--1.10%--__nss_database_lookup2
                          |                                |          |          
                          |                                |           --0.58%--__nss_disable_nscd
                          |                                |          
                          |                                |--6.32%--numeric_add
                          |                                |          |          
                          |                                |          |--5.07%--numeric_add_opt_error
                          |                                |          |          |          
                          |                                |          |          |--2.12%--add_var
                          |                                |          |          |          |          
                          |                                |          |          |           --1.96%--add_abs
                          |                                |          |          |                     |          
                          |                                |          |          |                      --0.70%--palloc
                          |                                |          |          |                                |          
                          |                                |          |          |                                 --0.50%--AllocSetAlloc
                          |                                |          |          |          
                          |                                |          |          |--1.21%--make_result_opt_error
                          |                                |          |          |          |          
                          |                                |          |          |           --0.57%--palloc
                          |                                |          |          |          
                          |                                |          |           --0.97%--free_var
                          |                                |          |                     |          
                          |                                |          |                      --0.86%--pfree
                          |                                |          |                                |          
                          |                                |          |                                 --0.50%--AllocSetFree
                          |                                |          |          
                          |                                |           --0.91%--pg_detoast_datum
                          |                                |                     |          
                          |                                |                      --0.68%--detoast_attr
                          |                                |          
                          |                                |--1.65%--__nss_database_lookup2
                          |                                |          
                          |                                 --0.54%--__nss_disable_nscd
                          |          
                          |--18.34%--lookup_hash_entries
                          |          |          
                          |          |--16.52%--LookupTupleHashEntry
                          |          |          |          
                          |          |          |--8.86%--LookupTupleHashEntry_internal
                          |          |          |          |          
                          |          |          |           --8.70%--tuplehash_insert_hash
                          |          |          |                     |          
                          |          |          |                      --8.52%--tuplehash_insert_hash_internal
                          |          |          |                                |          
                          |          |          |                                 --7.82%--TupleHashTableMatch
                          |          |          |                                           |          
                          |          |          |                                           |--6.93%--ExecQualAndReset
                          |          |          |                                           |          |          
                          |          |          |                                           |           --6.54%--ExecQual
                          |          |          |                                           |                     |          
                          |          |          |                                           |                      --6.40%--ExecEvalExprSwitchContext
                          |          |          |                                           |                                |          
                          |          |          |                                           |                                 --6.00%--ExecInterpExpr
                          |          |          |                                           |                                           |          
                          |          |          |                                           |                                           |--2.58%--bpchareq
                          |          |          |                                           |                                           |          |          
                          |          |          |                                           |                                           |          |--0.83%--__nss_database_lookup2
                          |          |          |                                           |                                           |          |          
                          |          |          |                                           |                                           |           --0.79%--bcTruelen
                          |          |          |                                           |                                           |          
                          |          |          |                                           |                                            --1.31%--slot_getsomeattrs
                          |          |          |                                           |                                                      |          
                          |          |          |                                           |                                                       --1.15%--slot_getsomeattrs_int
                          |          |          |                                           |                                                                 |          
                          |          |          |                                           |                                                                  --0.94%--tts_minimal_getsomeattrs
                          |          |          |                                           |                                                                            |          
                          |          |          |                                           |                                                                             --0.80%--slot_deform_heap_tuple
                          |          |          |                                           |          
                          |          |          |                                            --0.58%--ExecStoreMinimalTuple
                          |          |          |          
                          |          |           --6.96%--TupleHashTableHash_internal
                          |          |                     |          
                          |          |                     |--4.98%--FunctionCall1Coll
                          |          |                     |          |          
                          |          |                     |           --4.42%--hashbpchar
                          |          |                     |                     |          
                          |          |                     |                     |--2.26%--hash_any
                          |          |                     |                     |          |          
                          |          |                     |                     |           --1.97%--hash_bytes
                          |          |                     |                     |                     |          
                          |          |                     |                     |                      --0.73%--__nss_database_lookup2
                          |          |                     |                     |          
                          |          |                     |                      --0.73%--__nss_database_lookup2
                          |          |                     |          
                          |          |                      --0.52%--__nss_database_lookup2
                          |          |          
                          |           --1.22%--prepare_hash_slot
                          |                     |          
                          |                      --0.53%--ExecClearTuple
                          |          
                          |--12.30%--fetch_input_tuple
                          |          |          
                          |           --12.10%--ExecProcNode
                          |                     |          
                          |                      --11.93%--ExecSeqScan
                          |                                |          
                          |                                 --11.74%--ExecScan
                          |                                           |          
                          |                                           |--5.89%--ExecQual
                          |                                           |          |          
                          |                                           |           --5.72%--ExecEvalExprSwitchContext
                          |                                           |                     |          
                          |                                           |                      --5.29%--ExecInterpExpr
                          |                                           |                                |          
                          |                                           |                                |--3.57%--slot_getsomeattrs
                          |                                           |                                |          |          
                          |                                           |                                |           --3.42%--slot_getsomeattrs_int
                          |                                           |                                |                     |          
                          |                                           |                                |                      --3.13%--tts_buffer_heap_getsomeattrs
                          |                                           |                                |                                |          
                          |                                           |                                |                                 --2.97%--slot_deform_heap_tuple
                          |                                           |                                |                                           |          
                          |                                           |                                |                                            --0.67%--__nss_database_lookup2
                          |                                           |                                |          
                          |                                           |                                 --0.59%--date_le_timestamp
                          |                                           |          
                          |                                            --5.34%--ExecScanFetch
                          |                                                      |          
                          |                                                       --5.18%--SeqNext
                          |                                                                 |          
                          |                                                                  --4.87%--table_scan_getnextslot
                          |                                                                            |          
                          |                                                                             --4.56%--heap_getnextslot
                          |                                                                                       |          
                          |                                                                                        --3.82%--heapgettup_pagemode
                          |                                                                                                  |          
                          |                                                                                                   --2.50%--heapgetpage
                          |                                                                                                             |          
                          |                                                                                                              --1.56%--ReadBufferExtended
                          |                                                                                                                        |          
                          |                                                                                                                         --1.55%--ReadBuffer_common
                          |                                                                                                                                   |          
                          |                                                                                                                                   |--0.79%--smgrread
                          |                                                                                                                                   |          |          
                          |                                                                                                                                   |           --0.78%--mdread
                          |                                                                                                                                   |                     |          
                          |                                                                                                                                   |                      --0.75%--__libc_pread64
                          |                                                                                                                                   |                                |          
                          |                                                                                                                                   |                                 --0.74%--entry_SYSCALL_64_after_hwframe
                          |                                                                                                                                   |                                           do_syscall_64
                          |                                                                                                                                   |                                           |          
                          |                                                                                                                                   |                                            --0.71%--ksys_pread64
                          |                                                                                                                                   |                                                      |          
                          |                                                                                                                                   |                                                       --0.69%--vfs_read
                          |                                                                                                                                   |                                                                 |          
                          |                                                                                                                                   |                                                                  --0.67%--new_sync_read
                          |                                                                                                                                   |                                                                            |          
                          |                                                                                                                                   |                                                                             --0.66%--filemap_read
                          |                                                                                                                                   |                                                                                       |          
                          |                                                                                                                                   |                                                                                        --0.52%--copy_page_to_iter
                          |                                                                                                                                   |                                                                                                  |          
                          |                                                                                                                                   |                                                                                                   --0.51%--copyout
                          |                                                                                                                                   |                                                                                                             copy_user_enhanced_fast_string
                          |                                                                                                                                   |          
                          |                                                                                                                                    --0.65%--BufferAlloc
                          |          
                           --1.17%--MemoryContextReset
                                     |          
                                      --0.85%--MemoryContextResetOnly
                                                |          
                                                 --0.57%--AllocSetReset

Cluster 算子

ClusterGather

ExecInitClusterGather() {
  gatherstate->ps.ExecProcNode = ExecClusterGather;

  // 主要是构造 PlanState
  outerPlanState(gatherstate) = ExecStartClusterPlan() { //分发执行计划 {}
    // 只是explan 的话,并不需要发送执行计划。直接这里返回即可
    if (EXEC_FLAG_EXPLAIN_ONLY)
      return ExecInitNode(plan, estate, eflags);
    
    // 执行计划需要传输到其他节点,需要进行序列化,当前序列化操作使用的是查表的方法,可以不关注先后顺序,使用flag遍历查找,主要方法在mem_toc.h中
    // 针对不同的类型的数据的序列化和反序列化也是后来实现的
    StartRemotePlan() {
      // 发送执行计划到远程节点
      foreach(lc, state->cur_handle->handles) {
        PQsendPlan() 
      }

      PG_TRY() {
        // 如果执行计划中由reduce 节点,则启动 StartDynamicReduceWorker
        if (context->have_reduce && context->start_self_reduce) {
          StartDynamicReduceWorker();
        }

        // 并且接收dn的消息,查看dn状态是否正常
        foreach(lc, list_conn) {
          PQgetResult(conn);
        }
      }

      // 作用未知
      if (context->have_reduce) {
        StartRemoteReduceGroup();
      }
    }
    // 初始化下层节点,这里cn上其实应该只有一个 cluster gather 及之上的算子起作用才对,但是实际上下层节点中如果存在reduce 节点,且 如果 优化中选择再 cn 进行 reduce ,则下层还是会进行一些reduce 相关得操作,
    // 包括上面reduce 得一些设置
    return ExecInitNode(plan, estate, eflags);
  } 
}

ExecClusterGather() {
  // 获得下层节点的数据,这里分为两个不同的部分,先尝试从remote获得的数据,再尝试local的执行计划
  while(node->remote_running != NIL || node->local_end == false) {
    if(node->remote_running != NIL && PQNListExecFinish(node->remote_running, NULL, &node->hook_funcs, blocking)) {
      // PQNListExecFinish 负责获取dn上得数据,这里 remote_running 记录的是运行中的dn,如果dn 运行结束,则加入到 last_run_end ,后续会从 remote_running 中剔除 运行结束的dn
      return node->ps.ps_ResultTupleSlot;
    }

    // 获取cn上的数据
    if(node->local_end == false) {
      slot = ExecProcNode(outerPlanState(node));
    }
  }

}


ExecFinishClusterGather() {
  // 清理工作
}

ClusterMergeGather

功能和 ClusterGather 类似,但是会对 dn 收集的 数据进行排序, 在优化阶段中,如果语句最终的输出需要排序,则在构造顶层节点的时候,会生成 sort 算子,然后在生成 ClusterMergeGather 算子 ClusterMergeGather plan 中,dn的输出一定是有序的

ExecInitClusterMergeGather() {
  ps->ps.ExecProcNode = ExecClusterMergeGather;
  // 使用 ExecStartClusterPlan 初始化的 planstat
  outerPlanState(ps) = ExecStartClusterPlan();

  // 如果是需要排序输出,则在初始化 slot 的时候,需要使用 sort tuple 相关的函数,具体参考 tuplesort_begin_heap
  for(i=0;i<node->numCols;++i) {
    PrepareSortSupportFromOrderingOp();
  }
}

ExecClusterMergeGather() {
  // 获得元组,然后进行排序,这里也区分cn和dn混合使用 ExecProcNode 和 cmg_get_remote_slot
  // 其中 cmg_get_remote_slot 实际调用的是 PQNOneExecFinish
  // 之后使用 binaryheap***进行排序
}


ExecFinishClusterMergeGather() {
  // 清理工作
}

ClusterReduce

recuce 用于在cn 和 dn, dn 和 dn 之间传递数据,并且还会启动 一个 新进程负责此工作,这里简单梳理


typedef enum ReduceType
{
  RT_NOTHING = 1,                 // 不执行reduce 
  RT_NORMAL,                      // 常规reduce
  RT_REDUCE_FIRST,                // 优点向上发送数据而不是向其他节点
  RT_REDUCE_FIRST_EPQ,            // EPQ EvalPlanQual,子链接 中的子查询
  RT_PARALLEL_REDUCE_FIRST,       //
  RT_ADVANCE,                     // 提前进行reduce
  RT_ADVANCE_PARALLEL,
  RT_MERGE                        // reduce 要求有序
}ReduceType;

#define CRF_FETCH_LOCAL_FIRST  0x0001  /* fetch all local first */          // 
#define CRF_DISK_UNNECESSARY  0x0002  /* don't need cache on disk */
#define CRF_DISK_ALWAYS      0x0004  /* always cache tuples on disk */
#define CRF_MAYBE_EPQ      0x0008  /* maybe execute in EPQ */

ExecInitClusterReduce() {

  crstate->ps.ExecProcNode = ExecDefaultClusterReduce;

  // 如果有 PGXCNodeOid ,则设置 模式为 RT_NOTHING
  if (list_member_oid(node->reduce_oids, PGXCNodeOid) == false)
    crstate->reduce_method = (uint8)RT_NOTHING;
  // 如果要求排序,则 设置 为 RT_MERGE,numCols 大致指得是需要排序的列得数量
  else if (node->numCols > 0)
    crstate->reduce_method = (uint8)RT_MERGE;
  // 判断需要优先执行reduce
  else if (node->reduce_flags & (CRF_FETCH_LOCAL_FIRST|CRF_DISK_ALWAYS) ||
       crstate->eflags != 0)
    crstate->reduce_method = (uint8)RT_REDUCE_FIRST;
  else
    crstate->reduce_method = (uint8)RT_NORMAL;

  if ((eflags & EXEC_FLAG_IN_EPQ) &&
    crstate->reduce_method != RT_NOTHING)
    crstate->ps.ExecProcNode = ExecEPQDefaultClusterReduce;
}

// ExecProcNodeReal 函数指针, ExecDefaultClusterReduce 和  ExecEPQDefaultClusterReduce 都只是一个warpper, 调用的时候,会按照不同reduce 策略,调用不同的 init 函数, 对函数指针赋值

// 默认的reduce 函数
ExecDefaultClusterReduce() {
  ClusterReduceState *crstate = castNode(ClusterReduceState, pstate);
  if (crstate->private_state != NULL)
    return pstate->ExecProcNodeReal(pstate);

  InitReduceMethod(crstate);

  return pstate->ExecProcNodeReal(pstate);
}

// EPQ reduce
ExecEPQDefaultClusterReduce() {
  switch(origin->reduce_method) {
    case RT_REDUCE_FIRST:
      InitEPQReduceFirst(node, origin);
    case RT_MERGE:
      InitEPQMergeReduce(node, origin);
    case RT_ADVANCE:
      InitEPQAdvanceReduce(node, origin);
  }

  return pstate->ExecProcNodeReal(pstate);
}

void InitReduceMethod(ClusterReduceState *crstate) {
  switch(crstate->reduce_method) {
    case RT_NOTHING:
      // 设置 ExecProcNodeReal 为 ExecNothingReduce, 内部不具体得任务
      ExecSetExecProcNode(&crstate->ps, ExecNothingReduce);
    case RT_NORMAL:
      InitNormalReduce(crstate);
    case RT_REDUCE_FIRST:
      InitReduceFirst(crstate);
    case RT_MERGE:
      InitMergeReduce(crstate);
  }
}

ExecInitReduceScan