配置分布式 Always On 可用性组

适用于:SQL Server

要创建分布式可用性组,必须创建两个分别具有各自侦听器的可用性组。 然后将这些可用性组合并到分布式可用性组中。 以下步骤提供了在 Transact-SQL 中实现此操作的基本示例。 此示例不涵盖创建可用性组和侦听器的所有详细信息,相反,它着重于突出显示关键要求。

有关分布式可用性组的技术概述,请参阅分布式可用性组

先决条件

若要配置分布式可用性组,必须满足以下各项:

注意

如果您在 Azure 虚拟机上的 SQL Server 中使用分布式网络名称 (DNN) 配置了可用性组的监听器,则不支持在此可用性组之上配置分布式可用性组。 若要了解详细信息,请参阅 Azure VM 上的 SQL Server 功能与 AG 和 DNN 侦听器的互操作性

权限

在服务器上需要 CREATE AVAILABILITY GROUP 权限才能创建可用性组,以及 sysadmin 权限才能对分布式可用性组进行故障转移。

设置数据库镜像终结点以侦听所有 IP 地址

确保数据库镜像终结点可以在分布式可用性组中的不同可用性组之间进行通信。 如果将一个可用性组设置为数据库镜像终结点上的特定网络,则分布式可用性组无法正常工作。 在托管分布式可用性组中副本的每个服务器上,将数据库镜像终结点设置为侦听所有 IP 地址(LISTENER_IP = ALL)。

创建数据库镜像终结点以侦听所有 IP 地址

例如,以下脚本在 TCP 端口 5022 上创建一个新的数据库镜像终结点,用于侦听所有 IP 地址。

CREATE ENDPOINT [aodns-hadr]
    STATE = STARTED
    AS TCP
(
            LISTENER_PORT = 5022,
            LISTENER_IP = ALL
)
    FOR DATABASE_MIRRORING
(
            ROLE = ALL,
            AUTHENTICATION = WINDOWS NEGOTIATE,
            ENCRYPTION = REQUIRED ALGORITHM AES
);
GO

更改现有数据库镜像终结点以侦听所有 IP 地址

例如,以下脚本更改现有数据库镜像终结点以侦听所有 IP 地址。

ALTER ENDPOINT [aodns-hadr]
    AS TCP
(
            LISTENER_IP = ALL
);
GO

创建第一个可用性组

在第一个群集上创建主要可用性组

在第一个 Windows Server 故障转移群集 (WSFC) 上创建可用性组。 在此示例中,数据库 db1 的可用性组名为 ag1。 在分布式可用性组中,主可用性组的主副本称为 全局主副本。 Server1 是此示例中的全局主要副本。

CREATE AVAILABILITY GROUP [ag1]
FOR DATABASE db1
REPLICA ON N'server1' WITH (ENDPOINT_URL = N'TCP://server1.contoso.com:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
    BACKUP_PRIORITY = 50,
    SECONDARY_ROLE(ALLOW_CONNECTIONS = NO),
    SEEDING_MODE = AUTOMATIC),
N'server2' WITH (ENDPOINT_URL = N'TCP://server2.contoso.com:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
    BACKUP_PRIORITY = 50,
    SECONDARY_ROLE(ALLOW_CONNECTIONS = NO),
    SEEDING_MODE = AUTOMATIC);
GO

注意

上述示例使用自动种子设定,其中 SEEDING_MODE 设置为 AUTOMATIC,用于副本和分布式可用性组。 此配置将设置次要副本和次要可用性组自动填充,而无需手动备份和还原主要数据库。

将次要副本加入主可用性组

任何辅助副本都必须使用 ALTER AVAILABILITY GROUP 并配合 JOIN 选项加入可用性组。 由于此示例中使用了自动初始化,您还必须调用 ALTER AVAILABILITY GROUP 并配合 GRANT CREATE ANY DATABASE 选项。 此设置允许可用性组创建数据库,并开始从主副本自动为其设定种子。

在此示例中,在次要副本 server2上运行以下命令,以联接 ag1 可用性组。 允许可用性组在次要副本上创建数据库。

ALTER AVAILABILITY GROUP [ag1] JOIN
ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE
GO

注意

当可用性组在辅助副本上创建数据库时,它将数据库所有者设置为运行 ALTER AVAILABILITY GROUP 语句的帐户以授予创建任意数据库的权限。 有关详细信息,请参阅授予可用性组在复制副本上创建数据库的权限

为主要可用性组创建侦听程序

接下来,在第一个 WSFC 上为主要可用性组添加侦听器。 在此示例中,侦听器名为 ag1-listener。 有关创建侦听程序的详细说明,请参阅创建或配置可用性组侦听程序 (SQL Server)

ALTER AVAILABILITY GROUP [ag1]
    ADD LISTENER 'ag1-listener' (
        WITH IP ( ('2001:db88:f0:f00f::cf3c'),('2001:4898:e0:f213::4ce2') ) ,
        PORT = 60173);
GO

创建第二个可用性组

然后,在第二个 WSFC 上创建次要可用性组 ag2。 在这种情况下,不会指定数据库,因为它会自动从主可用性组进行初始化。 辅助可用性组的主要副本在分布式可用性组中称为转发器。 在此示例中,server3 是转发器。

CREATE AVAILABILITY GROUP [ag2]
FOR
REPLICA ON N'server3' WITH (ENDPOINT_URL = N'TCP://server3.contoso.com:5022',
    FAILOVER_MODE = MANUAL,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
    BACKUP_PRIORITY = 50,
    SECONDARY_ROLE(ALLOW_CONNECTIONS = NO),
    SEEDING_MODE = AUTOMATIC),
N'server4' WITH (ENDPOINT_URL = N'TCP://server4.contoso.com:5022',
    FAILOVER_MODE = MANUAL,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
    BACKUP_PRIORITY = 50,
    SECONDARY_ROLE(ALLOW_CONNECTIONS = NO),
    SEEDING_MODE = AUTOMATIC);
GO

注意

  • 该次要可用性组必须使用相同的数据库镜像终结点(此示例中为端口 5022)。 否则,在本地故障转移后,副本会停止。
  • 基础可用性组应处于相同的可用性模式 - 两个可用性组都应处于同步提交模式,或者两者都应处于异步提交模式。 如果您不确定应使用哪种模式,请将两者均设置为异步提交模式,直到您准备好进行故障转移为止。

将次要副本联接到次要可用性组

在此示例中,在次要副本 server4上运行以下命令,以联接 ag2 可用性组。 允许可用性组在次要副本上创建数据库以支持自动种子设定。

ALTER AVAILABILITY GROUP [ag2] JOIN
ALTER AVAILABILITY GROUP [ag2] GRANT CREATE ANY DATABASE
GO

为次要可用性组创建侦听器

接下来,在第二个 WSFC 上添加次要可用性组的侦听器。 在此示例中,侦听器名为 ag2-listener。 有关创建侦听程序的详细说明,请参阅创建或配置可用性组侦听程序 (SQL Server)

ALTER AVAILABILITY GROUP [ag2]
    ADD LISTENER 'ag2-listener' ( WITH IP ( ('2001:db88:f0:f00f::cf3c'),('2001:4898:e0:f213::4ce2') ) , PORT = 60173);
GO

在第一个群集上创建分布式可用性组

在第一个 WSFC 上创建分布式可用性组(此示例中命名为 distributedAG )。 将 CREATE AVAILABILITY GROUP 命令与 DISTRIBUTED 选项一起使用。 AVAILABILITY GROUP ON 参数指定成员可用性组ag1ag2

若要使用自动种子设定来创建分布式可用性组,请使用以下 Transact-SQL 代码:

CREATE AVAILABILITY GROUP [distributedAG]
   WITH (DISTRIBUTED)
   AVAILABILITY GROUP ON
      'ag1' WITH
      (
         LISTENER_URL = 'tcp://ag1-listener.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      ),
      'ag2' WITH
      (
         LISTENER_URL = 'tcp://ag2-listener.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      );
GO

注意

LISTENER_URL 为每个可用性组指定侦听器以及该可用性组的数据库镜像端点。 在此示例中,为端口 5022 (不是用于创建侦听程序的端口 60173 )。 如果使用负载均衡器(例如在 Azure 中),为分布式可用性组端口添加负载均衡规则。 除 SQL Server 实例端口外,还要为侦听器端口添加规则。

取消转发器的自动种子设定

无论出于何种原因,如果必须在同步两个可用性组取消转发器的初始化,请通过将转发器的 SEEDING_MODE 参数设置为 MANUAL 并立即取消种子设定来更改分布式可用性组。 在全局主要可用性组中运行命令:

-- Cancel automatic seeding​.  Connect to global primary but specify DAG AG2
ALTER AVAILABILITY GROUP [distributedAG] ​
   MODIFY ​
   AVAILABILITY GROUP ON ​
   'ag2' WITH ​
   ( ​ SEEDING_MODE = MANUAL ​ ); ​

在第二个群集上加入分布式可用性组

然后,在第二个 WSFC 上加入分布式可用性组。

若要使用自动种子设定联接分布式可用性组,请使用以下 Transact-SQL 代码:

ALTER AVAILABILITY GROUP [distributedAG]
   JOIN
   AVAILABILITY GROUP ON
      'ag1' WITH
      (
         LISTENER_URL = 'tcp://ag1-listener.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      ),
      'ag2' WITH
      (
         LISTENER_URL = 'tcp://ag2-listener.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      );
GO

联接第二个可用性组的辅助数据库

如果第二个可用性组已设置为使用自动播种,则转到步骤 2。

  1. 如果第二个可用性组正在使用手动种子设定,则将对全局主副本的备份还原到第二个可用性组的次要副本:

    RESTORE DATABASE [db1] FROM DISK = '<full backup location>'
        WITH NORECOVERY;
    
    RESTORE LOG [db1] FROM DISK = '<log backup location>'
        WITH NORECOVERY;
    
  2. 当第二个可用性组的次要副本上的数据库处于正在还原状态后,必须手动将它联接到可用性组。

    ALTER DATABASE [db1]
        SET HADR AVAILABILITY GROUP = [ag2];
    

对分布式可用性组进行故障转移

由于 SQL Server 2022 (16.x) 引入了 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置的分布式可用性组支持,因此,SQL Server 2022 及更高版本与 SQL Server 2019 及更早版本的分布式可用性故障转移说明不同。

对于分布式可用性组,唯一受支持的故障转移类型是由用户手动发起的 FORCE_FAILOVER_ALLOW_DATA_LOSS。 因此,若要防止数据丢失,必须执行额外的步骤(详情见本部分所述),以确保在启动故障转移之前在两个副本之间同步数据。

在数据丢失可接受的紧急情况下,您可以通过运行以下命令在不确保数据同步的情况下启动故障转移:

ALTER AVAILABILITY GROUP distributedAG FORCE_FAILOVER_ALLOW_DATA_LOSS;

您可以使用相同的命令将故障转移到转发器,也可以回退到全局主节点。

在 SQL Server 2022 (16.x) 及更高版本上,可以为分布式可用性组配置 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置,该设置旨在保证分布式可用性组故障转移时不会丢失任何数据。 如果已配置此设置,请按照本节中的步骤对分布式可用性组执行故障转移。 如果您不想使用 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置,请按照 SQL Server 2019 及更早版本中关于分布式可用性组故障转移的说明进行操作。

注意

REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置为 1 意味着主副本会在次要副本上提交事务后,才在主副本上提交事务,这可能会降低性能。 尽管分布式可用性组不需要限制或停止全局主数据库上的事务才能在 SQL Server 2022 (16.x)中同步,但这样做可以提高用户事务和分布式可用性组同步的性能,并将 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置为 1。

确保数据不会丢失的步骤

若要确保没有数据丢失,必须先配置分布式可用性组,以支持无数据丢失,步骤如下:

  1. 为故障转移做准备时,请验证全局主节点转发器是否处于 SYNCHRONOUS_COMMIT 模式。 否则,将其设置为 SYNCHRONOUS_COMMITALTER AVAILABILITY GROUP
  2. 将分布式可用性组的同步提交模式设置为全局主节点转发器均采用同步提交。
  3. 请等待分布式可用性组同步完成。
  4. 在全局主节点上,使用 ALTER AVAILABILITY GROUP 将分布式可用性组 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 的设置设为 1。
  5. 验证本地可用性组和分布式可用性组中的所有副本状态正常,且分布式可用性组处于 SYNCHRONIZED 状态。
  6. 在全局主副本上,将分布式可用性组角色设置为 SECONDARY,从而使分布式可用性组不可用。
  7. 在转发器(即计划作为新主节点的节点)上,使用 ALTER AVAILABILITY GROUP 配合 FORCE_FAILOVER_ALLOW_DATA_LOSS 对分布式可用性组执行故障转移。
  8. 在新辅助副本(上一个全局主副本)上,将分布式可用性组 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置为 0。
  9. 可选:如果可用性组跨越导致延迟的地理距离,请将可用性模式更改为 ASYNCHRONOUS_COMMIT。 如有必要,此操作将撤销第一步所做的更改。

T-SQL 示例

本节通过一个详细示例,介绍了如何使用 Transact-SQL 将名为 distributedAG 的分布式可用性组进行故障转移。 示例环境共有 4 个节点用于分布式可用性组。 全局主节点 N1N2 托管可用性组 ag1,而转发器 N3N4 托管可用性组 ag2。 分布式可用性组 distributedAG 将更改从 ag1 推送到 ag2

  1. 执行查询以验证构成分布式可用性组的本地可用性组的主节点上的 SYNCHRONOUS_COMMIT 状态。 直接在 转发器和全局主服务器 上运行以下 T-SQL:

    SELECT DISTINCT ag.name AS [Availability Group],
                    ar.replica_server_name AS [Replica],
                    ar.availability_mode_desc AS [Availability Mode]
    FROM sys.availability_replicas AS ar
         INNER JOIN
         sys.availability_groups AS ag
         ON ar.group_id = ag.group_id
         INNER JOIN
         sys.dm_hadr_database_replica_states AS rs
         ON ar.group_id = rs.group_id
            AND ar.replica_id = rs.replica_id
    WHERE ag.name IN ('ag1', 'ag2')
          AND rs.is_primary_replica = 1
    ORDER BY [Availability Group];
    --if needed, to set a given replica to SYNCHRONOUS for node N1, default instance. If named, change from N1 to something like N1\SQL22
    
    ALTER AVAILABILITY GROUP [testag] MODIFY REPLICA ON N'N1\SQL22' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);
    
  2. 通过在全局主节点转发器上运行以下代码,将分布式可用性组设置为同步提交:

     -- sets the distributed availability group to synchronous commit
     ALTER AVAILABILITY GROUP [distributedAG] MODIFY AVAILABILITY GROUP ON
     'ag1' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT),
     'ag2' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);
    

    注意

    在分布式可用性组中,两个可用性组之间的同步状态取决于两个副本的可用性模式。 对于同步提交模式,当前的主要可用性组和当前的次要可用性组必须具有 SYNCHRONOUS_COMMIT 可用性模式。 因此,必须在全局主备份和转发服务器上运行此脚本。

  3. 等待分布式可用性组的状态更改为 SYNCHRONIZED。 在全局主节点上运行以下查询:

    -- Run this query on the Global Primary
    
    -- Check the results to see if synchronization_state_desc is SYNCHRONIZED
    SELECT ag.name,
           drs.database_id AS [Availability Group],
           db_name(drs.database_id) AS database_name,
           drs.synchronization_state_desc,
           drs.last_hardened_lsn
    FROM sys.dm_hadr_database_replica_states AS drs
         INNER JOIN
         sys.availability_groups AS ag
         ON drs.group_id = ag.group_id
    WHERE ag.name = 'distributedAG'
    ORDER BY [Availability Group];
    

    当可用性组 synchronization_state_desc 状态为 SYNCHRONIZED 时,继续执行后续操作。

  4. 对于 SQL Server 2022(16.x)及更高版本,在全球主服务器上,使用以下 T-SQL 将 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置为 1:

    ALTER AVAILABILITY GROUP distributedAG SET (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 1);
    
  5. 通过查询全局主节点转发器,验证所有副本上的可用性组状态是否正常:

    SELECT ag.name AS [AG Name],
           db_name(drs.database_id) AS database_name,
           ar.replica_server_name AS [replica],
           drs.synchronization_state_desc,
           drs.last_hardened_lsn
    FROM sys.dm_hadr_database_replica_states AS drs
         INNER JOIN
         sys.availability_groups AS ag
         ON drs.group_id = ag.group_id
         INNER JOIN
         sys.availability_replicas AS ar
         ON drs.replica_id = ar.replica_id
            AND drs.replica_id = ar.replica_id
    WHERE ag.name IN ('ag1', 'ag2', 'distributedAG');
    
  6. 在全局主节点上,将分布式可用性组角色设置为 SECONDARY此时,分布式可用性组不可用。 此步骤完成后,在执行其余步骤之前,您无法进行故障回退。

    ALTER AVAILABILITY GROUP distributedAG SET (ROLE = SECONDARY);
    
  7. 从全局主节点进行故障转移,在转发器上运行以下查询以转换可用性组并将分布式可用性组恢复在线:

    -- Run the following command on the forwarder, the SQL Server instance that hosts the primary replica of the secondary availability group.
    ALTER AVAILABILITY GROUP distributedAG FORCE_FAILOVER_ALLOW_DATA_LOSS;
    

    执行此步骤后:

    • 全局主节点从 N1 转换为 N3
    • 转发器从 N3 转换到 N1
    • 分布式可用性组可用。
  8. 在新转发器(之前的全局主节点 N1)上,将分布式可用性组的属性 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 设置为 0 以清除该属性:

    ALTER AVAILABILITY GROUP distributedAG SET (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0);
    
  9. 可选:如果可用性组跨越地理距离导致延迟,请考虑将全局主节点和转发器两者的可用性模式改回 ASYNCHRONOUS_COMMIT。 如果需要,这会还原在第一步中所做的更改。

     -- If applicable: sets the distributed availability group to asynchronous commit:
     ALTER AVAILABILITY GROUP distributedAG MODIFY AVAILABILITY GROUP ON
     'ag1' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT),
     'ag2' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT);
    

