开发者社区 问答 正文

镜像的SQL Server数据库故障转移后如何获得通知

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

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

我有运行中的服务,可以很容易地使用它来监视它-因此,另一个问题是“我如何以编程方式确定哪个是主体,哪个是镜像”-最好以一种更加智能的方式,而不是仅尝试连接每个主体。转(大多数情况下可以,但是...)。

展开
收起
心有灵_夕 2019-12-25 20:39:24 1003 分享 版权
1 条回答
写回答
取消 提交回答
  • 这两个答案和一点点思考使我想到了一个接近答案的东西。

    首先再澄清一下:

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

    此外,问题不在于严重的服务器故障-通常更明显,但由于其他原因(参考上述错误肯定)会进行故障转移,因为由于多种原因,我们确实有几项无法进行故障转移无论如何,我们可以看看是否可以识别出误报的情况。

    因此,鉴于以上所述,仅检查框的状态还不够,并且追逐事件日志可能过于复杂-事实证明,答案非常简单: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)得到使我真正想到的答案,我就不会到达这里

    2019-12-25 20:39:51
    赞同 展开评论