本文讨论 Microsoft SqlClient Data Provider 对 SQL Server 高可用性和灾难恢复的支持,包括 Always On 可用性组。 有关详细信息,请参阅 Always On 可用性组。
你现在可以在连接属性中指定高可用性和灾难恢复(HADR)可用性组(AG)或故障转移群集实例(FCI)的可用性组侦听器。 如果 SqlClient 应用程序连接到发生故障切换的 Always On 数据库,原始连接会中断,应用程序必须在故障切换后重新开启连接才能继续工作。
如果你没有连接到可用性组监听器或FCI,且一个主机名关联多个IP地址,SqlClient会逐一遍历与该DNS条目关联的所有IP地址。 如果DNS服务器返回的第一个IP地址没有绑定在任何网络接口卡(NIC)上,这个过程可能会非常耗时。 当你连接到AG监听器或FCI时,SqlClient会尝试并行建立与所有IP地址的连接。 如果连接尝试成功,驱动程序将丢弃所有挂起的连接尝试。
备注
增大连接超时值和实现连接重试逻辑将增加应用程序连接到可用性组的概率。 此外,由于故障转移可能导致连接失败,因此请实现连接重试逻辑,在连接失败后持续重试,直到重新建立连接。
Microsoft SqlClient Data Provider for SQL Server 支持以下连接属性:
ApplicationIntentMultiSubnetFailover
可以通过编程方式修改这些连接字符串关键字:
使用 MultiSubnetFailover 进行连接
连接Microsoft SQL系列TCP端点时,务必指定MultiSubnetFailover=True。 该设置适用于可用性组监听器、故障转移集群实例以及多IP端点,如Azure SQL 数据库、Azure SQL 托管实例和Microsoft Fabric中的SQL数据库。
当连接字符串中的服务器名称解析为多个 IP 地址时,MultiSubnetFailover=True 会使 SqlClient 同时向所有这些地址打开连接,并使用最先响应的那个地址。 如果没有它,SqlClient 会逐个尝试这些地址。 对未响应地址的连接会一直阻塞,直到操作系统的 TCP 连接超时到期;这可能会在 SqlClient 尝试到会响应的地址之前耗尽 Connect Timeout。 故障切换后,SqlClient 首先尝试的地址可能已不再服务于数据库,因此本应成功访问另一个地址的连接会因超时而失败。
MultiSubnetFailover=True 改变客户端找到为数据库服务的副本的速度。 这不会改变服务器故障转移所需的时间。 开启该设置后,SqlClient 还会比操作系统默认的 TCP 重传间隔更快地重试 TCP 连接尝试,从而加快单子网和多子网可用性组以及故障转移集群实例的重新连接速度。
MultiSubnetFailover=True 可安全用于单个 IP 目标。 当 DNS 解析到单一地址时,SqlClient 会尝试一次连接,因此当不需要设置时,设置费用不高。
有关 SqlClient 中的连接字符串关键字的详细信息,请参阅 ConnectionString。 有关 .NET Framework 中相关的透明网络 IP 解析 (TNIR) 设置的指导,以及排查由具有多个 IP 的 DNS 名称导致的连接缓慢问题,请参阅 禁用透明网络 IP 解析 和 预登录握手超时导致的连接长时间延迟。
配置 MultiSubnetFailover时请遵循以下指导原则:
设置
MultiSubnetFailover=True。若要连接到某一可用性组,请在您的连接字符串中将该可用性组的可用性组侦听器指定为服务器。
连接到命名实例时不能使用
MultiSubnetFailover。你不能通过TCP以外的协议使用
MultiSubnetFailover。连接到配置超过64个IP地址的SQL Server实例会导致连接失败。
你不能将
MultiSubnetFailover与数据库镜像一起使用。 更多信息请参见 从数据库镜像升级为使用多子网集群。 所有支持的 SQL Server 版本均已弃用数据库镜像。 请使用 Always On 可用性组来替代其他解决方案。基于以下身份验证类型,使用
MultiSubnetFailover连接属性的应用程序的行为将不会受到影响:SQL Server 身份验证、Kerberos 身份验证或 Windows 身份验证。增大
Connect Timeout的值,为故障转移时间留出余量,并减少应用程序连接重试次数。不支持分布式事务。
如果只读路由不起作用,则连接到次要副本位置在以下情况下将失败:
如果辅助副本所在位置未配置为接受连接。
如果应用程序使用
ApplicationIntent=ReadWrite(在下面论述)且将辅助副本位置配置为只读访问。
只读辅助副本不支持 SqlDependency。
如果将主副本配置为拒绝只读工作负荷且连接字符串包含 ApplicationIntent=ReadOnly,连接将失败。
从数据库镜像升级到使用多子网群集
如果连接字符串中已存在 ArgumentException 和 MultiSubnetFailover 连接关键字,或者如果使用了 Failover Partner 和除 TCP 以外的其他协议,将出现连接错误 (MultiSubnetFailover=True)。 如果使用 MultiSubnetFailover 且 SQL Server 返回一个故障转移伙伴响应指示它是数据库镜像对的一部分,也将出现错误 (SqlException)。
如果你将当前使用数据库镜像的 SqlClient 应用程序升级到多子网方案,则应删除 Failover Partner 连接属性并使用设置为 MultiSubnetFailover 的 True 替换它,并且还应使用可用性组侦听程序替换连接字符串中的服务器名称。 如果连接字符串使用 Failover Partner 和 MultiSubnetFailover=True,则驱动程序将生成错误。 但是,如果连接字符串使用 Failover Partner 和 MultiSubnetFailover=False(或 ApplicationIntent=ReadWrite),则应用程序将使用数据库镜像。
如果您在可用性组的主副本上使用数据库镜像,并且在连接到主副本而不是可用性组侦听器的连接字符串中设置了 MultiSubnetFailover=True,驱动程序会返回错误。
指定应用程序意向
当你设置 ApplicationIntent=ReadOnly时,客户端在连接到启用 Always On 的数据库时请求读取工作负载。 服务器会在连接时以及执行 USE 数据库语句期间强制实施该意向,但仅适用于启用了 Always On 的数据库。
ApplicationIntent 关键字不适用于早期的只读数据库。
数据库可允许或禁止目标 Always On 数据库上的读取工作负载。 (这是通过 PRIMARY_ROLE 和 SECONDARY_ROLETransact-SQL 语句的 ALLOW_CONNECTIONS 子句实现的。)
ApplicationIntent 关键字用于启用只读路由。
只读路由
只读路由是一项可确保数据库只读副本的可用性的功能。 启用只读路由:
您必须连接到某一 AlwaysOn 可用性组侦听器。
ApplicationIntent连接字符串关键字必须设置为ReadOnly。数据库管理员必须配置该可用性组以便启用只读路由。
使用只读路由的多个连接可能不会全部连接到相同的只读副本。 对数据库同步进行更改或对服务器的路由配置进行更改可能导致客户端连接到不同的只读副本。 若要确保所有只读请求都连接到相同的只读副本,请勿将可用性组侦听器传递到 Data Source 连接字符串关键字。 而是指定只读实例的名称。
只读路由所用的时间可能会长于连接到主副本的时间,因为只读路由首先连接到主副本,然后查找可用的最佳可读取辅助副本。 因此,您应延长登录超时时间。