

# Microsoft SQL Server 多可用区部署限制、说明和建议
<a name="USER_SQLServerMultiAZ.Recommendations"></a>

以下是在 RDS for SQL Server 数据库实例上使用多可用区部署时的一些限制：
+ 不支持跨区域多可用区。
+ 不支持停止多可用区部署中的 RDS for SQL Server 数据库实例。
+ 您不能将辅助数据库实例配置为接受数据库读取活动。
+ 带 Always On 可用性组 (AG) 的多可用区支持内存中优化。
+ 带 Always On 可用性组 (AG) 的多可用区不支持对可用性组侦听器进行 Kerberos 身份验证。这是因为侦听器没有服务主体名称 (SPN)。
+ 目前只有 SQL Server Web 版实例支持具有块级复制功能的多可用区。
+ 您不能重命名位于 SQL Server 多可用区部署中的 SQL Server 数据库实例上的数据库。如果您需要在此类实例上重命名一个数据库，请先为数据库实例禁用多可用区，然后重命名数据库。最后，为数据库实例重新启用多可用区。
+ 您只能还原使用完全恢复模式备份的多可用区数据库实例。
+ 多可用区部署具有 10000 个 SQL Server 代理任务的限制。

  如果您需要更高的限制，则可联系 支持 请求增加限制。打开 [AWS 支持 Center (Amazon Web Services Support 中心)](https://console.aws.amazon.com/support/home#/) 页面，登录（如有必要），然后选择 **Create case (创建案例)**。选择 **Service Limit increase (提高服务限制)**。填写并提交表格。
+ 在位于 SQL Server 多可用区部署中的 SQL Server 数据库实例上不能有脱机数据库。
+ 对于使用块级复制的实例的辅助主机，容量指标不可用。

以下是有关在 RDS for SQL Server 数据库实例上使用多可用区部署的一些说明：
+ Amazon RDS 公开 Always On AG [可用性组侦听器终端节点](https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/listeners-client-connectivity-application-failover)。此端点显示在控制台中，由 `DescribeDBInstances` API 操作作为端点字段中的条目返回。
+ Amazon RDS 支持[可用性组多子网故障转移](https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/listeners-client-connectivity-application-failover)。
+ 要对虚拟私有云（VPC）中的 SQL Server 数据库实例使用 SQL Server 多可用区，您需要先创建一个数据库子网组，此数据库子网组在至少两个不同可用区中具有子网。然后，将该数据库子网组分配给 SQL Server 数据库实例的主副本。
+ 在将数据库实例修改为多可用区部署的过程中，数据库实例的状态为 **modifying (正在修改)**。Amazon RDS 创建备用数据库实例，并创建主数据库实例的备份。这个过程完成后，主数据库实例的状态变为 **available (可用)**。
+ 多可用区部署在同一节点上维护所有数据库。如果主要主机上的某个数据库发生故障转移，所有 SQL Server 数据库都将作为一个原子单元故障转移到备用主机。Amazon RDS 预置正常运行的新主机并替换运行状况不佳的主机。
+ 带 DBM、AG 或块级复制的多可用区支持单个备用副本。
+ 在多可用区部署中，RDS for SQL Server 会创建 SQL Server 登录名，来允许 Always On AG 或数据库镜像。RDS 使用模式 `db_<dbiResourceId>_node1_login`、`db_<dbiResourceId>_node2_login` 和 `db_<dbiResourceId>_witness_login` 创建登录名。
+ RDS for SQL Server 创建 SQL Server 登录名来允许访问只读副本。RDS 使用以下模式 `db_<readreplica_dbiResourceId>_node_login` 创建登录名。
+ 您可以看到，由于执行同步数据复制，因此相对于标准数据库实例部署（在单一可用区中），延迟有所提升。
+ 故障转移时间受完成恢复过程所用的时间的影响。大型事务会增加故障转移时间。
+ 在 SQL Server 多可用区部署中，通过故障转移重新启动仅重新启动主数据库实例。故障转移后，主数据库实例将成为新的备用数据库实例。多可用区实例的参数可能不更新。对于不进行失效转移的重新启动，主数据库实例和备用数据库实例将重新启动，并在重新启动后更新参数。如果数据库实例没有响应，我们建议重新启动而不进行失效转移。

下表针对 RDS for SQL Server 多可用区部署，比较了使用数据库镜像（DBM）或 Always On 可用性组（AG）与块级复制进行的服务器级对象复制。


**按对象类型划分的复制行为**  

| 对象 | 数据库镜像/Always On AG | 块级复制 | 
| --- | --- | --- | 
| 登录名 | 是：由 Amazon RDS 复制。DEFAULT\_DATABASE 属性未被复制。在 DBM 或 Always On AG 实例上创建或更改登录名时，请勿使用 DEFAULT\_DATABASE。 | 是：包括 DEFAULT\_DATABASE（无限制）。 | 
| 数据库用户和权限 | 是：通过 SQL Server 原生复制（存储在用户数据库中）进行复制。 | 可以。 | 
| 用户定义的服务器角色 | Always On AG：是 – 复制。DBM：否 – 未复制。 | 可以。 | 
| 链接服务器 | 否：存储在 AG 或镜像之外的 master 数据库中。在启用多可用区之前创建链接的服务器，或者在失效转移后手动重新创建这些服务器。 | 是：复制整个卷，包括系统数据库。 | 
| SQL Server Audit | 部分：复制数据库审计规范（在用户数据库中）。不复制服务器审计和服务器审计规范。您必须使用 AUDIT\_GUID 参数，在辅助数据库上手动创建这些以匹配主数据库。 | 是：所有审计对象都在卷级别上复制。 | 
| tempdb 配置 | 可选：启用与以下存储过程的同步。<pre>EXECUTE msdb.dbo.rds_set_system_database_sync_objects<br />    @object_types = 'TempDbFile';</pre> 永远不会复制临时对象和数据。 | 是：在卷级别复制配置。 | 
| SQL Server Agent 作业 | 可选：启用与以下存储过程的同步。<pre>EXECUTE msdb.dbo.rds_set_system_database_sync_objects<br />    @object_types = 'SQLAgentJob';</pre> 仅复制支持类别中的 T-SQL 作业步骤。SSIS、SSRS、复制、PowerShell 和数据库邮件步骤类型不会被复制。 | 是：所有作业都在卷级别上复制。 | 
| CDC（更改数据捕获） | 部分：复制 CDC 元数据和变更表（在用户数据库中）。捕获和清理作业（在 msdb 中）不会被直接复制。失效转移后，Amazon RDS 会丢弃它们并使用先前记录的参数在新数据库重新创建。使用 rds\_set\_configuration 在辅助数据库上预设 CDC 参数。 | 是：所有 CDC 对象都在卷级别上复制。 | 
| 资源管理器 | 是：由 Amazon RDS 复制。要验证同步，请运行以下查询。<pre>SELECT * FROM msdb.dbo.rds_fn_server_object_last_sync_time();</pre>  | 可以。 | 
| 数据库拥有者 | 否：在辅助实例上，数据库所有者设置为 NT AUTHORITY\\SYSTEM。失效转移后，使用 msdb.dbo.rds\_changedbowner\_to\_rdsa 重置所有权。 | 是：保留所有者。 | 
| msdb 权限 | 否：RDS for SQL Server 不会将 msdb 数据库权限复制到辅助实例。您必须手动创建它们。 | 是：在卷级别上复制。 | 

以下是有关使用针对 RDS for Microsoft SQL Server 数据库实例的多可用区部署的一些建议：
+ 对于生产或预生产中使用的数据库，我们建议使用以下选项：
  + 多可用区部署，可实现高可用性
  + “Provisioned IOPS (预置 IOPS)”，可实现快速一致的性能
  + “内存优化”而非“通用型”
+ 您无法为辅助实例选择可用区 (AZ)，因此，在部署应用程序主机时请注意这一点。您的数据库可能故障转移到其他可用区，并且应用程序主机与数据库可能不在同一可用区中。因此，我们建议您在给定 AWS 区域中的所有可用区之间平衡应用程序主机。
+ 为了获得最佳性能，请勿在大型数据加载操作期间启用数据库镜像、Always On AG 或块级复制。如果您希望尽可能快地完成数据加载，请先完成数据加载，然后再将数据库实例转换到多可用区部署。
+ 访问 SQL Server 数据库的应用程序应具有可捕获连接错误的异常处理功能。下面的代码示例显示了一个可捕获通信错误的 try/catch 块。在此示例中，如果连接成功，`break` 语句会退出 `while` 循环，但如果引发异常，则最多可重试 10 次。

  ```
  int RetryMaxAttempts = 10;
  int RetryIntervalPeriodInSeconds = 1;
  int iRetryCount = 0;
  while (iRetryCount < RetryMaxAttempts)
  {
     using (SqlConnection connection = new SqlConnection(DatabaseConnString))
     {
        using (SqlCommand command = connection.CreateCommand())
        {
           command.CommandText = "INSERT INTO SOME_TABLE VALUES ('SomeValue');";
           try
           {
              connection.Open();
              command.ExecuteNonQuery();
              break;
           }
           catch (Exception ex) 
           {
              Logger(ex.Message);
              iRetryCount++;
           }
           finally {
              connection.Close();
           }
        }
     }
     Thread.Sleep(RetryIntervalPeriodInSeconds * 1000);
  }
  ```
+ 在处理使用 DBM 或 AG 的多可用区实例时，请勿使用 `Set Partner Off` 命令。使用块级复制的实例不支持此命令。例如，请勿执行以下操作。

  ```
  --Don't do this
  ALTER DATABASE db1 SET PARTNER off
  ```
+ 请勿将恢复模式设置为 `simple`。例如，请勿执行以下操作。

  ```
  --Don't do this
  ALTER DATABASE db1 SET RECOVERY simple
  ```
+ 在多可用区数据库实例上创建新登录名时，请勿使用 `DEFAULT_DATABASE` 参数，除非使用块级复制来实现高可用性，因为这些设置不能应用于备用镜像。例如，请勿执行以下操作。

  ```
  --Don't do this
  CREATE LOGIN [test_dba] WITH PASSWORD=foo, DEFAULT_DATABASE=[db2]
  ```

  此外，请勿执行以下操作。

  ```
  --Don't do this
  ALTER LOGIN [test_dba] WITH DEFAULT_DATABASE=[db3]
  ```