为 Azure SQL 托管实例配置故障转移组

适用于:Azure SQL 托管实例

本文介绍如何使用 Azure 门户和 Azure PowerShell 为 Azure SQL 托管实例配置故障转移组

若要使端到端 PowerShell 脚本在故障转移组中创建这两个实例,请查阅使用 PowerShell 将实例添加到故障转移组

先决条件

要配置故障转移组,你需要事先具有恰当的权限以及一个要用作主实例的 SQL 托管实例。 要开始,请查阅创建实例

在创建辅助实例和故障转移组之前,请务必检查限制

配置要求

若要在主 SQL 托管实例和辅助 SQL 托管实例之间配置一个故障转移组,请考虑以下要求:

  • 辅助托管实例必须为空,即不包含任何用户数据库。
  • 这两个实例需位于相同的服务层级,并且具有相同的存储大小。 强烈建议让两个实例具有相同的计算大小,以确保辅助实例可以持续处理从主实例复制的更改(包括峰值活动的周期),虽然这不是必需的。
  • 主 IP 实例虚拟网络的地址范围不得与辅助托管实例的虚拟网络的地址范围以及与主虚拟网络或辅助虚拟网络对等互连的任何其他虚拟网络对等互连重叠。
  • 这两个实例必须位于相同的 DNS 区域中。 创建辅助托管实例时,必须指定主实例的 DNS 区域 ID。 如果你没有指定,则在每个虚拟网络中创建第一个实例时,将生成随机字符串形式的区域 ID,同一个 ID 将分配到同一子网中的所有其他实例。 分配后,无法修改 DNS 区域。
  • 两个实例子网的网络安全组 (NSG) 规则必须打开端口 5022 和端口范围 11000-11999 的入站和出站 TCP 连接,以方便两个实例之间的通信。
  • 出于性能原因,托管实例应部署到配对区域中。 与未配对区域相比,驻留在异地配对区域中的托管实例受益于明显更高的异地复制速度。
  • 这两个实例必须使用相同的更新策略。

创建辅助实例

创建辅助实例时,所使用的虚拟网络的 IP 地址空间不得与主实例的 IP 地址空间范围重叠。 另外,配置新的辅助实例时,必须指定主实例的区域 ID。

可以使用 Azure 门户 和 PowerShell 来配置辅助虚拟网络并创建辅助实例。

可以使用 PowerShell 创建虚拟网络和辅助实例。 有关同时执行这两项的完整 PowerShell 脚本示例,请查阅使用 PowerShell 将实例添加到故障转移组

如果要使用 Azure PowerShell 创建辅助实例,请确保将 DnsZonePartner 值指定为主实例的区域 ID。

可以使用 Get-AzSqlInstance 命令参数化主实例的 DNS 区域 ID,然后将其传递给 DnsZonePartner New-AzSqlInstance 命令的参数

# Get the DNS zone ID of the primary instance
$primaryManagedInstanceId = Get-AzSqlInstance -Name $primaryInstance -ResourceGroupName $resourceGroupName | Select-Object Id

在实例之间建立连接

为确保异地复制通信流不间断,必须在托管主实例和辅助实例的虚拟网络子网之间建立连接。 有多种方法可以连接不同 Azure 区域中的托管实例,其中包括:

建议使用全局虚拟网络对等互连,作为在故障转移组中的实例之间建立连接的最高性能和最可靠的方法。 全局虚拟网络对等互连使用 Microsoft 主干基础结构,在对等互连的虚拟网络之间提供低延迟、高带宽的专用连接。 在对等互连的虚拟网络之间通信不需公共 Internet、网关或额外加密。

重要

连接涉及其他网络设备的实例的替代方法可能会使连接故障排除或复制速度问题复杂化,可能需要网络管理员的积极参与,并可能显著延长解决时间。

如果使用机制(而不是使用建议的全局虚拟网络对等互连)来建立实例之间的连接,则需要确保:

  • 网络设备(如防火墙或网络虚拟设备 (NVA))不会阻止端口 5022 (TCP) 和端口范围 11000-11999 的入站和出站连接上的流量。
  • 路由已正确配置,并且避免了非对称路由。

