

# Babelfish 支持链接服务器
<a name="babelfish-postgres-linkedservers"></a>

适用于 Aurora PostgreSQL 的 Babelfish 在版本 3.1.0 中使用 PostgreSQL `tds_fdw` 扩展支持链接服务器。要使用链接服务器，您必须安装 `tds_fdw` 扩展。有关 `tds_fdw` 扩展的更多信息，请参阅[使用 Amazon Aurora PostgreSQL 支持的外部数据包装器](Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers.md)。

## 安装 `tds_fdw` 扩展
<a name="babelfish-postgres-linkedservers-tdsfdw"></a>

您可以使用以下方法安装 `tds_fdw` 扩展。

**从 PostgreSQL 终端节点使用 CREATE EXTENSION**

1. 在 PostgreSQL 端口中连接到 Babelfish 数据库上的 PostgreSQL 数据库实例。使用具有 rds\_superuser 角色的账户。

   ```
   psql --host={{your-DB-instance.aws-region.rds.amazonaws.com}} --port=5432 --username={{test}} --dbname=babelfish_db --{{password}}
   ```

1. 安装 `tds_fdw` 扩展。这是一个一次性安装过程。数据库集群重新启动时，无需重新安装。

   ```
   babelfish_db=> CREATE EXTENSION tds_fdw;
   CREATE EXTENSION
   ```

**从 TDS 终端节点调用 `sp_execute_postgresql` 存储过程**

从 3.3.0 开始，Babelfish 支持通过调用 `sp_execute_postgresql` 过程来安装 `tds_fdw` 扩展。无需退出 T-SQL 端口即可从 T-SQL 终端节点执行 PostgreSQL 语句。有关更多信息，请参阅 [使用适用于 Aurora PostgreSQL 的 Babelfish 过程](Appendix.Babelfish.Functions.md)。

1. 在 T-SQL 端口中连接到 Babelfish 数据库上的 PostgreSQL 数据库实例。

   ```
   sqlcmd -S {{your-DB-instance.aws-region.rds.amazonaws.com}} -U {{test}} -P {{password}}
   ```

1. 安装 `tds_fdw` 扩展。

   ```
   1>EXEC sp_execute_postgresql N'CREATE EXTENSION tds_fdw';
   2>go
   ```

## 支持的功能
<a name="babelfish-postgres-linkedservers-supportfunction"></a>

Babelfish 支持将远程 RDS for SQL Server 端点或适用于 Aurora PostgreSQL 的 Babelfish 端点添加为链接服务器。您也可以将其他远程 SQL Server 实例添加为链接服务器。然后，使用 `OPENQUERY()` 从这些链接服务器检索数据。从 Babelfish 版本 3.2.0 开始，还支持由四部分组成的名称。

为了使用链接服务器，支持以下存储过程和目录视图。

**存储过程**
+ **sp\_addlinkedserver** – Babelfish 不支持 `@provstr` 参数。
+ **sp\_addlinkedsrvlogin**
  + 必须提供明确的远程用户名和密码才能连接到远程数据来源。您无法使用用户自己的凭证进行连接。Babelfish 仅支持 `@useself = false`。
  + Babelfish 不支持 `@locallogin` 参数，因为不支持配置特定于本地登录的远程服务器访问。
+ **sp\_linkedservers**
+ **sp\_helplinkedsrvlogin**
+ **sp\_dropserver**
+ **sp\_droplinkedsrvlogin** – Babelfish 不支持 `@locallogin` 参数，因为不支持配置特定于本地登录的远程服务器访问。
+ **sp\_serveroption** – Babelfish 支持以下服务器选项：
  + 查询超时（自 Babelfish 版本 3.2.0）
  + 连接超时（自 Babelfish 版本 3.3.0） 
+ **sp\_testlinkedserver**（自 Babelfish 版本 3.3.0）
+ **sp\_enum\_oledb\_providers**（自 Babelfish 版本 3.3.0）

**目录视图**
+ **sys.servers**
+ **sys.linked\_logins**

## 使用传输中的加密进行连接
<a name="babelfish-postgres-linkedservers-encrytion"></a>

从适用于 Aurora PostgreSQL 的 Babelfish 源服务器到目标远程服务器的连接使用传输中加密（TLS/SSL），具体取决于远程服务器数据库配置。如果远程服务器未配置为进行加密，则向远程数据库发出请求的 Babelfish 服务器会回退到未加密状态。

