0

我有主体数据库(server_A),镜像数据库(server_B)和见证数据库(server_C)。数据库设置为自动故障转移,即server_A关闭或故障转移时,server_B承担新主体数据库的角色。就我所知,数据库法定人数设置正确。当主体出现故障时,自动故障转移到镜像数据库的多个连接

我已经用C++编写了一个应用程序来连接数据库并获取一个值来确保真正的连接。应用程序检测GetValue调用发生故障的时间,并在发生错误时尝试重新连接。

问题是这样的: 当我有数据库连接(两个线程连接,一旦连接,它将得到一个循环的值),当发生故障转移时(停止服务器A上的SQL服务器,所以服务器B将检测到连接失败并破坏我的连接并尝试使用相同连接字符串重新连接:

“Driver = {SQL Native Client}; Server = tcp:Server_A; Failover_Partner = tcp:Server_B ;数据库= SomeDatabase; UID = SomeUser是否; PWD = SomePassword;”

** NOTE ** 我已验证通过监视数据库发生了故障转移。即使与数据库的连接已被正确处置,但在重新启动应用程序之前,我无法重新连接到数据库,或者如果我使server_A重新联机(现在充当镜像数据库),然后故障转移server_B(关闭sql server)使服务器A再次成为主体数据库,应用程序可以重新连接而不必完全关闭。

尽管我可以操纵连接字符串,使server_B成为新的主体,server_A成为新的Failover_Partner,但这不是一个理想的解决方案,因为将会使用更多的连接。

请记住,这只会发生与数据库的多个连接。如果我只运行一个连接的应用程序,一切都很好,我可以在发生故障转移时重新连接。

编辑:如果我在一开始与多个线程连接,一切都很好。当我关闭SQL Server并因此发生故障转移时,我只能在重新连接时删除所有对象并重新实例化新对象。另外,我正在使用SQL Native Client 11.0(ODBC)。思考?

+0

这可能是因为您使用的驱动程序不是线程安全的,并且在线程环境中使用非线程安全库时,结果无法预见。 – 2014-08-27 19:13:46

+0

如果是这种情况,应用程序是否会在不通过镜像过程的情况下从一开始就失败?如果线程安全,我会怀疑无论故障转移多次连接都会发生故障。 – Zonxwedop 2014-08-27 19:27:25

+0

它可能,它可能不。当非线程安全的代码暴露给线程环境时,很难预测会发生什么。 – 2014-08-27 19:47:28

回答

0

好的我找到了答案。

我不得不修改主机文件,因为我的应用程序没有与数据库驻留在同一个域中。因此,当尝试进行故障转移时,我无法使用实例名称访问数据库(这是故障转移伙伴的缓存方式)。我更改了hosts文件以将实例名称解析为机器的IP地址,现在它全部正常工作。

0

您描述的很多内容与KB 2605597“.NET Framework数据提供者为SQLClient创建镜像数据库连接时发生超时错误”中描述的问题一致。

KB描述了连接超时设置为15秒时的问题,当连接超时设置为0时(这不是其他原因的好主意,以防万一) 。

此修补程序应用于应用程序服务器。如果你想排除这个可能的原因,你可以测试提高超时时间(就像它在帖子的变通办法部分所说的那样),以确保它不是问题。

后来认为:我注意到的另一件不同寻常的事情是,您在连接字符串和故障转移伙伴名称中指定了TCP协议。从文档中我不清楚它在故障转移伙伴名称中是否受支持。您可能想尝试删除它并指定网络属性。 (Recommended here。)

我明白你相信这个问题不是由于你测试过的单/多连接问题造成的。

但是,我认为最好简化连接字符串,以便尽可能与已发布的示例保持一致,并确保它不是人们通常首先遇到的问题。 (重试问题发生在存在延迟的情况下,这可能会使其有点零星。)

+0

提供的连接字符串已经以多种方式进行了修改,希望能够解决问题。我曾尝试过使用网络参数,但仍收到相同的结果。我不确定故障转移伙伴上的tcp:标记,但我无法找到任何相关信息,但它与其余部分完全相同。 顺便说一句,tcp:标记是因为命名管道被禁用,我不需要处理命名管道超时,当它没有启用的第一个地方。 最后,我尝试设置一个较长的超时时间,并在连接和故障转移伙伴上设置一个短暂的超时,但没有运气。 – Zonxwedop 2014-08-28 13:04:15