

# 使用 Amazon RDS for PostgreSQL 支持的外部数据包装器
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers"></a>

外部数据包装器 (FDW) 是一种特定类型的扩展，提供对外部数据的访问。例如，`oracle_fdw` 扩展允许您的 RDS for PostgreSQL 数据库集群使用 Oracle 数据库。再例如，通过使用 PostgreSQL 本机 `postgres_fdw` 扩展，您可以访问存储在 RDS for PostgreSQL 数据库实例外部的 PostgreSQL 数据库实例中的数据。

在下文中，您可以了解有关几种支持的 PostgreSQL 外部数据包装器的信息。

**Topics**
+ [使用 log\$1fdw 扩展通过 SQL 访问数据库日志](CHAP_PostgreSQL.Extensions.log_fdw.md)
+ [使用 postgres\$1fdw 扩展访问外部数据](postgresql-commondbatasks-fdw.md)
+ [使用 mysql\$1fdw 扩展处理 MySQL 数据库](postgresql-mysql-fdw.md)
+ [通过使用 oracle\$1fdw 扩展来使用 Oracle 数据库](postgresql-oracle-fdw.md)
+ [通过使用 tds\$1fdw 扩展来使用 SQL Server 数据库](postgresql-tds-fdw.md)

# 使用 log\$1fdw 扩展通过 SQL 访问数据库日志
<a name="CHAP_PostgreSQL.Extensions.log_fdw"></a>

RDS for PostgreSQL 数据库实例支持 `log_fdw` 扩展，您可以使用该扩展通过 SQL 界面访问数据库引擎日志。此 `log_fdw` 扩展提供了两个新函数，便于创建数据库日志的外部表：
+ `list_postgres_log_files` – 列出数据库日志目录中的文件，以及文件大小 (以字节为单位)。
+ `create_foreign_table_for_log_file(table_name text, server_name text, log_file_name text)` – 针对当前数据库中的指定文件构建外部表。

`log_fdw` 创建的所有函数均归 `rds_superuser` 所有。`rds_superuser` 角色的成员可以将这些函数的访问权限授予其他数据库用户。

