postgres_fdw:访问外部 PostgreSQL 服务器中的数据

F.38. postgres_fdw — 访问外部 PostgreSQL 服务器中的数据 #

postgres_fdw 模块提供外部数据封装器 postgres_fdw,可用来访问外部 PostgreSQL 服务器存储的数据。

此模块与较早的 dblink 模块提供的功能有大量重叠。不过,postgres_fdw 使用更透明、更符合标准的语法访问远程表,而且在许多情况下能够获得更好的性能。

使用 postgres_fdw 进行远程访问前,需要以下准备:

  1. 通过 CREATE EXTENSION 安装 postgres_fdw 扩展。

  2. 使用 CREATE SERVER 为要连接的每个远程数据库创建外部服务器对象。将连接信息作为服务器对象的选项指定,但 user 和 password 除外。

  3. 使用 CREATE USER MAPPING 为每个获准访问外部服务器的数据库用户创建用户映射。通过用户映射的 user 和 password 选项指定远程用户名和密码。

  4. 使用 CREATE FOREIGN TABLE 或 IMPORT FOREIGN SCHEMA 为要访问的每张远程表创建外部表。外部表的列必须与引用的远程表匹配。如果在外部表对象的选项中指定正确的远程名称,也可以使用与远程表不同的表名和/或列名。

现在,只需对外部表执行 SELECT,即可访问底层远程表的数据。也可以用 INSERT、UPDATE、DELETE、COPY 或 TRUNCATE 修改远程表。当然,用户映射中指定的远程用户必须拥有相应权限。

访问或修改远程表时,SELECT、UPDATE、DELETE 或 TRUNCATE 中的 ONLY 选项不会产生作用。

目前 postgres_fdw 不支持带 ON CONFLICT DO UPDATE 子句的 INSERT 语句。不过,支持 ON CONFLICT DO NOTHING 子句,前提是省略唯一索引推断规范。此外,postgres_fdw 支持在分区表上执行 UPDATE 时触发的行移动,但尚不能处理这种情况:选中用于插入移动行的远程分区,同时又是同一命令中其他位置要更新的 UPDATE 目标分区。

通常建议将外部表列声明为与对应远程表列完全相同的数据类型,以及适用时相同的排序规则。虽然 postgres_fdw 在必要的数据类型转换方面相当宽容,但类型或排序规则不匹配时,远程服务器可能以不同于本地服务器的方式解释查询条件,造成意外的语义异常。

外部表的列数可以少于底层远程表,列顺序也可以不同。列与远程表按名称匹配,而不是按位置匹配。

F.38.1. postgres_fdw 的 FDW 选项 #

F.38.1.1. 连接选项 #

使用 postgres_fdw 外部数据封装器的外部服务器,可使用 libpq 连接字符串接受的相同选项,详见 Section 32.1.2;但下列选项不允许使用或会被特殊处理:

  • user、password 和 sslpassword(应改为在用户映射中指定,或者使用服务文件)。

  • client_encoding(自动根据本地服务器编码设置)。

  • application_name — 可以在连接和 postgres_fdw.application_name 中的任一处或两处同时指定。如果两者同时存在,postgres_fdw.application_name 覆盖连接设置。与 libpq 不同,postgres_fdw 允许 application_name 包含“转义序列”,详见 postgres_fdw.application_name。

  • fallback_application_name(始终设为 postgres_fdw)。

  • sslkey 和 sslcert — 可以在连接和用户映射的任一处或两处指定。如果两者同时存在,用户映射设置覆盖连接设置。

只有超级用户可以创建或修改包含 sslcert 或 sslkey 设置的用户映射。

非超级用户可以通过密码验证或 GSSAPI 委派凭据连接外部服务器。因此,对于需要密码验证的非超级用户映射,应指定 password 选项。

超级用户可以逐个用户映射覆盖此检查,将用户映射选项设为 password_required 'false',例如:

ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw
OPTIONS (ADD password_required 'false');

为防止普通用户利用 postgres 服务器所运行的 Unix 用户的认证权限,提升为超级用户,只有超级用户可以在用户映射上设置此选项。

