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

时间:2008-08-26 15:22:38

标签: sql-server

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

我的第一个问题 - 关键问题 - 是在数据库故障转移时收到通知。我不需要知道,因为,呃,它的镜像,所以它(几乎)全部继续自动工作但是建议有用,我现在正在进行故障转移,当我不这样做我想我应该这样想知道它们何时发生(没有太多的挖掘),看看我能否确定原因。

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

谢谢,墨菲

附录:

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

3 个答案:

答案 0 :(得分:2)

对,

这两个答案和一点思绪让我接近了答案。

首先澄清一点:

该应用程序是用C#(2.0+)编写的,并使用ADO.NET与SQL Server 2005进行通信。 镜像设置是托管Principal和Mirror的两台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)得到让我真正思考

的回复,我就不会到这里

墨菲

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

另外,您是否使用见证服务器自动从主服务器故障转移到镜像服务器?这是我所知道的唯一一种让它自动发生的方式,而且根据我的经验,你会得到很多误报,网络打嗝可以欺骗镜子,并且见证主要是关闭,而事实上并非如此。 / p>