默认情况下，日志文件由 Amazon RDS 以 `stderr`（标准错误）格式生成，如 `log_destination` 参数中指定。此参数只有两个选项，即，`stderr` 和 `csvlog`（逗号分隔值，CSV）。如果您向参数添加 `csvlog` 选项，Amazon RDS 会同时生成 `stderr` 和 `csvlog` 日志。这可能会影响数据库集群的存储容量，因此您需要了解影响日志处理的其它参数。有关更多信息，请参阅 [设置日志目标（`stderr`、`csvlog`）](USER_LogAccess.Concepts.PostgreSQL.overview.parameter-groups.md#USER_LogAccess.Concepts.PostgreSQL.Log_Format)。

生成 `csvlog` 日志的一个优势是 `log_fdw` 扩展允许您构建将数据整齐地拆分为多个列的外部表。为此，您的实例需要与自定义数据库参数组关联，以便您可以更改 `log_destination` 的设置。有关如何执行此操作的更多信息，请参阅。[在 RDS for PostgreSQL 数据库实例上使用参数](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)

以下示例假设 `log_destination` 参数包含 `cvslog`。

**使用 log\$1fdw 扩展**

1. 安装 `log_fdw` 扩展。

   ```
   postgres=> CREATE EXTENSION log_fdw;
   CREATE EXTENSION
   ```

1. 创建日志服务器，作为外部数据包装器。

   ```
   postgres=> CREATE SERVER log_server FOREIGN DATA WRAPPER log_fdw;
   CREATE SERVER
   ```

1. 选择日志文件列表中的所有文件。

   ```
   postgres=> SELECT * FROM list_postgres_log_files() ORDER BY 1;
   ```

   示例响应如下所示。

   ```
             file_name           | file_size_bytes
   ------------------------------+-----------------
    postgresql.log.2023-08-09-22.csv |            1111
    postgresql.log.2023-08-09-23.csv |            1172
    postgresql.log.2023-08-10-00.csv |            1744
    postgresql.log.2023-08-10-01.csv |            1102
   (4 rows)
   ```

1. 为所选文件创建包含单个“log\$1entry”列的表。

   ```
   postgres=> SELECT create_foreign_table_for_log_file('my_postgres_error_log',
        'log_server', 'postgresql.log.2023-08-09-22.csv');
   ```

   除了告知现在存在表格外，响应不提供详细信息。

   ```
   -----------------------------------
   (1 row)
   ```

1. 选择日志文件的示例。以下代码检索日志时间和错误消息描述。

   ```
   postgres=> SELECT log_time, message FROM my_postgres_error_log ORDER BY 1;
   ```

   示例响应如下所示。

   ```
                log_time             |                                  message
   ----------------------------------+---------------------------------------------------------------------------
   Tue Aug 09 15:45:18.172 2023 PDT | ending log output to stderr
   Tue Aug 09 15:45:18.175 2023 PDT | database system was interrupted; last known up at 2023-08-09 22:43:34 UTC
   Tue Aug 09 15:45:18.223 2023 PDT | checkpoint record is at 0/90002E0
   Tue Aug 09 15:45:18.223 2023 PDT | redo record is at 0/90002A8; shutdown FALSE
   Tue Aug 09 15:45:18.223 2023 PDT | next transaction ID: 0/1879; next OID: 24578
   Tue Aug 09 15:45:18.223 2023 PDT | next MultiXactId: 1; next MultiXactOffset: 0
   Tue Aug 09 15:45:18.223 2023 PDT | oldest unfrozen transaction ID: 1822, in database 1
   (7 rows)
   ```

# 使用 postgres\$1fdw 扩展访问外部数据
<a name="postgresql-commondbatasks-fdw"></a>

您可以使用 [postgres\$1fdw](https://www.postgresql.org/docs/current/static/postgres-fdw.html) 扩展访问远程数据库服务器上表中的数据。如果您从 PostgreSQL 数据库实例设置远程连接，则访问还可用于您的只读副本。

**使用 postgres\$1fdw 访问远程数据库服务器**

1. 安装 postgres\$1fdw 扩展。

   ```
   CREATE EXTENSION postgres_fdw;
   ```

1. 使用 CREATE SERVER 创建外部数据服务器。

   ```
   CREATE SERVER foreign_server
   FOREIGN DATA WRAPPER postgres_fdw
   OPTIONS (host 'xxx.xx.xxx.xx', port '5432', dbname 'foreign_db');
   ```

1. 创建用户映射，用于标识将在远程服务器上使用的角色。
**重要**  
要掩蔽密码以使其不出现在日志中，请在会话级别设置 `log_statement=none`。在参数级别进行设置不会掩蔽密码。

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

1. 创建一个表，该表映射到远程服务器上的表。

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

# 使用 mysql\$1fdw 扩展处理 MySQL 数据库
<a name="postgresql-mysql-fdw"></a>

要从 RDS for PostgreSQL 数据库实例访问 MySQL 兼容数据库，您可以安装并使用 `mysql_fdw` 扩展。这款外部数据包装器允许您使用 RDS for MySQL、Aurora MySQL、MariaDB 和其他 MySQL 兼容数据库。从 RDS for PostgreSQL 数据库实例到 MySQL 数据库的连接会尽可能加密，具体取决于客户端和服务器配置。但是，如果您愿意，可以强制加密。有关更多信息，请参阅 [将传输中加密与扩展配合使用](#postgresql-mysql-fdw.encryption-in-transit)。

`mysql_fdw` 扩展在 Amazon RDS for PostgreSQL 版本 14.2、13.6 以及更高版本中受支持。它支持从 RDS for PostgreSQL 数据库到 MySQL 兼容数据库实例上的表的选择、插入、更新和删除。

**Topics**
+ [将 RDS for PostgreSQL 数据库设置为使用 mysql\$1fdw 扩展](#postgresql-mysql-fdw.setting-up)
+ [示例：从 RDS for PostgreSQL 使用 RDS for MySQL 数据库](#postgresql-mysql-fdw.using-mysql_fdw)
+ [将传输中加密与扩展配合使用](#postgresql-mysql-fdw.encryption-in-transit)

## 将 RDS for PostgreSQL 数据库设置为使用 mysql\$1fdw 扩展
<a name="postgresql-mysql-fdw.setting-up"></a>

在您的 RDS for PostgreSQL 数据库实例上设置 `mysql_fdw` 扩展涉及到在数据库实例中加载扩展，然后创建到 MySQL 数据库实例的连接点。对于该任务，您需要了解有关 MySQL 数据库实例的以下详细信息：
+ 主机名或终端节点。对于RDS for MySQL 数据库实例，您可以使用控制台查找终端节点。选择 Connectivity & security（连接和安全）选项卡，然后查看 Endpoint and port（终端节点和端口）部分。
+ 端口号。MySQL 的默认端口是 3306。
+ 数据库的名称。数据库标识符。

您还需要为 MySQL 端口 3306 提供对安全组或访问控制列表 (ACL) 的访问权限。RDS for PostgreSQL 数据库实例和 RDS for MySQL 数据库实例均需要访问端口 3306。如果访问权限配置不正确，当尝试连接到 MySQL 兼容表时，您会看到一条与以下内容类似的错误消息：

```
ERROR: failed to connect to MySQL: Can't connect to MySQL server on 'hostname.aws-region.rds.amazonaws.com:3306' (110)
```

在以下过程中，您（作为 `rds_superuser` 账户）创建外部服务器。然后，您将访问外部服务器的权限授予特定用户。然后，这些用户创建其自身到相应 MySQL 用户账户的映射以使用 MySQL 数据库实例。

**使用 mysql\$1fdw 访问 MySQL 数据库服务器**

1. 使用具有 `rds_superuser` 角色的账户连接到您的 PostgreSQL 数据库实例。如果在创建 RDS for PostgreSQL 数据库实例时接受默认值，则用户名为 `postgres`，您可以使用 `psql` 命令行工具进行连接，如下所示：

   ```
   psql --host=your-DB-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres –-password
   ```

1. 按如下方式安装 `mysql_fdw` 扩展：

   ```
   postgres=> CREATE EXTENSION mysql_fdw;
   CREATE EXTENSION
   ```

在 RDS for PostgreSQL 数据库实例上安装扩展后，您可以设置提供与 MySQL 数据库连接的外部服务器。

**创建外部服务器**

在 RDS for PostgreSQL 数据库实例上执行这些任务。这些步骤假定您以具有 `rds_superuser` 特权的用户身份连接，例如 `postgres`。

1. 在 RDS for PostgreSQL 数据库实例中创建外部服务器：

   ```
   postgres=> CREATE SERVER mysql-db FOREIGN DATA WRAPPER mysql_fdw OPTIONS (host 'db-name.111122223333.aws-region.rds.amazonaws.com', port '3306');
   CREATE SERVER
   ```

1. 向适当的用户授予访问外部服务器的权限。这些用户应该是非管理员用户，即，没有 `rds_superuser` 角色的用户。

   ```
   postgres=> GRANT USAGE ON FOREIGN SERVER mysql-db to user1;
   GRANT
   ```

PostgreSQL 用户通过外部服务器创建和管理其自身与 MySQL 数据库的连接。

## 示例：从 RDS for PostgreSQL 使用 RDS for MySQL 数据库
<a name="postgresql-mysql-fdw.using-mysql_fdw"></a>

假设您在 RDS for PostgreSQL 数据库实例上有一个简单的表。您的 RDS for PostgreSQL 用户想要在该表中查询（`SELECT`）、`INSERT`、`UPDATE` 和 `DELETE` 项目。假设 `mysql_fdw` 扩展是在您的 RDS for PostgreSQL 数据库实例上创建的，如前面的过程中所述。以具有 `rds_superuser` 权限的用户身份连接到 RDS for PostgreSQL 数据库实例后，您可以继续执行以下步骤。

1. 在 RDS for PostgreSQL 数据库实例上，创建一个外部服务器：

   ```
   test=> CREATE SERVER mysqldb FOREIGN DATA WRAPPER mysql_fdw OPTIONS (host 'your-DB.aws-region.rds.amazonaws.com', port '3306');
   CREATE SERVER
   ```

1. 将使用权授予没有 `rds_superuser` 权限的用户，例如 `user1`：

   ```
   test=> GRANT USAGE ON FOREIGN SERVER mysqldb TO user1;
   GRANT
   ```

1. 作为 *user1* 连接，然后创建一个到 MySQL 用户的映射：

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER mysqldb OPTIONS (username 'myuser', password 'mypassword');
   CREATE USER MAPPING
   ```

1. 创建链接到 MySQL 表的外部表：

   ```
   test=> CREATE FOREIGN TABLE mytab (a int, b text) SERVER mysqldb OPTIONS (dbname 'test', table_name '');
   CREATE FOREIGN TABLE
   ```

1. 针对外表运行简单查询：

   ```
   test=> SELECT * FROM mytab;
   a |   b
   ---+-------
   1 | apple
   (1 row)
   ```

1. 您可以从 MySQL 表中添加、更改和删除数据。例如：

   ```
   test=> INSERT INTO mytab values (2, 'mango');
   INSERT 0 1
   ```

   再次运行 `SELECT` 查询以查看结果：

   ```
   test=> SELECT * FROM mytab ORDER BY 1;
    a |   b
   ---+-------
   1 | apple
   2 | mango
   (2 rows)
   ```

## 将传输中加密与扩展配合使用
<a name="postgresql-mysql-fdw.encryption-in-transit"></a>

默认情况下，从 RDS for PostgreSQL 到 MySQL 的连接使用传输中加密（TLS/SSL）。但是，当客户端和服务器配置不同时，连接会回退为非加密状态。您可以通过在 RDS for MySQL 用户账户上指定 `REQUIRE SSL` 选项来对所有传出连接强制加密。这种方法也适用于 MariaDB 和 Aurora MySQL 用户账户。

对于配置为 `REQUIRE SSL` 的 MySQL 用户帐户，如果无法建立安全连接，则连接尝试将失败。

要对现有 MySQL 数据库用户帐户强制加密，可以使用 `ALTER USER` 命令。根据 MySQL 版本的不同，语法有所不同，如下表所示。有关更多信息，请参阅《MySQL 参考手册》**中的 [ALTER USER](https://dev.mysql.com/doc/refman/8.0/en/alter-user.html)。


| MySQL 5.7、MySQL 8.0 | MySQL 5.6 | 
| --- | --- | 
|  `ALTER USER 'user'@'%' REQUIRE SSL;`  |  `GRANT USAGE ON *.* to 'user'@'%' REQUIRE SSL;`  | 

有关 `mysql_fdw` 扩展的更多信息，请参阅 [mysql\$1fdw](https://github.com/EnterpriseDB/mysql_fdw) 文档。

# 通过使用 oracle\$1fdw 扩展来使用 Oracle 数据库
<a name="postgresql-oracle-fdw"></a>

要从 RDS for PostgreSQL 数据库实例访问 Oracle 数据库，您可以安装并使用 `oracle_fdw` 扩展。此扩展是 Oracle 数据库的外部数据包装器。要了解有关此扩展的更多信息，请参阅 [oracle\$1fdw](https://github.com/laurenz/oracle_fdw) 文档。

RDS for PostgreSQL 12.7、13.3 及更高版本支持 `oracle_fdw` 扩展。

**Topics**
+ [启用 oracle\$1fdw 扩展](#postgresql-oracle-fdw.enabling)
+ [示例：使用链接到 Amazon RDS for Oracle Database 的外部服务器](#postgresql-oracle-fdw.example)
+ [在传输过程中使用加密](#postgresql-oracle-fdw.encryption)
+ [了解 pg\$1user\$1mappings 视图和权限](#postgresql-oracle-fdw.permissions)

## 启用 oracle\$1fdw 扩展
<a name="postgresql-oracle-fdw.enabling"></a>

要使用 oracle\$1fdw 扩展，请执行以下步骤。

**启用 oracle\$1fdw 扩展**
+ 使用具有 `rds_superuser` 权限的账户运行以下命令。

  ```
  CREATE EXTENSION oracle_fdw;
  ```

## 示例：使用链接到 Amazon RDS for Oracle Database 的外部服务器
<a name="postgresql-oracle-fdw.example"></a>

以下示例展示如何使用链接到 Amazon RDS for Oracle Database 的外部服务器。

**创建链接到 RDS for Oracle 数据库的外部服务器**

1. 请注意 RDS for Oracle 数据库实例上的以下内容：
   + Endpoint
   + 端口
   + 数据库名称

1. 创建外部服务器。

   ```
   test=> CREATE SERVER oradb FOREIGN DATA WRAPPER oracle_fdw OPTIONS (dbserver '//endpoint:port/DB_name');
   CREATE SERVER
   ```

1. 将使用权授予没有 `rds_superuser` 权限的用户，例如 `user1`。

   ```
   test=> GRANT USAGE ON FOREIGN SERVER oradb TO user1;
   GRANT
   ```

1. 作为 `user1` 连接并创建到 Oracle 用户的映射。

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER oradb OPTIONS (user 'oracleuser', password 'mypassword');
   CREATE USER MAPPING
   ```

1. 创建链接到 Oracle 表的外部表。

   ```
   test=> CREATE FOREIGN TABLE mytab (a int) SERVER oradb OPTIONS (table 'MYTABLE');
   CREATE FOREIGN TABLE
   ```

1. 查询外部表。

   ```
   test=>  SELECT * FROM mytab;
   a
   ---
   1
   (1 row)
   ```

如果查询报告以下错误，请检查您的安全组和访问控制列表（ACL）以确保两个实例可以通信。

```
ERROR: connection for foreign table "mytab" cannot be established
DETAIL: ORA-12170: TNS:Connect timeout occurred
```

## 在传输过程中使用加密
<a name="postgresql-oracle-fdw.encryption"></a>

PostgreSQL-to-Oracle 传输中加密基于客户端和服务器配置参数的组合。有关使用 Oracle 21c 的示例，请参阅 Oracle 文档中的[关于协商加密和完整性的值](https://docs.oracle.com/en/database/oracle/oracle-database/21/dbseg/configuring-network-data-encryption-and-integrity.html#GUID-3A2AF4AA-AE3E-446B-8F64-31C48F27A2B5)。用于 Amazon RDS 上 oracle\$1fdw 的客户端配置有 `ACCEPTED`，这意味着加密取决于 Oracle 数据库服务器配置，并且使用 Oracle 安全库（libnnz）进行加密。

如果您的数据库位于 RDS for Oracle 上，请参阅 [Oracle 本机网络加密](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.NetworkEncryption.html)来配置加密。

## 了解 pg\$1user\$1mappings 视图和权限
<a name="postgresql-oracle-fdw.permissions"></a>

PostgreSQL 目录 `pg_user_mapping` 存储 RDS for PostgreSQL 用户到外部数据（远程）服务器上用户的映射。虽然对目录的访问受到限制，但是您可以使用 `pg_user_mappings` 视图来查看映射。在下面，您可以找到一个示例，该示例演示如何将权限应用于示例 Oracle 数据库，但此信息更普遍地适用于任何外部数据包装器。

在以下输出中，您可以找到映射到三个不同示例用户的角色和权限。用户 `rdssu1` 和 `rdssu2` 是 `rds_superuser` 角色的成员，而 `user1` 不是。此示例使用 `psql` 元命令 `\du` 列出现有角色。

```
test=>  \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+-------------------------------------------------------------
 rdssu1          |                                                            | {rds_superuser}
 rdssu2          |                                                            | {rds_superuser}
 user1           |                                                            | {}
```

所有用户，包括具有 `rds_superuser` 权限的用户，都可以查看 `pg_user_mappings` 表中他们自己的用户映射 (`umoptions`)。如以下示例所示，当 `rdssu1` 尝试获取所有用户映射时，即使存在 `rdssu1``rds_superuser` 权限，也会出现错误：

```
test=> SELECT * FROM pg_user_mapping;
ERROR: permission denied for table pg_user_mapping
```

下面是一些示例。

```
test=> SET SESSION AUTHORIZATION rdssu1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     | {user=oracleuser,password=mypwd}
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)

test=> SET SESSION AUTHORIZATION rdssu2;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     | {user=oracleuser,password=mypwd}
 (3 rows)

test=> SET SESSION AUTHORIZATION user1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |           umoptions
-------+-------+---------+--------+------------+--------------------------------
 16414 | 16411 | oradb   |  16412 | user1      | {user=oracleuser,password=mypwd}
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)
```

由于 `information_schema._pg_user_mappings` 和 `pg_catalog.pg_user_mappings` 的实施差异，手动创建的 `rds_superuser` 需要额外的权限才能在 `pg_catalog.pg_user_mappings` 中查看密码。

`rds_superuser` 无需额外权限即可在 `information_schema._pg_user_mappings` 中查看密码。

没有 `rds_superuser` 角色的用户只能在以下条件下在 `pg_user_mappings` 中查看密码：
+ 当前用户是被映射的用户，拥有服务器或对其具有 `USAGE` 权限。
+ 当前用户是服务器所有者，此映射用于 `PUBLIC`。

# 通过使用 tds\$1fdw 扩展来使用 SQL Server 数据库
<a name="postgresql-tds-fdw"></a>

您可以使用 PostgreSQL `tds_fdw` 扩展来访问支持表格数据流 (TDS) 协议的数据库，例如 Sybase 和 Microsoft SQL Server 数据库。此外部数据包装器可让您从 RDS for PostgreSQL 数据库实例 连接到使用 TDS 协议的数据库，包括 Amazon RDS for Microsoft SQL Server。有关更多信息，请参阅 GitHub 上的 [tds-fdw/tds\$1fdw](https://github.com/tds-fdw/tds_fdw) 文档。

Amazon RDS for PostgreSQL 版本 14.2、13.6 及更高版本支持该 `tds_fdw` 扩展。

## 将 Aurora PostgreSQL 数据库设置为使用 tds\$1fdw 扩展
<a name="postgresql-tds-fdw-setting-up"></a>

在以下过程中，您可以找到设置 `tds_fdw` 并将其与 RDS for PostgreSQL 数据库实例结合使用的示例。在可以使用 `tds_fdw` 连接到 SQL Server 数据库之前，您需要获取实例的以下详细信息：
+ 主机名或终端节点。对于 RDS for SQL Server 数据库实例，您可以使用控制台查找终端节点。选择 Connectivity & security（连接和安全）选项卡，然后查看 Endpoint and port（终端节点和端口）部分。
+ 端口号。Microsoft SQL Server 的默认端口是 1433。
+ 数据库的名称。数据库标识符。

您还需要为 SQL Server 端口 1433 提供对安全组或访问控制列表 (ACL) 的访问权限。RDS for PostgreSQL 数据库实例和 RDS for SQL Server 数据库实例都需要访问端口 1433。如果访问权限配置不正确，当您尝试查询 Microsoft SQL Server 时，会看到以下错误消息：

```
ERROR: DB-Library error: DB #: 20009, DB Msg: Unable to connect:
Adaptive Server is unavailable or does not exist (mssql2019.aws-region.rds.amazonaws.com), OS #: 0, OS Msg: Success, Level: 9
```

**使用 tds\$1fdw 连接到 SQL Server 数据库**

1. 使用具有 `rds_superuser` 角色的账户连接到您的 PostgreSQL 数据库实例：

   ```
   psql --host=your-DB-instance.aws-region.rds.amazonaws.com --port=5432 --username=test –-password
   ```

1. 安装 `tds_fdw` 扩展：

   ```
   test=> CREATE EXTENSION tds_fdw;
   CREATE EXTENSION
   ```

在 RDS for PostgreSQL 数据库实例上安装扩展后，应设置外部服务器。

**创建外部服务器**

使用具有 `rds_superuser` 权限的账户在 RDS for PostgreSQL 数据库实例上执行这些任务。

1. 在 RDS for PostgreSQL 数据库实例中创建外部服务器：

   ```
   test=> CREATE SERVER sqlserverdb FOREIGN DATA WRAPPER tds_fdw OPTIONS (servername 'mssql2019.aws-region.rds.amazonaws.com', port '1433', database 'tds_fdw_testing');
   CREATE SERVER
   ```

   要访问 SQLServer 端的非 ASCII 数据，请在 RDS for PostgreSQL 数据库实例中使用 character\$1set 选项创建服务器链接：

   ```
   test=> CREATE SERVER sqlserverdb FOREIGN DATA WRAPPER tds_fdw OPTIONS (servername 'mssql2019.aws-region.rds.amazonaws.com', port '1433', database 'tds_fdw_testing', character_set 'UTF-8');
   CREATE SERVER
   ```

1. 向没有 `rds_superuser` 角色权限的用户授予权限，例如 `user1`：

   ```
   test=> GRANT USAGE ON FOREIGN SERVER sqlserverdb TO user1;
   ```

1. 以 user1 身份进行连接，然后创建到 SQL Server 用户的映射：

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER sqlserverdb OPTIONS (username 'sqlserveruser', password 'password');
   CREATE USER MAPPING
   ```

1. 创建链接到 SQL Server 表的外部表：

   ```
   test=> CREATE FOREIGN TABLE mytab (a int) SERVER sqlserverdb OPTIONS (table 'MYTABLE');
   CREATE FOREIGN TABLE
   ```

1. 查询外部表：

   ```
   test=> SELECT * FROM mytab;
    a
   ---
    1
   (1 row)
   ```

### 使用传输中的加密进行连接
<a name="postgresql-tds-fdw-ssl-tls-encryption"></a>

RDS for PostgreSQL 到 SQL Server 的连接使用传输中加密 (TLS/SSL)，具体取决于 SQL Server 数据库配置。如果 SQL Server 未配置为加密，则向 SQL Server 数据库发出请求的 RDS for PostgreSQL 客户端将回退到未加密状态。

您可以通过设置 `rds.force_ssl` 参数对与 RDS for SQL Server 数据库实例的连接进行加密。要了解操作方法，请参阅[强制与数据库实例的连接使用 SSL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html#SQLServer.Concepts.General.SSL.Forcing)。有关 RDS for SQL Server 的 SSL/TLS 配置的更多信息，请参阅[将 SSL 与 Microsoft SQL Server 数据库实例结合使用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html)。