必须谨慎确保这不会让映射用户以超级用户身份连接映射数据库,相关问题见 CVE-2007-3278 和 CVE-2007-6601。不要对 public 角色设置 password_required=false。映射用户可能使用 postgres 服务器所运行系统用户的 Unix 主目录中的任何客户端证书、.pgpass、.pg_service.conf 等;主目录的查找方式见 Section 32.16。它也可能利用 peer 或 ident 等认证方式授予的信任关系。

F.38.1.2. 对象名称选项 #

这些选项控制发送给远程 PostgreSQL 服务器的 SQL 语句所使用的名称。当创建外部表时使用的名称与底层远程表不同,就需要这些选项。

schema_name (string)

可对外部表指定此选项,用于给出该表在远程服务器上的模式名。省略时,使用外部表自身所在模式的名称。

table_name (string)

可对外部表指定此选项,用于给出该表在远程服务器上的表名。省略时,使用外部表自身的名称。

column_name (string)

可对外部表的列指定此选项,用于给出该列在远程服务器上的列名。省略时,使用该列自身的名称。

F.38.1.3. 成本估算选项 #

postgres_fdw 通过在远程服务器执行查询获取数据,因此理想情况下,扫描外部表的估算成本应当等于远程服务器上的执行成本加上一些通信开销。最可靠的估算方式是向远程服务器询问,再加上额外开销;但对简单查询而言,为了估算成本额外执行一次远程查询可能不值得。因此,postgres_fdw 提供以下选项控制成本估算:

use_remote_estimate (boolean)

可对外部表或外部服务器指定此选项,控制 postgres_fdw 是否发送远程 EXPLAIN 命令获取成本估算。表级设置覆盖服务器级设置,但只对该表生效。默认值为 false。

fdw_startup_cost (floating point)

这是可对外部服务器指定的浮点值,将加到该服务器上每次外部表扫描的估算启动成本中,表示建立连接、在远程端解析与规划查询等额外开销。默认值为 100。

fdw_tuple_cost (floating point)

这是可对外部服务器指定的浮点值,作为该服务器上外部表扫描中每个元组的额外成本,表示服务器之间传输数据的额外开销。可以根据远程服务器网络延迟的高低增减这个值。默认值为 0.2。

use_remote_estimate 为 true 时,postgres_fdw 从远程服务器获取行数和成本估算,再将 fdw_startup_cost 和 fdw_tuple_cost 加入成本估算。use_remote_estimate 为 false 时,postgres_fdw 在本地估算行数和成本,再加上 fdw_startup_cost 和 fdw_tuple_cost。除非本地保存了远程表统计信息的副本,否则本地估算很可能不准确。对外部表运行 ANALYZE 可更新本地统计信息:它扫描远程表,然后像处理本地表一样计算并保存统计信息。维护本地统计信息有助于减少远程表每次查询的规划开销;但如果远程表频繁更新,本地统计信息很快会过时。

下面的选项控制这种 ANALYZE 操作的行为:

analyze_sampling (string)

可对外部表或外部服务器指定此选项,决定对外部表运行 ANALYZE 时,是在远程端采样,还是读取并传输全部数据后在本地采样。支持值为 off、random、system、bernoulli 和 auto。off 禁用远程采样,全部数据会传输到本地再采样。random 使用 random() 函数在远程端选择返回行;system 和 bernoulli 使用对应名称的内置 TABLESAMPLE 方法。random 适用于所有远程服务器版本,而 TABLESAMPLE 仅从9.5开始支持。默认的 auto 自动选择建议的采样方法,目前会根据远程服务器版本选择 bernoulli 或 random。

F.38.1.4. 远程执行选项 #

默认只考虑将使用内置运算符和函数的 WHERE 子句发送到远程服务器执行。涉及非内置函数的子句,在取回行后在本地检查。如果远程端也有这些函数,并且能可靠地产生与本地相同的结果,把这些 WHERE 子句发送到远程执行可以改善性能。下面的选项控制此行为:

extensions (string)