本文介绍如何使用 Azure 门户 和 PowerShell 在两个实例的网络之间配置全局虚拟网络对等互连。

在主托管实例和辅助托管实例的虚拟网络之间配置全局虚拟网络对等互连:

# Create global virtual network peering
$primaryVirtualNetwork  = Get-AzVirtualNetwork -Name $primaryVNet -ResourceGroupName $resourceGroupName

$secondaryVirtualNetwork = Get-AzVirtualNetwork -Name $secondaryVNet -ResourceGroupName $resourceGroupName
                  
Write-host "Peering primary VNet to secondary VNet..."
Add-AzVirtualNetworkPeering -Name primaryVnet-secondaryVNet1 -VirtualNetwork $primaryVirtualNetwork -RemoteVirtualNetworkId $secondaryVirtualNetwork.Id
 Write-host "Primary VNet peered to secondary VNet successfully."

Write-host "Peering secondary VNet to primary VNet..."
Add-AzVirtualNetworkPeering -Name secondaryVNet-primaryVNet -VirtualNetwork $secondaryVirtualNetwork -RemoteVirtualNetworkId $primaryVirtualNetwork.Id
Write-host "Secondary VNet peered to primary VNet successfully."

Write-host "Checking peering state on the primary virtual network..."
Get-AzVirtualNetworkPeering -ResourceGroupName $resourceGroupName -VirtualNetworkName $primaryVNet | Select PeeringState

Write-host "Checking peering state on the secondary virtual network..."
Get-AzVirtualNetworkPeering -ResourceGroupName $resourceGroupName -VirtualNetworkName $secondaryVNet | Select PeeringState

此代码片段使用以下命令:

命令 说明
1. Get-AzVirtualNetwork 获取资源组中的虚拟网络。
2. Add-AzVirtualNetworkPeering 将对等互连添加到虚拟网络。
3. Get-AzVirtualNetworkPeering 获取虚拟网络的对等互连。

配置端口和 NSG 规则

无论两个实例之间选择的连接机制为何,网络都必须满足以下异地复制流量的要求:

  • 分配给托管实例子网的路由表和网络安全组不会在两个对等互连的虚拟网络之间共享。
  • 托管每个实例的两个子网上的网络安全组 (NSG) 规则允许端口 5022 和端口范围 11000-11999 上的入站和出站流量流向其他实例。

可以使用 Azure 门户和 PowerShell 配置端口通信和 NSG 规则。

可以使用 Add-AzNetworkSecurityRuleConfig PowerShell 命令来修改现有网络安全组,为这两个虚拟网络配置 NSG 规则。 有关配置这两个网络的完整 PowerShell 脚本示例,请查阅使用 PowerShell 将实例添加到故障转移组

创建故障转移组

使用 Azure 门户或 PowerShell 为托管实例创建故障转移组。

使用 New-AzSqlDatabaseInstanceFailoverGroup 通过 PowerShell 为托管实例创建故障转移组。

# Create failover group
Write-host "Creating the failover group..."
$failoverGroup = New-AzSqlDatabaseInstanceFailoverGroup -Name $failoverGroupName -Location $location -ResourceGroupName $resourceGroupName -PrimaryManagedInstanceName $primaryInstance -PartnerRegion $drLocation -PartnerManagedInstanceName $secondaryInstance -FailoverPolicy Manual -GracePeriodWithDataLossHours 1
$failoverGroup

测试故障转移

使用 Azure 门户或 PowerShell 测试故障转移组的故障转移。

备注

如果实例位于不同的订阅或资源组中,从辅助实例启动故障转移。

通过使用 PowerShell 故障转移到辅助副本,然后故障回复来测试计划的故障转移。

验证每个实例的角色

使用 Get-AzSqlDatabaseInstanceFailoverGroup 命令确认每个实例的角色:

# Verify the current primary role
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $location -Name $failoverGroupName

故障转移到辅助实例

使用 Switch-AzSqlDatabaseFailoverGroup 故障转移到辅助实例。

# Failover the primary managed instance to the secondary role
Write-host "Failing primary over to the secondary location"
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $drLocation -Name $failoverGroupName | Switch-AzSqlDatabaseInstanceFailoverGroup
Write-host "Successfully failed failover group to secondary location"

# Verify the current primary role
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $drLocation -Name $failoverGroupName

验证每个实例的角色

使用 Get-AzSqlDatabaseInstanceFailoverGroup 命令确认每个实例的角色:

# Verify the current primary role
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $location -Name $failoverGroupName

将故障转移组还原到主服务器

或者,使用 Switch-AzSqlDatabaseFailoverGroup 命令故障回复到主实例。

# Fail primary managed instance back to primary role
Write-host "Failing primary back to primary role"
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $location -Name $failoverGroupName | Switch-AzSqlDatabaseInstanceFailoverGroup
Write-host "Successfully failed failover group to primary location"

# Verify the current primary role
Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName -Location $location -Name $failoverGroupName

修改现有故障转移组

可以使用 Azure 门户、PowerShell、Azure CLI 和 REST API 修改现有故障转移组,例如更改故障转移策略

要使用 Azure 门户修改现有的故障转移组,请遵照以下步骤执行:

  1. 转到 Azure 门户中的 SQL 托管实例

  2. 在“数据管理”下,选择“故障转移组”以打开“故障转移组”窗格。

  3. 在“故障转移组”窗格中,从命令栏中选择“编辑配置”以打开“编辑故障转移组”窗格:

    Azure 门户中的“故障转移组”窗格屏幕截图,其中突出显示了“编辑配置”。

定位侦听器终结点

配置故障转移组后,更新应用程序的连接字符串,以指向“读/写”侦听器终结点,以便应用程序在故障转移后继续连接到主实例。 通过使用侦听器终结点,无需在每次故障转移组故障转移时都手动更新连接字符串,因为流量始终会被路由到当前的主数据库。 还可以将只读工作负载指向“只读”侦听器终结点。

重要

虽然支持使用实例专用连接字符串连接到故障转移组中的实例时,但强烈建议不要这样做。 应改用侦听器端点。

若要在 Azure 门户中找到侦听器终结点,请转到你的 SQL 托管实例,然后在“数据管理”下选择“故障转移组”

向下滚动,查找侦听器终结点:

  • “读/写”侦听器终结点,其形式是 fog-name.dns-zone.database.chinacloudapi.cn,会将流量路由到主实例。
  • “只读”侦听器终结点,其形式是 fog-name.secondary.dns-zone.database.chinacloudapi.cn,会将流量路由到辅助实例。

显示在 Azure 门户中查找故障转移组连接字符串的位置的屏幕截图。

在不同订阅的实例之间创建故障转移组

只要订阅与同一个 Microsoft Entra 租户关联,就可以在两个不同订阅中的 SQL 托管实例之间创建故障转移组。

  • 使用 PowerShell API 时,可以通过为辅助 SQL 托管实例指定 PartnerSubscriptionId 参数来执行此操作。
  • 使用 REST API 时,properties.managedInstancePairs 参数中包含的每个实例 ID 都可以具有自己的订阅 ID。
  • Azure 门户不支持创建跨不同订阅的故障转移组。

重要

Azure 门户不支持创建跨不同订阅的故障转移组。 对于跨不同订阅和/或资源组的故障转移组,不能通过 Azure 门户从主 SQL 托管实例手动启动故障转移。 改为从异地辅助实例启动它。

防止关键数据丢失

由于广域网的延迟时间较长,异地复制使用了异步复制机制。 如果主数据库发生故障,异步复制会导致数据丢失不可避免。 为了防止这些关键事务数据丢失,应用程序开发人员可以在提交事务后立即调用 sp_wait_for_database_copy_sync 存储过程。 调用 sp_wait_for_database_copy_sync 会阻止调用线程,直到最后提交的事务已传输并强制执行到辅助数据库的事务日志中。 但是,它不会等待传输的事务在辅助数据库上进行重播(恢复)。 sp_wait_for_database_copy_sync 范围限定为特定异地复制链接。 对主数据库具有连接权限的任何用户都可以调用此过程。

备注

sp_wait_for_database_copy_sync 防止特定事务异地故障转移后数据丢失,但不保证完全同步进行读取访问。 sp_wait_for_database_copy_sync 过程调用导致的延迟可能很明显,具体取决于调用时主数据库上尚未传输的事务日志大小。

更改次要区域

假设实例 A 是主实例,实例 B 是现有的辅助实例,实例 C 是第三个区域中的新辅助实例。 若要进行转换,请执行以下步骤:

  1. 在同一个 DNS 区域中创建大小与 A 相同的实例 C。
  2. 删除实例 A 与 B 之间的故障转移组。此时,尝试登录开始失败,因为故障转移组侦听器的 SQL 别名已删除,因此网关无法识别故障转移组名称。 辅助数据库从主实例断开连接,并成为读写数据库。
  3. 在实例 A 与 C 之间创建同名的故障转移组。按照配置故障转移组指南中的说明操作。 这是一个与数据大小相关的操作,实例 A 中的所有数据库都已设定种子并同步后,则此操作完成。
  4. 如果不需要实例 B,请将其删除,以免产生不必要的费用。

备注

完成步骤 2 到 3 后,如果实例 A 发生灾难性故障,其中的数据库将仍不受保护。

更改主要区域

假设实例 A 是主实例,实例 B 是现有的辅助实例,实例 C 是第三个区域中的新主实例。 若要进行转换,请执行以下步骤:

  1. 在同一个 DNS 区域中创建大小与 B 相同的实例 C。
  2. 从实例 B 启动手动故障转移,使其成为新的主实例。 实例 A 自动成为新的辅助实例。
  3. 删除实例 A 和 B 之间的故障转移组。此时,使用故障转移组终结点的登录尝试会失败。 A 上的辅助数据库与主数据库断开连接,并成为读写数据库。
  4. 在实例 B 和 C 之间以相同名称创建故障转移组。这是一个与数据大小相关的操作,当实例 B 中的所有数据库都已设定种子并与实例 C 同步后,此操作完成。此时,登录尝试将不再失败。
  5. 手动故障转移以将 C 实例切换到主角色。 实例 B 自动成为新的辅助实例。
  6. 如果不需要实例 A,请将其删除,以免产生不必要的费用。

注意

完成步骤 3 到 4 后,如果实例 A 发生灾难性故障,其中的数据库将仍不受保护。

重要

删除故障转移组时,也会删除侦听器终结点的 DNS 记录。 此时,其他人有可能创建同名的故障转移组。 由于故障转移组名称必须全局唯一,因此这将阻止你再次使用相同名称。 为最大程度地降低这种风险,请勿使用通用的故障转移组名称。

启用依赖于系统数据库中的对象的方案

系统数据库不会复制到故障转移组中的辅助实例。 若要启用依赖于系统数据库中的对象的方案,请确保在辅助实例上创建相同的对象并让辅助实例与主实例保持同步。

例如,如果你计划在辅助实例上使用相同的登录名,请确保使用相同的 SID 创建它们。

-- Code to create login on the secondary instance
CREATE LOGIN foo WITH PASSWORD = '<enterStrongPasswordHere>', SID = <login_sid>;

有关详细信息,请参阅复制登录名和代理作业

同步实例属性和保留策略实例

故障转移组中的实例保持独立的 Azure 资源,对主实例配置所做的任何更改都不会自动复制到辅助实例。 确保同时在主要辅助实例上执行所有相关更改。 例如,如果在主实例上更改备份存储冗余或长期备份保留策略,请确保在辅助实例上也进行更改。

缩放实例

可以在同一服务层级内将主实例和辅助实例纵向扩展或缩减到不同的计算大小,或纵向扩展或缩减到不同的服务层级。 在同一服务层级内纵向扩展时,请先纵向扩展异地辅助实例,然后再纵向扩展主实例。 在同一服务层级内纵向缩减时,按相反顺序操作:先纵向缩减主数据库,再纵向缩减辅助数据库。 将实例扩展到其他服务层级时,请遵循相同的顺序。

建议按此顺序进行,以避免出现以下问题:较低 SKU 的异地辅助实例过载,并且必须在升级或降级过程中重新设定种子。

