Автоматическое аварийное переключение нескольких подключений к зеркальной базе данных при отключении основного

0

У меня есть основная база данных (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). Мысли?

  • 0
    Вполне возможно, что используемый вами драйвер не является потокобезопасным, и когда в поточной среде используется не поточно-безопасная библиотека, результаты не предвидятся.
  • 0
    Если бы это было так, разве приложение не сработало бы с самого начала без прохождения процесса зеркалирования? Если бы он не был безопасным для работы с потоками, я подозреваю, что сбой произошел бы при подключении несколько раз, независимо от отработки отказа.
Показать ещё 1 комментарий
Теги:
connection-string
connection-pooling
failover
database-mirroring

2 ответа

0
Лучший ответ

Хорошо, я нашел ответ.

Мне пришлось изменить файл hosts, потому что мое приложение не находилось в том же домене, что и базы данных. Поэтому, пытаясь провалиться, я не смог связаться с базой данных с именем экземпляра (к чему был кэширован партнер по отказоустойчивости). Я изменил файл hosts, чтобы разрешить имя экземпляра на ip-адрес машины, и теперь все работает.

0

Многое из того, что вы описываете, согласуется с проблемой, описанной в KB 2605597 " Ошибка тайм-аута, когда зеркальное соединение с базой данных создается поставщиком данных.NET Framework для SQLClient".

В КБ описаны проблемы, когда тайм-аут соединения установлен на 15 секунд, я часто слышал об аналогичных проблемах, когда тайм-аут соединения установлен на 0 (что не является хорошей идеей по другим причинам, упомянув на всякий случай).

Это исправление применяется к серверам приложений. Если вы хотите разрешить это как возможную причину, вы можете протестировать повышение таймаута (как это говорится в разделах обходных путей сообщения), чтобы убедиться, что это не проблема.

Позже подумал: Другая вещь, которую я замечаю, необычна, заключается в том, что вы указываете TCP-протокол в строке подключения и имени партнера по отказоустойчивости. Мне не ясно, из документации, которую она поддерживает в имени партнера по отказоустойчивости. Возможно, вы захотите удалить это и указать сетевой атрибут. (Рекомендуется здесь.)

Я понимаю, что вы считаете, что проблема не в этом, из-за проблемы с одиночными/несколькими соединениями, которые вы протестировали.

Тем не менее, я думаю, что вам лучше упростить строку подключения, чтобы она была максимально последовательной с опубликованными примерами и удостоверилась, что это не те проблемы, с которыми люди обычно сталкивались с этим в первую очередь. (Проблема повторения возникает, когда есть латентность, что может сделать ее несколько спорадической.)

  • 0
    Предоставленная строка подключения была изменена несколькими способами в надежде, что это проблема. Я попытался возиться с параметром сети, но все равно получил тот же результат. Я также не уверен в теге tcp: на отказоустойчивом партнере, я ничего не мог найти по этому поводу, но он делает то же самое, что и остальные. Кстати, тег tcp: потому что именованные каналы отключены, и мне не нужно иметь дело с таймаутом именованных каналов, когда он не включен в первую очередь. Наконец, я попытался установить более длительное время ожидания и установить короткое время ожидания для соединения и партнера по восстановлению после сбоя, но безуспешно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню