前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何从0深入PostgreSQL内核写一个执行器算子?

如何从0深入PostgreSQL内核写一个执行器算子?

作者头像
公众号guangcity
发布2024-04-28 15:56:07
630
发布2024-04-28 15:56:07
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

1.执行器概论

执行器作为连接查询计划和存储引擎的桥梁,负责从存储引擎读取数据,并基于查询计划树执行对应的算子,并得到最终的查询结果。

执行器的处理模型主要分为两大类:基于拉操作的模型和基于推操作的模型。

1.1 Pull模型

也被称为火山模型,是指从最顶层的输出节点开始,不断从下层节点拉取数据,因此是一种自顶向下的执行方式。

优点

  • 通用性:拉模型不受数据及规模的限制,可以处理任意规模的数据集。
  • 灵活性:拉模型可以灵活控制输出的数量,比如Limit算子及时短路。

不足

  • 阻塞节点:对于排序节点,需要首先读取下层节点所有数据,并根据数据量,选择合适的算法进行内排序或者外排序。
  • 函数调用开销:每条元组在节点之间流动的过程中都会涉及大量的函数调用。
  • 缓存不友好:过多的控制语句、函数调用容易导致缓存失效。
  • 并行不友好。

1.2 Push模型

Push模型:从最底层的节点开始,不断生成数据,并向上层节点进行数据推送,因此是一种自底向上的执行方式。推模型本质是一种基于物化的操作,每一个节点处理所有的输入数据,并将处理后的数据进行物化,并传递给上层节点。

优点

  • 并行友好。
  • 推模型解决了拉模型中函数调用过多和缓存切换过多的问题。由于每个节点内部的处理逻辑相同,缓存使用率也更高。

不足

  • 内存占用大

1.3 向量化执行引擎

除了拉模型和推模型两大基础模型之外,还引入向量化执行引擎。

  • 每次一个 batch数据而非一行数据,减少函数调用。
  • 配合列式存储 + SIMD指令,提升性能。

2.执行器执行流程

2.1 执行器与上下游的关联关系

1.执行器与算子如何关联?

通过三部曲:ExecutorStart、ExecutorRun、ExecutorEnd。

2.查询计划与执行器如何关联?

通过Portal。

Portal记录了与执行相关的所有信息,例如查询树、计划树和执行状态。对于用户提交的普通查询语句,执行器会创建一个匿名的Portal对象。游标语句,执行器会创建一个对应的命名Portal对象。

3.执行器与存储层如何关联?

通过table am与scan/modifyTable算子进行关联。

2.2 表达式与投影

SQL语句中除了SELECT、FROM、WHERE、GROUP BY等关键字之外的部分,都可以被认为是某种表达式。

例如:a列,a + 1,a * b等等。

表达式名

示例

常量表达式

10

列引用

i, j

位置参数引用

$1

下标

arr[i]

域选择表达式

table.column

运算符表达式

a > b, x and y, x or y

函数表达式

upper(name), now()

聚集表达式

coumt(*), avg(salary)

窗口函数

sum(salary) over (partition by department)

标量子查询

select (select max(age) from students) from student;

数组表达式

select array[1, 2, 3]

Row表达式

select row(1, 'John Doe')

2.3 表达式实现原理

  • ExprContext

记录下每次表达式评估所需要的tuple,可能来自scan、outer、inner。

代码语言:javascript
复制
TupleTableSlot *ecxt_scantuple;
TupleTableSlot *ecxt_innertuple;
TupleTableSlot *ecxt_outertuple;
  • ExprState

ExprState 是表达式求值的顶级节点,它包含:

  • 计算表达式的指令(steps)
  • 存储评估的结果slot
  • 存储空值结果
  • 存储scalar表达式评估的结果
  • 实际计算表达式的函数

对于一个表达式树,每个node初始化为ExprEvalOp,ExprEvalStep 存储每一步表达式评估的结果。

3.如何写一个执行器算子?

假设有一个数据库需求,需要添加一个数据检查的功能,会检查其输入的数据,并对数据进行验证,如果发现数据不符合条件,则会抛出错误或者警告。

例如:plan如下

代码语言:javascript
复制
-> Assert
  Assert Cond: (i = 1)
  -> Seq Scan

我们如何为数据库新增一个AssertOp算子呢?(不考虑优化器,只考虑执行器)

以上就是本次的分享,欢迎转发与收藏。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-26,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.执行器概论
    • 1.1 Pull模型
      • 1.2 Push模型
        • 1.3 向量化执行引擎
        • 2.执行器执行流程
          • 2.1 执行器与上下游的关联关系
            • 2.2 表达式与投影
              • 2.3 表达式实现原理
              • 3.如何写一个执行器算子?
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
              http://www.vxiaotou.com