2

我们有几个镜像 SQL Server 数据库。

我的第一个问题 - 关键问题 - 是在数据库故障转移时获得通知。我不需要知道,因为,erm,它是镜像的,所以它(几乎)都可以自动运行,但建议它会很有用,当我认为我不应该这样做时,我目前正在进行故障转移,所以它想要知道它们何时发生(无需过多挖掘),看看我是否可以确定原因。

我有正在运行的服务,我可以很容易地使用它来监控它 - 所以另一个问题是“我如何以编程方式确定哪个是主体,哪个是镜像” - 最好以更智能的方式而不是仅仅尝试连接每个转(这将主要工作,但......)。

谢谢,墨菲

附录:

答案之一询问为什么我不需要知道它何时进行故障转移 - 答案是我们正在使用 ADO.NET 进行开发并且具有自动故障转移支持,您所要做的就是添加Failover Partner=MIRRORSERVER(其中 MIRRORSERVER 是名称您的镜像服务器实例)到您的连接字符串,您的代码将透明地故障转移 - 您可能会收到一些错误,具体取决于哪些连接处于活动状态,但在我们的例子中很少。

4

3 回答 3

2

对,

这两个答案和一个小小的想法让我想到了一个接近答案的东西。

首先澄清一点:

该应用程序是用 C# (2.0+) 编写的,并使用 ADO.NET 与 SQL Server 2005 通信。镜像设置是两台 W2k3 服务器托管主体和镜像,加上第三台服务器托管 express 实例作为监视器。这样做的好处是故障转移对使用数据库的应用程序几乎是透明的,它会为某些连接抛出错误,但基本上一切都会很好地进行。是的,我们得到了奇怪的误报,但重点是让系统以最少的麻烦继续工作,而镜像确实很好地提供了这一点。

此外,问题不在于严重的服务器故障 - 这通常更明显,但由于其他原因(参见上面的误报)进行故障转移,因为我们确实有一些事情由于各种原因无法进行故障转移无论如何,我们可以看看我们是否可以确定我们得到误报的情况。

因此,鉴于上述情况,仅检查框的状态是不够的,并且通过事件日志追踪可能过于复杂 - 事实证明,答案相当简单:sp_helpserver

sp_helpserver 返回的第一列是服务器名称。如果您定期运行请求,保存以前的服务器名称并每次进行比较,您将能够识别何时发生更改,然后采取适当的措施。

以下是演示主体的控制台应用程序 - 虽然它需要一些工作(例如,连接应该是非池化的并且每次都是新的)但现在已经足够了(所以我会接受这个作为“答案” ). 参数是Principal, Mirror, Database

using System;
using System.Data.SqlClient;

namespace FailoverMonitorConcept
{
    class Program
    {
        static void Main(string[] args)
        {
            string server = args[0];
            string failover = args[1];
            string database = args[2];

            string connStr = string.Format("Integrated Security=SSPI;Persist Security Info=True;Data Source={0};Failover Partner={1};Packet Size=4096;Initial Catalog={2}", server, failover, database);
            string sql = "EXEC sp_helpserver";

            SqlConnection dc = new SqlConnection(connStr);
            SqlCommand cmd = new SqlCommand(sql, dc);
            Console.WriteLine("Connection string: " + connStr);
            Console.WriteLine("Press any key to test, press q to quit");

            string priorServerName = "";
            char key = ' ';

            while(key.ToString().ToLower() != "q")
            {
                dc.Open();
                try
                {
                    string serverName = cmd.ExecuteScalar() as string;
                    Console.WriteLine(DateTime.Now.ToLongTimeString() + " - Server name: " + serverName);
                    if (priorServerName == "")
                    {
                        priorServerName = serverName;
                    }
                    else if (priorServerName != serverName)
                    {
                        Console.WriteLine("***** SERVER CHANGED *****");
                        Console.WriteLine("New server: " + serverName);
                        priorServerName = serverName;
                    }
                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    Console.WriteLine("Error: " + ex.ToString());
                }
                finally
                {
                    dc.Close();
                }
                key = Console.ReadKey(true).KeyChar;

            }

            Console.WriteLine("Finis!");

        }
    }
}

如果没有 a) 提出问题,然后 b) 得到让我真正思考的回答,我就不会到达这里

墨菲

于 2008-08-31T21:18:40.210 回答
1

如果故障转移逻辑在您的应用程序中,您可以编写一个状态屏幕,在第一次连接尝试失败时通过写入 var 来显示您连接的盒子。

我认为你最好的选择是一个 ping 守护进程/cron 作业,它定期检查每个盒子的状态,如果没有回复,就会发送一封电子邮件。

于 2008-08-27T00:57:04.997 回答
1

使用 Host Monitor http://www.ks-soft.net/hostmon.eng/之类的东西来监控事件日志中与故障转移事件相关的消息,这可以通过电子邮件/短信向您发送警报。

我很好奇您如何不需要知道故障转移发生了,因为您不必更新应用程序中的数据源以指向您故障转移到的新服务器吗?镜像发生在不同的主机(主主机和镜像主机)上,与集群不同,集群具有多个节点,从外部看似乎是单个设备。

另外,您是否使用见证服务器来自动从主服务器故障转移到镜像服务器?这是我所知道的让它自动发生的唯一方法,并且根据我的经验,你会得到很多误报,其中网络打嗝可以欺骗镜子并目击者认为主节点已关闭,而实际上并非如此。

于 2008-08-27T01:13:09.310 回答