Как СУБД справляется с устаревшими соединениями? - PullRequest
0 голосов
/ 07 июня 2009

Подумайте о настройке подключения к СУБД, а затем дерните сетевой штекер. (Вы получите тот же эффект, если соединение проходит через шлюз NAT, и шлюз решает удалить это соединение.)

В этот момент сервер СУБД ожидает запроса или чего-либо еще, что никогда не произойдет. И TCP-соединение не будет закрыто клиентом, так как его больше нет в этой сети. Предположительно, сервер также не закроет его, поскольку он по-прежнему считает, что соединение открыто.

Может ли типичная СУБД справиться с этим с таймаутами и / или реализовать простой механизм поддержки активности через TCP? У кого-нибудь есть опыт работы с Oracle, SQL Server и MySQL?

Редактировать; Больше копаний предполагает, что mysql удаляет соединения после 8 часов бездействия.

Ответы [ 6 ]

1 голос
/ 07 июня 2009

Когда базовое TCP-соединение сбрасывается клиентом или сервером, стек TCP / IP на другой стороне обнаруживает это и уведомляет приложение. Вы можете быть уверены, что сервер базы данных закрывает соединение (и откатывает любую незафиксированную транзакцию).

Обновление: сбой сети просто выглядит с каждой стороны, как другая ушла. Обе стороны установят время ожидания сокета, сделают повторные попытки и т. Д., Чтобы они могли корректно обработать эти сбои. Джонатан поднимает интересную подзадачу в комментариях и выясняет, что сервер делает неявную фиксацию транзакции, если клиент явно отключается без прерывания транзакции в любом случае.

1 голос
/ 07 июня 2009

Это довольно широкий вопрос. Позвольте мне дать вам широкий ответ.

В дни клиент / сервер это было бы более серьезной проблемой, поскольку клиенты поддерживали постоянные соединения с базой данных. В настоящее время, по причине масштабируемости и других причин, приложения обычно пишутся «отключенными», в результате чего они устанавливают соединение с базой данных для получения своих данных, а затем быстро отключаются. Другими словами, приложения запрашивают соединения по мере необходимости.

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

Тайм-ауты гарантируют, что любые случайные соединения с базой данных не будут оставаться открытыми вечно.

0 голосов
/ 07 июня 2009

В SQL Server соединение (вы можете увидеть это с помощью sp_who) закрывается, а незафиксированные транзакции откатываются.

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

0 голосов
/ 07 июня 2009

Драйвер JDBC Oracle предоставляет метод proprietery ping () для класса соединения, который возвращает значение true, если соединение считается "активным".

К сожалению, ping () был реализован идиотом. Он отправляет на сервер запрос «выберите« x »из двойного», который далек от того, чтобы быть запросом с низкой отдачей из-за присутствия литерала «x», который затрудняет кэш запроса.

Мы вызывали ping () с нашего сервера приложений каждый раз, когда соединение было заимствовано из пула, пока оно почти не убило наш сервер оракула. ​​

Не рекомендуется.

0 голосов
/ 07 июня 2009

Соединения с базой данных, как правило, объединяются в пул, поэтому вам не нужно каждый раз устанавливать штраф за установление соединения. Серверы приложений предоставляют эту возможность, и они обычно предоставляют гибкость для очистки пула соединений и повторного установления всех соединений в их пуле при обнаружении этого состояния устаревших соединений.

0 голосов
/ 07 июня 2009

Конкретной ситуации, о которой вы говорите, на самом деле не бывает. Тот факт, что соединение установлено, не означает, что СУБД "ожидает" поступления запроса. Он может просто отметить наличие соединения, запустить асинхронную операцию чтения и продолжить работу.

Если бы проблема заключалась в том, чтобы асинхронное чтение никогда не завершалось, то, конечно, СУБД могла бы реализовать механизм периодического «пинга», который бы определял, открыто ли еще соединение. Как я думаю, вы уже знаете, что соединение TCP / IP открыто только в том случае, если оно открыто на обоих концах, поэтому, если СУБД отправила «ping» клиенту, которого больше нет, запись произойдет с истечением времени соединения, конец сервера закроется. Можно ожидать, что СУБД заметит это и уничтожит все серверные ресурсы, связанные с соединением.

...