删除分布式可用性组

以下 Transact-SQL 语句删除了名为 distributedAG的分布式可用性组:

DROP AVAILABILITY GROUP distributedAG;

在故障转移群集实例上创建分布式可用性组

你可以使用故障转移群集实例 (FCI) 上的可用性组来创建分布式可用性组。 在此情况下,无需任何可用性组侦听器。 为 FCI 实例的主要副本使用虚拟网络名称 (VNN)。 以下示例演示了一个名为 SQLFCIDAG 的分布式可用性组。 其中一个可用性组为 SQLFCIAG。 SQLFCIAG 有 2 个 FCI 副本。 FCI 主要副本的 VNN 为 SQLFCIAG-1,FCI 次要副本的 VNN 为 SQLFCIAG-2。 该分布式可用性组还包含用于灾难恢复的 SQLAG-DR。

Always On 分布式可用性组的示意图。

以下 DDL 创建此分布式可用性组:

CREATE AVAILABILITY GROUP [SQLFCIDAG]
   WITH (DISTRIBUTED)
   AVAILABILITY GROUP ON
  'SQLFCIAG' WITH
      (
         LISTENER_URL = 'tcp://SQLFCIAG-1.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      ),
  'SQLAG-DR' WITH
      (
         LISTENER_URL = 'tcp://SQLAG-DR.contoso.com:5022',
         AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
         FAILOVER_MODE = MANUAL,
         SEEDING_MODE = AUTOMATIC
      );

侦听程序 URL 是主要 FCI 实例的 VNN。

在分布式可用性组中手动故障转移 FCI

若要手动故障转移 FCI 可用性组,请更新分布式可用性组,以反映侦听程序 URL 的更改。 例如,在分布式 AG 的全局 master 数据库和 SQLFCIDAG 的分布式 AG 的转发器上运行以下 DDL:

ALTER AVAILABILITY GROUP [SQLFCIDAG]
   MODIFY AVAILABILITY GROUP ON
 'SQLFCIAG' WITH
    (
        LISTENER_URL = 'tcp://SQLFCIAG-2.contoso.com:5022'
    )