PostgreSQL · 实现分析 · PostgreSQL 10.0 并行查询和外部表的结合



title: PostgreSQL · 实现分析 · PostgreSQL 10.0 并行查询和外部表的结合

author: 义从


前言

大家都知道,PostgreSQL 近几大版本中加入了很多 OLAP 相关特性。9.6 的并行扫描应该算最大的相关特性。在今年发布的 10.0 中,并行扫描也在不断加强,新增了并行的索引扫描。

我们知道并行扫描是支持外部数据源的。在云上,有很多存储存储产品可以以外部数据源的形式做数据库的外部存储。例如,阿里云的 OSS 和 AWS 的 S3 都是绝佳的外部数据源。云上的 PostgreSQL 和他们的结合可以给用户提供既廉价又高性能数存储的方案。

另人欣喜的是,PostgreSQL 的外部表对外提供了可编程接口,并且支持并行扫描框架。利用它可以使 PostgreSQL 的外部数据源访问效率得到质的提升。

技术铺垫

并行查询

并行查询是 PostgreSQL 引入的一个大特性,它可以优化 SQL 语句的执行方式,从传统的单一进程,最多使用单个 CPU 运算的模式,提升到多进程,协同完成工作的模式。

并行查询消耗更多的硬件资源,大大提高了任务的执行效率。
在 PostgreSQL 中,一个 SQL 任务是否可以被并行化,可以通过查看 SQL 的执行计划(Plan)的方式看到。

例如:

EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
                                     QUERY PLAN
-------------------------------------------------------------------------------------
 Gather  (cost=1000.00..217018.43 rows=1 width=97)
   Workers Planned: 2
   ->  Parallel Seq Scan on pgbench_accounts  (cost=0.00..216018.33 rows=1 width=97)
         Filter: (filler ~~ '%x%'::text)
(4 rows)

可以看到,上面的 SQL 采用了并行的方式执行,它使用了2个额外的并行工作进程(共3个进程)完成工作。

  1. 并行 worker 主要完成顺序扫描数据的和过滤数据的工作,符合条件的数据被发送给主进程。
  2. 主进程的 Gather 节点接受来自子进程的数据,再发给客户端。

并行查询的参数配置

合理的配置下列参数能让 PostgreSQL 成功开启并行查询特性。

  1. max_worker_processes 整个实例允许的最大并行工作进程,它的值建议和实例所在主机的逻辑 CPU 相关
  2. max_parallel_workers_per_gather 单个 Gather 节点的并行度,让单个 SQL 更快的执行,可以增大该参数的设置。
  3. force_parallel_mode 是否让查询优化器尽可能的选择并行的执行方式。

详细的参数描述在这

外部表

外部表是 PostgreSQL 引入外部数据的入口,任何的外部数据源都可以使用该接口把数据引入到数据库中。用户可以像访问表一样读写外部数据源上的数据。
目前 PostgreSQL 支持的常见外部数据源有 MySQL Oracle PostgreSQL OSS S3 等。
PostgreSQL 在引入并行查询时也支持了外部表的并行查询,并扩展了之前的编程接口。

并行的外部表扫描实现分析

SQL 语句执行一般过程

一条 SQL 语句的执行通常经历下面的过程:

1) 语法分析和语意分析
2) 查询优化
3) 查询执行

外部表的扫描在阶段 2 和 3 都有相应的操作

  1. 查询优化阶段,需要提供对应外部数据源的数据大小(行数和行宽度)等信息,用于优化器计算最优的查询路径
  2. 查询执行阶段,需要实现几个回调函数,用于向执行器(executor)输送以行(slot)为单位的数据,直到外部数据读取完成。

并行查询在传统模式上的变化

并行查询模式的引入,是 PostgreSQL 在传统的 Pipeline 模式上的较大改动。

大致的改进点如下,这部分也是外部表的并行查询模式实现所要注意的

一 查询优化阶段

提供给优化器并行模型的各类代价信息,参与优化器进行整体的代价评估。
当并行模式最终被确认为最优方案后,优化器会给出并行模式的执行计划。

二 查询执行器阶段

