Как установить тайм-аут для запроса MySQL, используя C API - PullRequest
8 голосов
/ 23 ноября 2010

Я знаю, что здесь много похожих вопросов, а также много результатов, когда я в Google, но ни один из них не отвечает на мой вопрос.Я прочитал это , это , это и это , но ни один из них не работает для меня.Я не говорю о каких-либо блокировках, я не хочу делать это с использованием коннектора MySQL c ++, просто C API.

Также, что здесь очень важно: я делаю это на LINUX.Почему я упоминаю это?Потому что в документации для mysql_options:

MYSQL_OPT_READ_TIMEOUT - ...This option works only for 
TCP/IP connections and, prior to MySQL 5.0.25, only for Windows.

MYSQL_OPT_WRITE_TIMEOUT- ... This option works only for 
TCP/IP connections and, prior to MySQL 5.0.25, only for Windows

Итак, есть ли способ установить время ожидания запроса для версий, предшествующих 5.0.25?

Моя версия MySQL:

[root@xxx kiril]# mysql --version
mysql  Ver 14.12 Distrib 5.0.22, for redhat-linux-gnu (i686) using readline 5.0

РЕДАКТИРОВАТЬ: По крайней мере, есть ли способ отменить запрос?Я могу запустить таймер как другой поток, но когда он истечет .. могу ли я как-то отменить запрос?

Ответы [ 4 ]

2 голосов
/ 17 декабря 2010

Хорошо, я нашел решение .. Спасибо Будет и PRR (мой сотрудник).

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

Кроме того, не было возможности ни разорвать соединение через библиотеку, ни отменить / уничтожить запрос, поскольку проблема была в сервере БД.

А вот и грубое решение, но все же гораздо лучше, чем _EXIT( FAILURE ): Вот связанный с этим вопрос: «Как принудительно закрыть сокет в Linux?» - так что я просто закрыл сокет, используя системный вызов.

Важное примечание : (спасибо Will) - Оказалось, что наша оболочка библиотеки MySQL имеет флаг "fail-safe", поэтому на закрытом сокете (или другой критической ошибке) она пытается «решить» проблему, поэтому она сама открывает сокет в моем случае. Итак, я просто отключил эту опцию, и теперь все в порядке - выполнение прекращается из-за исключения - это самый "мягкий" способ сделать это.
Конечно, это должно быть сделано через другой поток - например, по таймеру.

РЕДАКТИРОВАТЬ: Тайм-ауты действительно работают для версий после 5.0.25. Но, по крайней мере на RHEL4 и RHEL5, таймауты по некоторым причинам утроены! Например, если для некоторых тайм-аутов установлено значение 20 с, реальное время ожидания составляет ~ 60 с.
Кроме того, еще одним важным моментом является то, что эти таймауты (как и любые другие параметры) ДОЛЖНЫ быть установлены после mysql_init и до mysql_connect или mysql_real_connect ,

1 голос
/ 26 ноября 2010

Полагаю, вы могли бы реализовать тайм-аут для вызова функции C (как описано в этом потоке C ++: как реализовать тайм-аут для произвольного вызова функции? ), но вам необходимо тщательно обдумать в каком состоянии вы бы оставили БД - предположительно, они предназначены только для чтения базы данных, а не для вставки / обновления.

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

Если вы не возражаете против использования потоков, вы можете запустить запрос из нового потока, и основной поток выполнит короткий pthread_cond_timedwait, чтобы новый поток установил переменную условия, с которой он устанавливает соединение. Затем вы можете позволить потоку задерживаться до истечения времени ожидания самого вызова mysql. Просто убедитесь, что он отключен, чтобы его ресурсы освободились, когда он наконец-то истечет. Это решение не очень красивое, но, по крайней мере, должно работать.

0 голосов
/ 23 ноября 2010

Я никогда не пытался это сделать, но я читал, и я думаю, что это может означать, что MYSQL_OPT_WRITE_TIMEOUT и MYSQL_OPT_READ_TIMEOUT предназначены только для окон до MySQL версии 5.0.25, но теперь они должны работать для каждого соединения TCP / IP.Взгляните здесь

С уважением

РЕДАКТИРОВАТЬ: Я бы попытался обновить сервер MySQL до более новой версии и попробовать, если он работает.

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