一、FDW简介
FDW 是 PostgreSQL 提供的一个特性,它能够让用户在 PostgreSQL 中创建 外部表(Foreign Table)。外部表将被作为代理,用于访问外部数据源。当用户对外部表发起查询时,FDW 会负责把查询进行一定的形式转换后访问外部数据源,并负责将外部数据源返回的数据转换回 PostgreSQL 的结果形式,让用户觉得查询一个外部数据源好像和查询一个数据库内的普通表一样没什么区别。
目前 PostgreSQL 官方提供了两个 FDW 实现:
file_fdw:使用户能够创建代表普通文件的外部表postgres_fdw:使用户能够创建代表另一个 PostgreSQL 数据库表的外部表
二、问题概述
在一个客户在使用postgres_fdw 外部表进行查询数据时,发现在数据量比较大的情况下执行的时间非常的长甚至已经到不可用的状态。
2.1 排查网络
排查本地pg到外部服务器之间的网络配置及网络流量,本地网络带宽6Gbps,流量最大4MB/s;
说明网络带宽及网络流量远远没有达到上限,但是流量为什么只有4MB/s呢,查询的数据量非常大按照道理来说流量已经会有一个比较高的峰值才对?
2.2 检查数据库配置
检查数据库的参数,本地及远程服务器内存配置较大;并发参数设置也合理。
2.3 测试查询
1. 在本地客户端执行查询,使用limit 进行不同数据量的外表查询,在limit比较少时查询非常快,但limit越大,发现执行时间越久。
2. 客户端连接远程服务器,使用sql测试执行比较快;说明远程数据库也非执行较慢的瓶颈。
2.4 查看外部表配置
查看外部表配置,只有基本的数据库信息配置,没有设置任何的参数。从前面的排查过程看,定位在本地执行外部表交互上,但网络带宽及网络流量看都未触及瓶颈。
根据外部表配置参数,fetch_size postgres_fdw在每次获取操作中应获取的行数,默认值为100。也就是默认配置下外部表每次执行获取100行,在大数据量的情况下会产生非常多小数据量的传输交互,所以这里也说明了为什么查看网络流量时,最大的流量很小。
fetch_size(integer)fetch_size(integer)This option specifies the number of rows
postgres_fdwshould get in each fetch operation. It can be specified for a foreign table or a foreign server. The option specified on a table overrides an option specified for the server. The default is100.
三、问题原因
在配置postgres_fdw时,未配置参数导致执行产生了非常多的小数据量的传输交互,导致了大量的时间消耗。
四、解决方案
配置postgres_fdw 配置外部服务器的fetch_size,如果版本在14之后可以开启异步同步。
具体fetch_size配置值可以测试不同配置的执行时间。
ALTER SERVER foreign_server
OPTIONS (ADD async_capable 'true',ADD fetch_size '50000');客户fetch_size 配置100000后原需要4个多小时都无法执行出的sql,修改后10分钟可以执行完成,执行时间大幅提升。