此选项是一个逗号分隔的 PostgreSQL 扩展名称列表。这些扩展必须以兼容版本同时安装在本地与远程服务器。属于这些扩展且不可变的函数和运算符,会被视为可发送到远程执行。此选项只能对外部服务器指定,不能逐表指定。

使用 extensions 选项时,用户有责任确保列表中的扩展在本地和远程服务器上都存在,且行为相同;否则远程查询可能失败或表现异常。

fetch_size (integer)

此选项指定 postgres_fdw 每次提取操作应获取的行数。可以对外部表或外部服务器指定,表级选项覆盖服务器级选项。默认值为 100。

batch_size (integer)

此选项指定 postgres_fdw 每次插入操作应插入的行数。可以对外部表或外部服务器指定,表级选项覆盖服务器级选项。默认值为 1。

postgres_fdw 一次实际插入的行数取决于列数和给定的 batch_size 值。整个批次作为一条查询执行,而 postgres_fdw 连接远程服务器所用的 libpq 协议,将单条查询参数数限制为65535。当列数乘以 batch_size 超出限制时,会调整 batch_size 以避免错误。

此选项也适用于向外部表复制数据。在这种情况下,postgres_fdw 一次实际复制的行数以类似插入的方式确定,但因 COPY 命令的实现限制,最多为1000行。

F.38.1.5. 异步执行选项 #

postgres_fdw 支持异步执行,通过并发而非串行运行 Append 节点的多个部分来改善性能。以下选项控制此行为:

async_capable (boolean)

此选项控制 postgres_fdw 是否允许并发扫描外部表以进行异步执行。可以对外部表或外部服务器指定,表级选项覆盖服务器级选项。默认值为 false。

为确保远程服务器返回数据的一致性,postgres_fdw 对给定外部服务器只建立一条连接,并串行运行该服务器上的所有查询,即使涉及多张外部表也一样;除非这些表使用不同用户映射。在这种情况下,禁用此选项,消除异步运行查询的额外开销,可能具有更好的性能。

即使 Append 节点同时包含同步与异步执行的子计划,也会应用异步执行。若异步子计划由 postgres_fdw 处理,则至少要等一个同步子计划返回所有元组后,才会返回异步子计划的元组,因为异步子计划等待发给外部服务器的查询结果时,该同步子计划会执行。这一行为可能在未来版本中改变。

F.38.1.6. 事务管理选项 #

如事务管理章节所述,postgres_fdw 通过创建对应远程事务管理事务,通过创建对应远程子事务管理子事务。当前本地事务涉及多个远程事务时,默认由 postgres_fdw 在本地事务提交或中止时串行提交或中止各远程事务。当前本地子事务涉及多个远程子事务时,默认由 postgres_fdw 在本地子事务提交或中止时串行处理。以下选项可改善性能:

parallel_commit (boolean)

此选项控制本地事务提交时,postgres_fdw 是否并行提交该本地事务中在外部服务器上开启的远程事务;也适用于远程和本地子事务。只能对外部服务器指定,不能逐表指定。默认值为 false。

parallel_abort (boolean)

此选项控制本地事务中止时,postgres_fdw 是否并行中止该本地事务中在外部服务器上开启的远程事务;也适用于远程和本地子事务。只能对外部服务器指定,不能逐表指定。默认值为 false。

若本地事务涉及多个启用了这些选项的外部服务器,本地事务提交或中止时,这些服务器上的多个远程事务会跨服务器并行提交或中止。

启用这些选项后,若某外部服务器拥有许多远程事务,本地事务提交或中止时,该服务器可能受到负面性能影响。

F.38.1.7. 可更新性选项 #

默认假定使用 postgres_fdw 的所有外部表都可更新。可用下面的选项覆盖:

updatable (boolean)

此选项控制 postgres_fdw 是否允许通过 INSERT、UPDATE 和 DELETE 命令修改外部表。可以对表或服务器指定,表级选项覆盖服务器级选项。默认值为 true。

当然,如果远程表实际上不可更新,仍会报错。此选项主要使错误可在本地抛出,而无需查询远程服务器。不过,information_schema 视图会根据此选项的设置报告 postgres_fdw 外部表是否可更新,不会检查远程服务器。