**强制连接加密**
+ 如果目标链接服务器是 RDS for SQL Server 实例，则为目标 SQL Server 实例设置 `rds.force_ssl = on`。有关 RDS for SQL Server 的 SSL/TLS 配置的更多信息，请参阅[将 SSL 与 Microsoft SQL Server 数据库实例结合使用](https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html)
+ 如果目标链接服务器是适用于 Aurora PostgreSQL 的 Babelfish 集群，请为目标服务器设置 `babelfishpg_tds.tds_ssl_encrypt = on` 和 `ssl = on`。有关 SSL/TLS 的更多信息，请参阅 [Babelfish SSL 设置和客户端连接](babelfish-configuration.md#babelfish-ssl)。

## 从 SQL Server 将 Babelfish 添加为链接服务器
<a name="babelfish-linkedserver-SQLserver"></a>

适用于 Aurora PostgreSQL 的 Babelfish 可以从 SQL Server 添加为链接服务器。在 SQL Server 数据库上，可以使用适用于 ODBC 的 Microsoft OLE DB 提供程序将 Babelfish 添加为链接服务器：MSDASQL。

有两种方法可以使用 MSDASQL 提供程序从 SQL Server 将 Babelfish 配置为链接服务器：
+ 提供 ODBC 连接字符串作为提供程序字符串。
+ 添加链接服务器时提供 ODBC 数据来源的系统 DSN。

## 限制
<a name="babelfish-postgres-linkedservers-limitations"></a>
+ OPENQUERY() 仅适用于 SELECT，而不适用于 DML。
+ 由四部分组成的对象名称仅用于读取，不适用于修改远程表。UPDATE 可以在 FROM 子句中引用远程表，而无需对其进行修改。
+ 不支持针对 Babelfish 链接服务器执行存储过程。
+ 如果存在依赖于 `OPENQUERY()` 的对象或通过由四部分组成的名称引用的对象，则 Babelfish 主要版本升级可能不起作用。在主要版本升级之前，必须确保删除任何引用 `OPENQUERY()` 或由四部分组成的名称的对象。
+ 以下数据类型在远程 Babelfish 服务器上无法按预期运行：`nvarchar(max)`、`varchar(max)`、`varbinary(max)`、`binary(max)` 和 `time`。我们建议使用 CAST 函数将这些数据类型转换为支持的数据类型。

## 示例
<a name="babelfish-postgres-linkedservers-example"></a>

在以下示例中，适用于 Aurora PostgreSQL 的 Babelfish 实例正在连接到云中的 RDS for SQL Server 实例。

```
EXEC master.dbo.sp_addlinkedserver @server=N'rds_sqlserver', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'{{myserver.CB2XKFSFFMY7.US-WEST-2.RDS.AMAZONAWS.COM}}';
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'rds_sqlserver',@useself=N'False',@locallogin=NULL,@rmtuser=N'{{username}}',@rmtpassword='{{password}}';
```

 当链接服务器到位后，您可以使用 T-SQL OPENQUERY() 或标准的四部分命名来引用远程服务器上的表、视图或其他支持的对象：

```
SELECT * FROM OPENQUERY(rds_sqlserver, 'SELECT * FROM TestDB.dbo.t1');
SELECT * FROM rds_sqlserver.TestDB.dbo.t1;
```

要删除链接服务器和所有关联的登录信息，请执行以下操作：

```
EXEC master.dbo.sp_dropserver @server=N'rds_sqlserver', @droplogins=N'droplogins';
```

## 问题排查
<a name="babelfish-postgres-linkedservers-troubleshooting"></a>

您可以对源服务器和远程服务器使用同一个安全组，以允许它们相互通信。安全组应仅允许 TDS 端口（默认为 1433）上的入站流量，并且可以将安全组中的源 IP 设置为安全组 ID 本身。有关如何设置用于在具有相同安全组的实例之间进行连接的规则的更多信息，请参阅[用于在具有相同安全组的实例之间进行连接的规则](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/security-group-rules-reference.html#sg-rules-other-instances)。

如果访问权限配置不正确，当尝试查询远程服务器时，会出现一条与以下示例类似的错误消息。

```
TDS client library error: DB #: 20009, DB Msg: Unable to connect: server is unavailable or does not exist (mssql2019.aws-region.rds.amazonaws.com), OS #: 110, OS Msg: Connection timed out, Level: 9                        
```