执行器得到一个带有并行执行节点的计划,还要进行如下工作

  1. 启动并行工作进程。
  2. 开辟相关共享内存结构,准备交换数据。
  3. 构造并行协作相关内存结构。
  4. 给工作进程下发并行相关的执行任务。
  5. 并行执行,并行工作进程拿到数据做相应的处理后发送给主进程的 Gather 节点,主进程的 Gather 节点拿到数据后返回给上层节点。直到所有数据处理完毕。
  6. 释放资源,处理事物信息。

上诉工作中框架相关的通用工作 PostgreSQL 已经完成,我们需要在并行框架下实现各阶段的部分逻辑。下面将会重点说明这部分细节。

外表的并行查询的实现分析

实现外部表的并行扫描需要注意上述环节中每个环节,下面描述概要设计

一: 查询优化阶段

  1. 实现 IsForeignScanParallelSafe ,返回 true。 标志该数据源可以并行化。
  2. 补充函数 GetForeignPaths 根据外数据的规模和可提供的并行工作进程数等信息提供给优化器可以行并行 Path。

    a) 调用 create_foreignscan_path 创建可并行的外部表扫描节点 Path。

    b) 调用 add_partial_path 把生成好的 Path 加入优化器 Path 备选队列。

  3. 补充函数 GetForeignPlan 创建可并行的外部表扫描节点 Plan。

    a) 函数内部调用 make_foreignscan 根据输入的 Path 生成 Plan, 并向上返回。

二: 查询执行阶段

并行任务关键当然是把一个大的任务拆分成多个尽可能不相关的子任务,让这些子任务被并行的完成。

例如:

  • 1 对外部 MySQL 一张表 t 的读取,可以按照表 t 主键的值域把数据拆分成 N 部分,让并行 worker 分别读取其中一部分。
  • 2 对外部数据源 oss 一个目录 dir1 中多个文件中数据的读取,可以把这批文件均匀的分成 N 份,让并行 worker 分别完成其中的一部分。

如何合理的切分子任务,往往决定了最终的并行效果。合理的切分数据会使并行任务间尽量少的交互,最终任务完成耗时和并行工作进程数线性相关。

执行器的具体工作:

  1. 实现 EstimateDSMForeignScan 计算需求的共享内存大小。这部分内存将用户存放整个并行任务的相关信息。
    这部分流程主进程完成,即 Gather 节点完成。
  2. 实现 InitializeDSMForeignScan 分配共享内存,放入相关信息。
    我们把整个大任务拆分成一个子任务队列,并存入到共享内存中,初始化锁等信息。
    这部分流程也主进程完成,即 Gather 节点完成。
  3. 实现 InitializeWorkerForeignScan 并行 Worker 读取共享内存上的信息,获取子任务,准备正式开始工作。
  4. 数据的读写操作。
    这部分的实现尽量兼容传统模式的数据读取,或小幅调整。
  5. 实现 ShutdownForeignScan 数据扫描完成的后清理工作。

详细的 Foreign Data Wrapper 接口实现说明在这

并行外部表查询的应用

并行查询能大大提高数据的访问效率,他把外部数据源深度整合到 PostgreSQL 中。可以轻松的和本地数据一起做复杂的运算。同时,我们也能利用这套机制,实现高效的外部数据导入工作。

时间: 2024-05-19 21:37:11

PostgreSQL · 实现分析 · PostgreSQL 10.0 并行查询和外部表的结合的相关文章

PostgreSQL 10.0 preview 多核并行增强 - 索引扫描、子查询、VACUUM、fdw/csp钩子

标签 PostgreSQL , 10.0 , 并行计算 , 索引扫描 , 子查询 , VACUUM , 外部表并行 背景 PostgreSQL 9.6推出的多核并行计算特性,支持全表扫描,hash join,聚合操作. 10.0 在此基础上,增加了更多的支持. 1. Parallel bitmap heap scan 2. Parallel Index Scans 3. Parallel Merge Join 4. parallelize queries containing subplans

PostgreSQL 10.0 preview 多核并行增强 - tuplesort 多核并行创建索引