F.38.1.8. 可截断性选项 #

默认假定使用 postgres_fdw 的所有外部表都可截断。可用下面的选项覆盖:

truncatable (boolean)

此选项控制 postgres_fdw 是否允许通过 TRUNCATE 命令截断外部表。可以对表或服务器指定,表级选项覆盖服务器级选项。默认值为 true。

当然,如果远程表实际上不可截断,仍会报错。此选项主要使错误可在本地抛出,而无需查询远程服务器。

F.38.1.9. 导入选项 #

postgres_fdw 能够通过 IMPORT FOREIGN SCHEMA 导入外部表定义。该命令在本地创建与远程服务器中的表或视图匹配的外部表定义。如果待导入的远程表包含用户自定义类型的列,本地服务器必须具有同名的兼容类型。

可以在 IMPORT FOREIGN SCHEMA 命令中指定以下选项,自定义导入行为:

import_collate (boolean)

此选项控制从外部服务器导入的表定义是否包含列的 COLLATE 选项。默认值为 true。若远程服务器的排序规则名称集合与本地不同,例如操作系统不同,可能需要关闭此选项。但这样做有很严重的风险:导入表的列排序规则可能与底层数据不匹配,造成异常查询行为。

即使此参数设为 true,导入使用远程服务器默认排序规则的列仍有风险。它们会以 COLLATE "default" 导入,从而选择本地服务器的默认排序规则,而后者可能不同。

import_default (boolean)

此选项控制从外部服务器导入的表定义是否包含列的 DEFAULT 表达式。默认值为 false。启用后应当注意,本地计算某些默认值可能与远程结果不同;nextval() 是常见问题来源。如果导入的默认表达式使用本地不存在的函数或运算符,整个 IMPORT 会失败。

import_generated (boolean)

此选项控制导入的外部表定义是否包含列的 GENERATED 表达式。默认值为 true。如果导入的生成表达式使用本地不存在的函数或运算符,整个 IMPORT 会失败。

import_not_null (boolean)

此选项控制导入的外部表定义是否包含列的 NOT NULL 约束。默认值为 true。

除了 NOT NULL,不会从远程表导入其他约束。虽然 PostgreSQL 支持外部表检查约束,但不会自动导入,因为约束表达式在本地和远程服务器可能求值不同。检查约束的行为不一致可能造成难以发现的查询优化错误。因此,如需导入检查约束,必须手动完成,并仔细验证每个约束的语义。外部表检查约束处理的更多细节见 CREATE FOREIGN TABLE。

作为其他表分区的表或外部表,只有在 LIMIT TO 子句中明确指定时才会导入,否则会自动从 IMPORT FOREIGN SCHEMA 中排除。由于可以通过分区层级根节点的分区表访问全部数据,只导入分区表,就应能访问所有数据而不创建多余对象。

F.38.1.10. 连接管理选项 #

默认情况下,postgres_fdw 与外部服务器建立的所有连接都会在本地会话中保持打开,以供复用。

keep_connections (boolean) #

此选项控制 postgres_fdw 是否保持与外部服务器的连接打开,以供后续查询复用。只能对外部服务器指定,默认值为 on。设为 off 时,每个事务结束后会丢弃该外部服务器的所有连接。

use_scram_passthrough (boolean) #

此选项控制 postgres_fdw 是否通过 SCRAM 透传认证连接外部服务器。可对服务器或用户映射指定,用户映射设置覆盖服务器设置。通过 SCRAM 透传认证,postgres_fdw 使用经 SCRAM 哈希的秘密信息而非明文用户密码连接远程服务器,从而避免在 PostgreSQL 系统目录中存储明文用户密码。

使用 SCRAM 透传认证需要满足:

  • 远程服务器必须请求 scram-sha-256 认证方式,否则连接失败。

  • 远程服务器可使用任何支持 SCRAM 的 PostgreSQL 版本;只有客户端,也就是 FDW 一侧,需要支持 use_scram_passthrough。

  • 不会使用用户映射密码。

  • 运行 postgres_fdw 的服务器和远程服务器,对于在 postgres_fdw 中用于认证外部服务器的用户,必须具有相同的 SCRAM 秘密信息(加密密码),即盐和迭代次数相同,而不只是密码相同。

    由此推论,若 FDW 需要连接多个主机,例如分区外部表或分片场景,各主机对于涉及的用户必须具有相同的 SCRAM 秘密信息。

  • 发起出站 FDW 连接的 PostgreSQL 实例,其当前会话的入站客户端连接也必须使用 SCRAM 认证。这就是“透传”的含义:入站和出站都要使用 SCRAM。这是 SCRAM 协议的技术要求。

F.38.2. 函数 #

postgres_fdw_get_connections( IN check_conn boolean DEFAULT false, OUT server_name text, OUT user_name text, OUT valid boolean, OUT used_in_xact boolean, OUT closed boolean, OUT remote_backend_pid int4) returns setof record

此函数返回 postgres_fdw 从本地会话到外部服务器建立的所有打开连接的信息。如果没有打开的连接,则不返回记录。

若 check_conn 设为 true,函数会检查每条连接状态,并在 closed 列显示结果。目前只有支持 poll 系统调用的非标准 POLLRDHUP 扩展的系统提供此功能,包括 Linux。它可检查事务内使用的连接是否仍然打开。如果任何连接已关闭,事务就无法成功提交,因此检测到关闭连接时应尽早回滚,不要继续到事务结束。若函数报告某连接的 used_in_xact 和 closed 都为 true,用户可以立即回滚事务。

函数用法示例:

postgres=# SELECT * FROM postgres_fdw_get_connections(true);
 server_name | user_name | valid | used_in_xact | closed | remote_backend_pid
-------------+-----------+-------+--------------+-----------------------------
 loopback1   | postgres  | t     | t            | f      |            1353340
 loopback2   | public    | t     | t            | f      |            1353120
 loopback3   |           | f     | t            | f      |            1353156

输出列见 表 F.28。

表 F.28. postgres_fdw_get_connections 的输出列

列 类型 描述
server_name text 该连接的外部服务器名称。如果服务器已被删除,但连接仍然打开,即被标记为无效,则为 NULL。
user_name text 该连接中映射到外部服务器的本地用户名称;使用公共映射时为 public。如果用户映射已被删除,但连接仍然打开,即被标记为无效,则为 NULL。
valid boolean 连接无效时为 false,即当前事务正在使用该连接,但它的外部服务器或用户映射已经被修改或删除。无效连接会在事务结束时关闭。其他情况返回 true。
used_in_xact boolean 当前事务正在使用该连接时为 true。
closed boolean 连接关闭时为 true,否则为 false。如果 check_conn 设为 false,或者此平台不能检查连接状态,则返回 NULL。
remote_backend_pid int4 在外部服务器上处理该连接的远程后端进程 ID。如果远程后端终止且连接关闭(closed 为 true),这里仍显示已经终止的后端进程 ID。

postgres_fdw_disconnect(server_name text) returns boolean

此函数丢弃 postgres_fdw 从本地会话到指定名称的外部服务器建立的打开连接。注意,可能通过不同用户映射对同一服务器建立多条连接。若连接正在被当前本地事务使用,则不关闭,并报告警告。至少关闭一条连接时返回 true,否则返回 false。找不到指定名称的外部服务器则报错。示例:

postgres=# SELECT postgres_fdw_disconnect('loopback1');
 postgres_fdw_disconnect
-------------------------
 t
postgres_fdw_disconnect_all() returns boolean

此函数丢弃 postgres_fdw 从本地会话到外部服务器建立的所有打开连接。若连接正在被当前本地事务使用,则不关闭,并报告警告。至少关闭一条连接时返回 true,否则返回 false。示例:

postgres=# SELECT postgres_fdw_disconnect_all();
 postgres_fdw_disconnect_all
-----------------------------
 t

F.38.3. 连接管理 #

第一次查询使用某外部服务器关联的外部表时,postgres_fdw 会建立到该服务器的连接。默认保留该连接,以供同一会话的后续查询复用。可以通过服务器的 keep_connections 选项控制。如果用多个用户身份,即多个用户映射访问同一服务器,会为每个映射建立连接。

修改定义或删除外部服务器、用户映射时,关联连接会关闭。不过,若连接正被当前本地事务使用,会保留到事务结束。后续查询使用外部表且需要连接时,会重新建立已经关闭的连接。

建立外部服务器连接后,默认保持到本地或相应远程会话退出。要显式断开连接,可以禁用服务器的 keep_connections 选项,或使用 postgres_fdw_disconnect 和 postgres_fdw_disconnect_all 函数。这可关闭不再需要的连接,释放外部服务器的连接资源。

F.38.4. 事务管理 #

查询引用外部服务器上的远程表时,如果尚不存在与当前本地事务对应的远程事务,postgres_fdw 会在远程端开启事务。本地事务提交或中止时,远程事务也提交或中止。保存点通过创建对应的远程保存点以类似方式管理。

当本地事务使用 SERIALIZABLE 隔离级别时,远程事务使用 SERIALIZABLE;其他情况下,远程事务使用 REPEATABLE READ。这确保查询在远程服务器多次扫描表时,所有扫描都取得快照一致的结果。因此,同一事务内的连续查询会看到相同的远程数据,即使其他活动正在并发更新远程端也是如此。本地事务采用 SERIALIZABLE 或 REPEATABLE READ 时,这一行为符合预期,但对于 READ COMMITTED 本地事务可能令人意外。未来版本可能调整这些规则。

目前 postgres_fdw 不支持为两阶段提交准备远程事务。

F.38.5. 远程查询优化 #

postgres_fdw 尝试优化远程查询,减少从外部服务器传输的数据量:将查询的 WHERE 子句发送到远程执行,并且不获取当前查询不需要的列。为减少错误执行的风险,只有当 WHERE 子句仅使用内置的数据类型、运算符与函数,或使用外部服务器 extensions 选项所列扩展中的这些对象时,才会发送到远程;其中的运算符和函数还必须是 IMMUTABLE。对于 UPDATE 或 DELETE 查询,如果没有无法发送到远程的 WHERE 子句,没有本地连接,目标表没有行级本地 BEFORE、AFTER 触发器或存储生成列,也没有来自父视图的 CHECK OPTION 约束,则 postgres_fdw 会尝试将整个查询发送到远程服务器来优化执行。在 UPDATE 中,目标列赋值表达式必须仅使用内置数据类型、IMMUTABLE 运算符或 IMMUTABLE 函数,以减少错误执行风险。

postgres_fdw 遇到同一外部服务器上的外部表连接时,除非认为分别提取各表的行更高效,或者涉及的表引用使用不同用户映射,否则会将整个连接发送到远程服务器。发送 JOIN 子句时,会采用与前述 WHERE 子句相同的防范措施。

使用 EXPLAIN VERBOSE 可以检查实际发送给远程服务器执行的查询。

F.38.6. 远程查询执行环境 #

在 postgres_fdw 打开的远程会话中,search_path 被设为仅包含 pg_catalog,因此不使用模式限定时,只能看到内置对象。对于 postgres_fdw 自己生成的查询,这不是问题,因为它总会加上模式限定。但对于远程表触发器或规则所执行的函数,这可能造成隐患。例如,若远程表实际上是视图,视图使用的任何函数都会在受限搜索路径下执行。建议对此类函数的所有名称使用模式限定,或者给函数附加 SET search_path 选项(见 CREATE FUNCTION),建立其预期的搜索路径环境。

postgres_fdw 同样会设置远程会话的其他参数:

这些设置比 search_path 更不容易引发问题,但必要时仍可通过函数的 SET 选项处理。

不建议修改这些参数的会话级设置来覆盖此行为,这很可能导致 postgres_fdw 无法正常工作。

F.38.7. 跨版本兼容性 #

postgres_fdw 可以用于低至 PostgreSQL 8.3 的远程服务器;只读功能可用于低至8.1的版本。

一个限制是:postgres_fdw 通常认为,外部表 WHERE 子句中的不可变内置函数和运算符可以安全发送到远程执行。因此,在远程服务器所用版本发布之后才加入的内置函数,也可能被发送过去,导致“function does not exist”或类似错误。可以重写查询规避,例如把外部表引用放入带 OFFSET 0 优化屏障的子 SELECT,将有问题的函数或运算符置于子 SELECT 之外。

另一个限制是:在外部表上执行带 ON CONFLICT DO NOTHING 子句的 INSERT 语句时,远程服务器必须运行 PostgreSQL 9.5或之后版本,因为更早版本不支持该功能。

F.38.8. 等待事件 #

postgres_fdw 可以在 Extension 等待事件类型下报告以下事件:

PostgresFdwCleanupResult

等待远程服务器上的事务中止。

PostgresFdwConnect

等待与远程服务器建立连接。

PostgresFdwGetResult

等待从远程服务器接收查询结果。

F.38.9. 配置参数 #

postgres_fdw.application_name (string) #

指定 postgres_fdw 建立外部服务器连接时使用的 application_name 配置参数值。它覆盖服务器对象的 application_name 选项。修改此参数不会影响已经建立的连接,直到连接重新建立。

postgres_fdw.application_name 可以是任意长度的字符串,甚至包含非 ASCII 字符。但作为 application_name 传给外部服务器时,会被截短为少于 NAMEDATALEN 个字符。除可打印 ASCII 字符外的内容,会替换成 C 风格十六进制转义。详见 application_name。

% 字符开始一个“转义序列”,按下表替换为状态信息。未识别的转义被忽略,其他字符直接复制到应用名称。注意,不允许在 % 之后、选项之前指定正负号或数字字面量来进行对齐和填充。

转义 效果
%a 本地服务器上的应用名称
%c 本地服务器上的会话 ID,详见 log_line_prefix。
%C 本地服务器上的集群名称,详见 cluster_name。
%u 本地服务器上的用户名
%d 本地服务器上的数据库名
%p 本地服务器上的后端进程 ID
%% 字面量 %

例如,用户 local_user 从数据库 local_db 以 foreign_user 用户身份连接 foreign_db 时,设置 'db=%d, user=%u' 会被替换为 'db=local_db, user=local_user'。

F.38.10. 示例 #

下面是通过 postgres_fdw 创建外部表的示例。首先安装扩展:

CREATE EXTENSION postgres_fdw;

然后用 CREATE SERVER 创建外部服务器。本例要连接主机 192.83.123.89 上监听端口 5432 的 PostgreSQL 服务器,远程数据库名为 foreign_db:

CREATE SERVER foreign_server
        FOREIGN DATA WRAPPER postgres_fdw
        OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');

还需要使用 CREATE USER MAPPING 定义用户映射,标识在远程服务器上使用的角色:

CREATE USER MAPPING FOR local_user
        SERVER foreign_server
        OPTIONS (user 'foreign_user', password 'password');

现在可以通过 CREATE FOREIGN TABLE 创建外部表。本例访问远程服务器上的 some_schema.some_table 表,在本地使用名称 foreign_table:

CREATE FOREIGN TABLE foreign_table (
        id integer NOT NULL,
        data text
)
        SERVER foreign_server
        OPTIONS (schema_name 'some_schema', table_name 'some_table');

CREATE FOREIGN TABLE 中声明的列数据类型和其他属性必须与实际远程表匹配。列名也必须匹配,除非为各列附加 column_name 选项,指定对应的远程列名。在许多情况下,使用 IMPORT FOREIGN SCHEMA 比手工构建外部表定义更合适。

F.38.11. 作者 #

Shigeru Hanada <shigeru.hanada@gmail.com>


原文:F.38. postgres_fdw — access data stored in external PostgreSQL servers。来源:PostgreSQL 官方文档。

© The PostgreSQL Global Development Group。采用 PostgreSQL License。

原始版权与许可

原始许可证

PostgreSQL Database Management System
(also known as Postgres, formerly as Postgres95)

Portions Copyright © 1996-2026, The PostgreSQL Global Development Group

Portions Copyright © 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容