Как принудительно закрыть сокет в Linux? - PullRequest
1 голос
/ 16 декабря 2010

Для ЭТОЙ причины, я хочу попробовать что-то новое - закрыть сокет, используя какой-то системный вызов.

Ситуация в двух словах - невозможно установить тайм-аут запроса библиотеки mysql (C API, обратитесь к ссылке для получения дополнительной информации), поэтому я хочу попробовать закрыть сокет, чтобы посмотреть, как отреагирует библиотека. Возможно, это не очень хорошая идея, но все же хочу попробовать.

Вот что я сделал - есть еще один запущенный поток - таймер. Итак, после определенного времени ожидания (скажем, 10 секунд), если нет ответа, я хочу закрыть сокет. Структура MYSQL имеет член net, который также является структурой, и содержит fd. Но когда я пытаюсь сделать это:

shutdown( m_pOwner->m_ptrDBConnection->m_mysql.net.fd, SHUT_RDWR );
close( m_pOwner->m_ptrDBConnection->m_mysql.net.fd );

ничего не происходит. Возвращаемые значения из shutdown и close равны 0, но сокет все еще открыт (поскольку после 60-секундного ожидания есть возвращенный результат из БД, это означает, что клиент mysql все еще ожидает ответа от БД .

Есть идеи?

Спасибо

EDIT - Да, запущена транзакция, пока я пытаюсь закрыть сокет. Но это настоящая проблема - я не могу ни завершить запрос, ни закрыть соединение, ничего, и я не хочу ждать весь тайм-аут, который составляет 20 минут и 30 секунд, или что-то вроде этого. Вот почему я ищу грубую силу ..: /

Ответы [ 3 ]

1 голос
/ 16 декабря 2010

Просто выстрел в темноте, но обязательно отмените / прекратите все запущенные транзакции.Я не знаком с MySQL C API, но думаю, что есть способ проверить наличие активных соединений / запросов.Возможно, вам не удастся закрыть сокет просто потому, что все еще выполняются какие-то вещи, и их нужно привести в какое-то «разрешенное» состояние, будь то зафиксированное или откатанное.Я бы начал там и посмотрел, что происходит.Вы действительно не хотите отключать стиль сокета "грубой силы", если у вас все равно есть что-то ожидающее, потому что ваши данные впоследствии не будут в надежном "состоянии" - вы не будете знать, какие транзакции были успешными, а какие - нет, хотя япредположил бы, что MySQL будет откатывать любые ожидающие транзакции, если соединение внезапно прервалось.

EDIT : Из того, что я нашел с помощью Googling «MySQL останавливает безудержный запрос», консенсус, похоже, заключается в том, чтобы спроситьMySQL для завершения потока убегающего / долго выполняющегося запроса с использованием

KILL thread-id

Я мог бы представить, что вам доступен идентификатор потока в структуре данных MySQL, содержащей сокет.Возможно, вы захотите попробовать это, хотя IIRC для этого требует привилегий суперпользователя.

EDIT # 2 : Очевидно, MySQL предоставляет отказоустойчивый механизм, который принудительно перезапускает закрытое соединение, поэтомувыключение сокета фактически не завершит запрос.Как только вы закроете его, MySQL откроет другой и попытается завершить запрос.Отключение этого параметра позволит вам закрыть сокет и заставить запрос завершиться.

В комментариях ниже показано, как был найден ответ, и процесс мышления в нем.

0 голосов
/ 16 декабря 2010

Насколько я знаю, если shutdown() и close() оба возвращают 0, нет сомнений, что вы успешно закрыли сокет. Дело в том, что вы могли закрыть не тот FD. Или сервер не может правильно реагировать на корректное завершение работы (если это так, это можно считать ошибкой сервера: нет причин все еще ждать поступления данных). Я бы продолжал искать поддерживаемый способ сделать это.

0 голосов
/ 16 декабря 2010

Похоже, что у вас возникла проблема с таймером ожидания TCP, то есть со временем он закроется. [Короче говоря] это как бы неизбежно. По этому поводу было еще одно обсуждение.

закрыть против выключения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...