FDW(Foreign Data Wrapper)

上一篇博客里,最末尾提到了 FDW。

FDW 到底是什么呢?

标准

FDW(Foreign Data Wrapper)遵循了 SQL/MED 标准,标准全称:ISO/IEC 9075-9 Management of External Data (SQL/MED)

2003 年,SQL/MED(SQL Management of External Data)被加入 SQL 标准,其为外部数据管理提供了规范。在 2011 年发行的 PostgreSQL 9.1 开始支持外部数据读,2013 发行的 PostgreSQL 9.3 开始支持外部数据写。

下面两篇 PG wiki 内容介绍得很详细:

FDW 有何用?

source:https://leileiluoluo.com/posts/postgres-foreign-data-wrappers.html

  1. 数据分片

使用 FDW 将数据分布式存储在多个数据库上从而实现数据分片(如 pg_shardman 插件,即是使用 postgres_fdw 和 pg_pathman 插件来实现数据分片的)。

  1. 数据同步

使用 FDW 建立本地数据库与外部数据库的连接,即可定时同步外部数据至本地。

  1. 数据迁移

使用 FDW 建立本地数据库与外部数据库的连接,即可进行数据迁移。

  1. ETL(Extract-Transform-Load,抽取转换加载)

使用 FDW 将来自不同类型数据库的数据抽取到一个数据仓库中,便于统一化访问。

PG 实现

pg 实现了数百个 fdw,用于访问外部数据,包括:

  • Generic SQL Database Wrappers (如 JDBC、ODBC)
  • Specific SQL Database Wrappers(如 MySQL、SQLServer)
  • NoSQL Database Wrappers(如 Redis、Cassandra)
  • File Wrappers(如 CSV、JSON、Parquet)
  • Geo Wrappers
  • LDAP Wrappers
  • Generic Web Wrappers(如 git、www)
  • Specific Web Wrappers
  • Big Data Wrappers(如 ES、HDFS、Hive、Arrow)
  • Operating System Wrappers
  • Exotic Wrappers(如 faker_fdw)

这个页面里,可以找到这些 Wrapper 的源码

从上面的实现里可以看到,所有 wrapper 的核心,都是实现 FdwRoutine 中的接口。

cpp 复制代码
/*
 * Foreign-data wrapper handler function: return a struct with pointers
 * to my callback routines.
 */
Datum
jdbc_fdw_handler(PG_FUNCTION_ARGS)
{
	FdwRoutine 	*fdwroutine = makeNode(FdwRoutine);
	
	#if (PG_VERSION_NUM < 90200)
	fdwroutine->PlanForeignScan = jdbcPlanForeignScan;
	#endif

	#if (PG_VERSION_NUM >= 90200)
	fdwroutine->GetForeignRelSize = jdbcGetForeignRelSize;
	fdwroutine->GetForeignPaths = jdbcGetForeignPaths;
	fdwroutine->GetForeignPlan = jdbcGetForeignPlan;
	#endif

	fdwroutine->ExplainForeignScan = jdbcExplainForeignScan;
	fdwroutine->BeginForeignScan = jdbcBeginForeignScan;
	fdwroutine->IterateForeignScan = jdbcIterateForeignScan;
	fdwroutine->ReScanForeignScan = jdbcReScanForeignScan;
	fdwroutine->EndForeignScan = jdbcEndForeignScan;

	pqsignal(SIGINT, SIGINTInterruptHandler);

	PG_RETURN_POINTER(fdwroutine);
}

关于 FdwRoutine 中每个接口的含义,可以参考 PG 官网文章:https://www.postgresql.org/docs/current/fdw-callbacks.html

关于 FdwRountine 的更多细节,可以参考专门的文章,十分有趣。如果你希望写一个自己的 wrapper,从 helloworld 入手会非常合适。

思考

PG 真的是一个学院派数据库!在设计之初就能提炼出一个具备进化能力的外部数据接入框架,实在是伟大(实际经历过企业系统研发的人是能体会的)。

FDW 从产品层面的成功之处,是定义好了一套标准的使用接口,包括:定义 FDW Server;定义 FDW 外表,且支持传入选项。

例如:

sql 复制代码
CREATE SERVER foreign_server
        FOREIGN DATA WRAPPER postgres_fdw
        OPTIONS (host 'localhost', port '5432', dbname 'postgres');
        
CREATE FOREIGN TABLE foreign_weather (
      city        varchar(80),
      temp_low    int,
      temp_high   int,
      prcp        real,
      date        date
  ) SERVER foreign_server
    OPTIONS (schema_name 'public', table_name 'weather');
    
IMPORT FOREIGN SCHEMA public FROM SERVER foreign_server INTO public;

有了这套接口,用户就能够非常自由地实现自己的 fdw 扩展。

FDW 从执行层面的成功之处,成功定义了 FdwRoutine 接口,在整个 postgres 实现中贯彻了接口思想,落实在了代码中。

进一步思考

FdwRoutine 支持的接口看,并不支持 batch mode,它仅支持火山模型的逐行读取。假设要支持高效的 parquet 文件向量化处理,用 parquet_fdw 插件大约是获取不到最优性能的。

相关推荐
jiedaodezhuti1 分钟前
Flink直接缓冲存储器异常解析与解决方案
大数据·flink
★YUI★37 分钟前
学习制作记录(选项UI以及存档系统)8.24
学习·游戏·ui·unity·c#
咸甜适中43 分钟前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十四)垂直滚动条
笔记·学习·rust·egui
代码的余温1 小时前
Elasticsearch Master选举机制解析
大数据·elasticsearch·搜索引擎
计算机源码社1 小时前
计算机毕设选题推荐 基于Spark的家庭能源消耗智能分析与可视化系统 基于机器学习的家庭能源消耗预测与可视化系统源码
大数据·机器学习·数据分析·spark·毕业设计·课程设计·毕业设计源码
IT研究室2 小时前
大数据毕业设计选题推荐-基于大数据的北京市医保药品数据分析系统-Spark-Hadoop-Bigdata
大数据·hadoop·spark·毕业设计·源码·数据可视化
Flink_China2 小时前
Lazada 如何用实时计算 Flink + Hologres 构建实时商品选品平台
大数据·flink
It_张3 小时前
Building Systems with the ChatGPT API 使用 ChatGPT API 搭建系统(第五章学习笔记及总结)
笔记·学习·chatgpt
The_Second_Coming3 小时前
Linux 学习笔记 - 集群管理篇
linux·笔记·学习
时序数据说4 小时前
IoTDB如何解决海量数据存储难题?
大数据·数据库·物联网·时序数据库·iotdb