陷阱 SQL 故障转移异常
Posted
技术标签:
【中文标题】陷阱 SQL 故障转移异常【英文标题】:Trap SQL Failover Exceptions 【发布时间】:2016-10-13 19:08:26 【问题描述】:我正在使用 NuGet 包 Polly 来实现捕获故障转移 SQL 异常的重试逻辑。我在 Azure 中设置了 SQL Server Always On High Availability。
我想捕获发生故障转移时发生的特定 SQL 异常,而不是捕获所有 SQL 异常(这将是不正确的)。
通过 SSMS,我显示仪表板,然后我能够人为地触发故障转移来测试我的代码。最初,我让所有异常都冒泡(所以没有陷阱)。然后我会排队进行故障转移并查看我的日志以查看引发了什么 SQL 异常。随后,我能够捕获由于故障转移而发生的所有 SQL 异常。
我的问题是,这是一份完整的清单吗?在 SQL Server 故障转移上实现重试逻辑的其他人是否会捕获任何其他 SQL 异常?
我已经用逻辑尝试了将近 100 次故障转移,但没有出现任何问题。这当然并不意味着我已经捕获了所有的故障转移 SQL 异常。
重试逻辑有 Policy.Handle(se => IsFailoverSqlException(se))。当故障转移排队时,根据我在代码中的位置,我会看到下面捕获的三个 SQL 异常。
private static bool IsFailoverSqlException(SqlException se)
return (
/*
A network-related or instance-specific error occurred while establishing a connection to SQL Server.
The server was not found or was not accessible.
Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
*/
(se.Class == 20 && se.State == 0 && se.Number == 53) ||
/*
Failed while logging Fatal to MT Database: Unable to access availability database 'MedicusMT' because the database replica is not in the PRIMARY or SECONDARY role.
Connections to an availability database is permitted only when the database replica is in the PRIMARY or SECONDARY role.
Try the operation again later.
*/
(se.Class == 14 && se.State == 1 && se.Number == 983) ||
// A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
(se.Class == 20 && se.State == 0 && se.Number == -1)
);
【问题讨论】:
【参考方案1】:使用 NET 4.5 及更高版本时行为发生了变化。 SqlException Number 可能是 Win32 API number 我发现错误号取决于 SQL Server 连接中使用的网络库。
命名管道库的值很好。 与 Azure 库通信时,需要处理一个暂时性错误。不要在 Azure 案例上重复一个好的 analysis。 Windows 主机上的 TCP 网络库会有一个 Win32 内部异常 1225。错误号:1225,状态:0,类:20
我不喜欢 SqlException Net45 更改的是 SqlException.Number 是 mixed domain 的值。它可以是来自底层网络库的SQL Server Error 或Azure Transient Error 或Win32 API。
如果您在 Unit of work 级别应用策略,请考虑重试死锁受害者 SQL Server 错误 1205
如果您进行实时升级,您可能会发现 DBA 会终止 PSID 错误号:596,State:1,Class:21
【讨论】:
【参考方案2】:为什么不简化逻辑,只检查连接状态,如果需要,创建一个新连接: 连接!= 空 || conn.State != ConnectionState.Open
类似于这篇文章:https://technet.microsoft.com/en-us/library/cc917713.aspx#ECAA
【讨论】:
连接状态不会告诉您有关“无法访问...”的案例 2 的任何信息 - 只有当您对不再是主要数据库的特定数据库执行操作时才会发生此错误sql 实例。以上是关于陷阱 SQL 故障转移异常的主要内容,如果未能解决你的问题,请参考以下文章
sql server 镜像 主节点异常 镜像节点会提供服务吗