标签 PostgreSQL , 10.0 , 并行增强 , 多核并行创建索引 背景 PostgreSQL 10.0的多核并行有了诸多增强,比如多核并行排序,可以用于提升创建btree索引的速度. As some of you know, I've been working on parallel sort. I think I've gone as long as I can without feedback on the design (and I see that we're accepti

PostgreSQL 10.0 preview 功能增强 - 后台运行(pg_background)

标签 PostgreSQL , 10.0 , 后台运行 , pg_background_launch , pg_background_result , pg_background_detach , pg_background 背景 当用户在管理数据库时,如果要在交互式界面跑一些QUERY,但是不知道QUERY要运行多久,担心网络问题或者其他问题导致终端断开,QUERY执行情况不明的话.就需要后台运行这个功能了. 后台运行在LINUX中也很常见,比如 nohup ls -la / >/tmp/re

PostgreSQL 10.0 preview 功能增强 - 逻辑复制支持并行COPY初始化数据

标签 PostgreSQL , 10.0 , 逻辑复制 , 初始数据COPY 背景 PostgreSQL 已支持逻辑复制,同时对逻辑复制增加了一个初始同步的增强功能,支持通过wal receiver协议跑COPY命令(已封装在逻辑复制的内核代码中),支持多表并行. 也就是说,你可以使用PostgreSQL的逻辑复制,快速的(流式.并行)将一个实例迁移到另一个实例. Logical replication support for initial data copy Add functionalit

PostgreSQL 10.0 preview 多核并行增强 - 并行hash join支持shared hashdata, 节约哈希表内存提高效率

标签 PostgreSQL , 10.0 , 多核并行增强 , shared hash表 , hash join 背景 PostgreSQL 9.6支持哈希JOIN并行,但是每个worker进程都需要复制一份哈希表,所以会造成内存的浪费,小表无妨,但是大表的浪费是非常大的. 因此10.0做了一个改进,使用共享的哈希表. Hi hackers, In PostgreSQL 9.6, hash joins can be parallelised under certain conditions, b

PostgreSQL 10.0 preview 多核并行增强 - 控制集群并行度

标签 PostgreSQL , 多核并行 , 集群并行度 , SQL并行度 , NODE并行度 背景 PostgreSQL 9.6引入多核并行,一条SQL可以使用多个CPU核,提升SQL性能. 但是多核并行一定不要滥用,因为CPU资源有限,如果单个QUERY把CPU都用光了,其他QUERY就会因为缺乏CPU资源造成性能抖动. 9.6刚出来的时候,可以控制单个gather的并行度,比如全表扫描,扫描节点算一个gather,一个gather下面会fork 一些worker process执行并行任务

PostgreSQL 10.0 preview sharding增强 - 支持异步, 多节点并行

标签 PostgreSQL , 10.0 , sharding 增强 背景 PostgreSQL 10.0的sharding增强,比如聚合函数的下推算一个. 现在又带来了一个核武器级别的增强,postgres_fdw的异步化调用. 为什么说是核武器级别的呢,比如你有16个sharding节点(对应postgres_fdw的16个库),10.0以前,如果我需要执行一个QUERY涉及到所有的sharding节点时,每个sharding节点是串行执行的然后append结果. 10.0开始,会变成异步化

PgSQL · 答疑解惑 · PostgreSQL 9.6 并行查询实现分析

背景 随着PG9.5 项目的release,属于PG9.6的代码也陆续进入代码主干,其中最让人激动的特性并行查询终于进入了核心代码.pger们对这个新特性期待了太久的时间,代码刚提交我们就迫不及待的拿到,从设计到性能进行一番探究,并通过本文介绍给大家. 并行技术的过去和未来 这是个很困难的工作,要说清楚它需要讲清楚并行技术相关的一些背景. PG 目前的架构是基于多进程的,必要的信息通过共享内存这样的机制来传递. 该架构的好处是: 代码相对简单: 在多CPU环境下多会话任务可以由操作系统来调度:

PostgreSQL 10.0 preview 功能增强 - OLAP增强 向量聚集索引(列存储扩展)

标签 PostgreSQL , 10.0 , Vertical Clustered Index (columnar store extension) , 列存储 , 向量聚集索引 背景 未来数据库OLTP+OLAP逐渐模糊化,需求逐渐融合是一个大的趋势,如果你的数据库只支持OLTP的场景,未来可能会成为业务的绊脚石. 在这方面PostgreSQL每年发布的新版本,都给用户很大的惊喜,OLTP已经具备非常强大的竞争力(性能.功能.稳定性.成熟度.案例.跨行业应用等),而OLAP方面,新增的feat