У меня есть основная база данных (server_A), зеркальная база данных (server_B) и база данных свидетелей (server_C). Базы данных настроены для автоматического перехода на другой ресурс, т.е. Когда сервер_A сходит или выходит из строя, сервер_B принимает на себя роль новой основной базы данных. Кворум базы данных настроен правильно, насколько мне известно.
Я написал приложение в c++ для подключения к базе данных и получения значения для обеспечения подлинного соединения. Приложение обнаруживает, когда происходит сбой при вызове GetValue и пытается восстановить соединение при возникновении ошибки.
Проблема заключается в следующем: когда у меня есть МНОЖЕСТВЕННЫЕ подключения к базе данных (два потока подключены, после подключения они получат значение в цикле), когда происходит переход на другой ресурс (остановка сервера sql на сервере A, так что сервер B возьмет на себя роль принципала), Я обнаруживаю сбой подключения и уничтожаю мое соединение и пытаюсь восстановить соединение с использованием той же строки соединения:
"Driver = {собственный клиент SQL]; Server = tcp: Server_A; Failover_Partner = tcp: Server_B; Database = SomeDatabase; Uid = SomeUser; Pwd = SomePassword;
** ПРИМЕЧАНИЕ ** Я подтвердил, что восстановление после сбоя произошло путем мониторинга баз данных.
Несмотря на то, что соединение с базой данных было правильно утилизировано, я не могу повторно подключиться к базе данных до тех пор, пока я не перезапущу приложение, или если я верну серверную_сервер обратно (теперь действую как зеркальная база данных), а затем отказоустойчивый сервер_B (выключение сервера sql), делая сервер A основной базой данных снова, приложение может подключаться без полного закрытия.
Хотя я мог бы манипулировать строкой соединения, чтобы сделать server_B новым главным и сервером_A новым Failover_Partner, это не идеальное решение, так как будет использовано больше соединений.
Имейте в виду, что это ТОЛЬКО случается с несколькими подключениями к базе данных. Если я запускаю приложение только с одним соединением, все в порядке, и я могу восстановить соединение только в том случае, когда происходит переход на другой ресурс.
EDIT: если я подключаюсь в начале с несколькими потоками, все в порядке. Когда я завершаю работу SQL Server, и, следовательно, происходит переход на другой ресурс, я могу повторно подключиться только тогда, когда я просматриваю и удаляю ВСЕ объекты и повторно создаю новые объекты. Кроме того, я использую SQL Native Client 11.0 (ODBC). Мысли?
Хорошо, я нашел ответ.
Мне пришлось изменить файл hosts, потому что мое приложение не находилось в том же домене, что и базы данных. Поэтому, пытаясь провалиться, я не смог связаться с базой данных с именем экземпляра (к чему был кэширован партнер по отказоустойчивости). Я изменил файл hosts, чтобы разрешить имя экземпляра на ip-адрес машины, и теперь все работает.
Многое из того, что вы описываете, согласуется с проблемой, описанной в KB 2605597 " Ошибка тайм-аута, когда зеркальное соединение с базой данных создается поставщиком данных.NET Framework для SQLClient".
В КБ описаны проблемы, когда тайм-аут соединения установлен на 15 секунд, я часто слышал об аналогичных проблемах, когда тайм-аут соединения установлен на 0 (что не является хорошей идеей по другим причинам, упомянув на всякий случай).
Это исправление применяется к серверам приложений. Если вы хотите разрешить это как возможную причину, вы можете протестировать повышение таймаута (как это говорится в разделах обходных путей сообщения), чтобы убедиться, что это не проблема.
Позже подумал: Другая вещь, которую я замечаю, необычна, заключается в том, что вы указываете TCP-протокол в строке подключения и имени партнера по отказоустойчивости. Мне не ясно, из документации, которую она поддерживает в имени партнера по отказоустойчивости. Возможно, вы захотите удалить это и указать сетевой атрибут. (Рекомендуется здесь.)
Я понимаю, что вы считаете, что проблема не в этом, из-за проблемы с одиночными/несколькими соединениями, которые вы протестировали.
Тем не менее, я думаю, что вам лучше упростить строку подключения, чтобы она была максимально последовательной с опубликованными примерами и удостоверилась, что это не те проблемы, с которыми люди обычно сталкивались с этим в первую очередь. (Проблема повторения возникает, когда есть латентность, что может сделать ее несколько спорадической.)