Право,
Два ответа и небольшая мысль привели меня к чему-то приближающемуся к ответу.
Сначала немного больше уточнений:
Приложение написано на 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!");
}
}
}
Я бы не приехал сюда, если бы а) не задал вопрос, а затем б) не получил ответов, которые заставили меня на самом деле подумать
Murph