权限

通过 Azure 基于角色的访问控制 (Azure RBAC) 管理故障转移组的权限。

SQL 托管实例参与者角色的范围限定为主要托管实例和辅助托管实例的资源组,足以对故障转移组执行所有管理操作。

下表提供了最低所需权限的精细视图,以及它们各自针对故障转移组的管理操作所需的最小范围级别

管理操作 权限 范围
创建/更新故障转移组 Microsoft.Sql/locations/instanceFailoverGroups/write 主托管实例和辅助托管实例的资源组
创建/更新故障转移组 Microsoft.Sql/managedInstances/write 主托管实例和辅助托管实例
对故障转移组进行故障转移 Microsoft.Sql/locations/instanceFailoverGroups/failover/action 主托管实例和辅助托管实例的资源组
对故障转移组强制执行故障转移 Microsoft.Sql/locations/instanceFailoverGroups/forceFailoverAllowDataLoss/action 主托管实例和辅助托管实例的资源组
删除故障转移组 Microsoft.Sql/locations/instanceFailoverGroups/delete 主托管实例和辅助托管实例的资源组

限制

创建新的故障转移组时,应注意以下限制:

  • 不能在同一 Azure 区域中的两个实例之间创建故障转移组。
  • 一个实例在任何时候只能参与一个故障转移组。
  • 不能在属于不同 Azure 租户的两个实例之间创建故障转移组。
  • 仅 Azure PowerShell 或 REST API(而不是 Azure 门户或 Azure CLI)支持在不同资源组或订阅中的两个实例之间创建故障转移组。 创建故障转移组后,该组在 Azure 门户中可见,Azure 门户或 Azure CLI 支持所有操作。 故障转移必须从辅助实例启动。
  • 如果所有数据库的初始种子设定未在 7 天内完成,则创建故障转移组会失败,并且所有成功复制的数据库都会从辅助实例中删除。
  • 目前不支持使用配置了托管实例链接的实例创建故障转移组。
  • 在执行直接转换步骤之前,使用日志重播服务 (LRS) 迁移到 Azure SQL 托管实例的数据库无法添加到故障转移组。

使用故障转移组时,应注意下列限制:

  • 无法重命名故障转移组。 需要删除该组,并使用不同的名称重新创建它。
  • 故障转移组正好包含两个托管实例。 不支持将其他实例添加到故障转移组。
  • 故障转移组中的数据库不支持数据库重命名。 需要临时删除故障转移组,才能重命名数据库。
  • 系统数据库不会复制到故障转移组中的辅助实例。 因此,依赖于系统数据库中对象(例如服务器登录和代理作业)的方案要求在辅助实例上手动创建对象,并在对主实例进行更改后手动保持同步。 唯一的例外是 SQL 托管实例的服务主密钥 (SMK),它在创建故障转移组期间自动复制到辅助实例。 但是,在主实例上进行的任何后续 SMK 更改都不会复制到辅助实例。 若要了解详细信息,请参阅如何启用依赖于系统数据库中的对象的方案

以编程方式管理故障转移组

也可以使用 Azure PowerShell、Azure CLI 和 REST API 以编程方式管理故障转移组。 下表描述了可用的命令集。 故障转移组包含一组用于管理的 Azure Resource Manager API,其中包括 Azure SQL 数据库 REST APIAzure PowerShell cmdlet。 这些 API 需要使用资源组,并支持 Azure 基于角色的访问控制 (Azure RBAC)。 有关如何实现访问角色的详细信息,请参阅 Azure 基于角色的访问控制 (Azure RBAC)

Cmdlet 说明
New-AzSqlDatabaseInstanceFailoverGroup 此命令会创建故障转移组,并将其同时注册到主实例和辅助实例
Set-AzSqlDatabaseInstanceFailoverGroup 修改故障转移组的配置
Get-AzSqlDatabaseInstanceFailoverGroup 检索故障转移组的配置
Switch-AzSqlDatabaseInstanceFailoverGroup 触发故障转移组到辅助实例的故障转移
Remove-AzSqlDatabaseInstanceFailoverGroup 删除故障转移组