代码之家  ›  专栏  ›  技术社区  ›  Murph

镜像SQL Server数据库故障转移时如何获取通知

  •  2
  • Murph  · 技术社区  · 16 年前

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

    我的第一个问题-关键问题-是在数据库故障转移时得到通知。我不 需要 要知道,因为,呃,它是镜像的,所以它(几乎)都是自动工作的,但是它会有用的被建议,我目前正在得到故障转移时,我认为我不应该这样,所以它想知道什么时候发生(没有太多的挖掘),看看我是否能确定原因。

    我有运行的服务,我可以很容易地使用它们来监视这一点,所以另一个问题是“我如何以编程方式确定哪一个是主体,哪一个是镜像”—最好是以一种更智能的方式,而不是试图依次连接每一个主体(这一点基本上是可行的,但……)。

    谢谢,默夫

    附录:

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

    3 回复  |  直到 16 年前
        1
  •  2
  •   Murph    16 年前

    正确的,

    这两个答案和一个小小的思考让我有了接近答案的东西。

    首先要澄清一点:

    该应用程序是用C(2.0+)编写的,并使用ADO.NET与SQL Server 2005进行对话。 镜像设置是两个承载主体的W2K3服务器,以及一个作为监视器承载Express实例的第三个服务器。这方面的好处是故障转移对使用数据库的应用程序几乎是透明的,它会对某些连接抛出一个错误,但从根本上说,一切都将顺利进行。是的,我们得到了奇怪的假阳性,但关键是让系统以最少的干扰和镜像继续工作。 把这个交得很好。

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

    因此,考虑到上述情况,仅仅检查这些框的状态还不够,而查看事件日志可能过于复杂-答案是,事实证明,相当简单:sp_helpserver

    sp_helpserver返回的第一列是服务器名。如果定期运行请求,则保存 以前的 服务器名和每次进行比较时,您将能够确定何时发生了更改,然后采取适当的操作。

    下面是一个控制台应用程序,它演示了主体——尽管它需要一些工作(例如,每次连接都应该是非池的和新的),但现在已经足够了(所以我会接受这一点作为“答案”)。参数包括主体、镜像、数据库

    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)得到回答,我就不会到这里来了,这让我 认为

    默普

        2
  •  1
  •   Nick    16 年前

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

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

        3
  •  1
  •   Dane    16 年前

    使用主机监视器之类的工具 http://www.ks-soft.net/hostmon.eng/ 要监视与故障转移事件相关的消息的事件日志,可以通过电子邮件/SMS向您发送警报。

    不过,我很好奇,您怎么可能不需要知道故障转移发生了,因为您不需要更新应用程序中的数据源来指向您故障转移到的新服务器?镜像发生在不同的主机(主主机和镜像)上,不同于具有多个节点的群集,这些节点从外部看来是单个设备。

    另外,您是否使用见证服务器来自动从主服务器故障转移到镜像?这是我所知道的唯一能让它自动发生的方法,在我的经验中,你会得到很多误报,在这些误报中,网络打嗝会欺骗镜子和证人,让他们认为,当事实上不是的时候,初选就要失败了。