2008-08-26 63 views
2

我們有幾個鏡像SQL Server數據庫。如何在鏡像SQL Server數據庫發生故障時收到通知

我的第一個問題 - 關鍵問題 - 是在數據庫故障轉移時收到通知。我不需要需要知道,因爲,呃,它的鏡像,所以它(幾乎)所有進行自動工作,但它會有用的建議,我目前正在獲得故障轉移,當我不認爲我應該如此它想知道它們什麼時候發生(沒有太多的挖掘),看看我能否確定原因。

我有服務運行,我可以很容易地用它來監視這個 - 所以另一個問題是「如何以編程方式確定哪個是主體,哪個是鏡像」 - 最好是以比嘗試更聰明的方式依次連接每個(這將主要工作,但...)。

感謝,墨菲

附錄:

答案之一查詢爲什麼我不需要知道其失敗時 - 答案是,我們正在使用ADO.NET開發,並且具有自動故障轉移支持,您只需將Failover Partner=MIRRORSERVER(其中MIRRORSERVER是您的鏡像服務器實例的名稱)添加到您的連接字符串中,並且您的代碼將透明地故障轉移 - 您可能會看到一些錯誤,具體取決於哪些連接處於活動狀態,但在我們的情況很少。

回答

2

右鍵,

兩個答案,多花點心思讓我的東西接近的答案。

一是多一點澄清:

的應用程序是用C#(2.0+),並使用ADO.NET交談到SQL Server 2005 鏡像設置是承載主體和鏡像兩個W2K3服務器加上第三臺服務器作爲顯示器託管一個快速實例。關於這一點的好處是故障轉移對於使用數據庫的應用程序來說都是透明的,它會爲某些連接拋出一個錯誤,但從根本上來說,一切都會很好地進行。是的,我們得到了奇怪的誤報,但重點在於讓系統繼續以最少的次數進行工作,並且鏡像確實提供了非常好的結果。

此外,這個問題並不是嚴重的服務器故障 - 通常有點更明顯,但有其他原因的故障轉移(參見上面的誤判),因爲我們確實有一些事情不能,對於各種原因,故障轉移,無論如何我們可以看到我們是否能夠識別出我們得到誤報的情況。

因此,考慮到箱子的上面,只需檢查狀態是不是很夠,並通過事件日誌追逐可能是過於複雜的 - 答案是,事實證明,相當簡單: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!"); 

     } 
    } 
} 

我就不會來到這裏沒有)提出的問題,然後b)獲得這讓我真正認爲

響應

Murph

1

如果故障切換邏輯位於您的應用程序中,您可以編寫一個狀態屏幕,通過在第一次連接嘗試失敗時寫入var來顯示您連接了哪個盒子。

我認爲你最好的選擇將是一個ping守護進程/ cron作業,它定期檢查每個框的狀態,並在沒有響應時發送一封電子郵件。

1

使用類似Host Monitor http://www.ks-soft.net/hostmon.eng/的東西來監視事件日誌中與故障轉移事件相關的消息,該消息可以通過電子郵件/短信向您發送警報。

我很好奇,儘管如何不需要知道故障轉移發生,因爲您是否必須更新應用程序中的數據源以指向失敗的新服務器?鏡像發生在不同的主機上(主鏡像和鏡像鏡像),而不像集羣有多個節點,這些節點似乎是外部的單個設備。

此外,您是否使用見證服務器爲了自動故障從主要鏡像到鏡像?這是我知道讓它自動發生的唯一途徑,並且根據我的經驗,你會得到很多誤報,其中網絡打嗝可以欺騙鏡子,而目擊者認爲主要是打倒了,實際上並非如此。