Тайм-аут клиента, в то время как MySQL запрос продолжает работать

9

У нас возникла проблема, из-за которой запрос только для чтения, выполняемый через рабочую среду MySQL, блокировался по тайм-ауту с точки зрения пользовательского интерфейса и оставался запущенным на сервере (и, очевидно, потребляющим все больше и больше ресурсов), пока у нас не произошел сбой.

Вопросов

  • Есть ли стандартный способ решения этой проблемы в MySQL?
  • Есть ли фундаментальная причина, которую нам нужно избегать?
asthasr
источник

Ответы:

11

Вам нужно посмотреть, какие значения по умолчанию используются для тайм-аутов:

mysql> show variables like '%timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| innodb_rollback_on_timeout | OFF   |
| interactive_timeout        | 60    |
| net_read_timeout           | 30    |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 60    |
+----------------------------+-------+
10 rows in set (0.00 sec)

Обычно я наблюдаю за несколькими переменными тайм-аута. Это очень важно, если вы используете MySQL удаленно из MySQL Workbench, клиента mysql или приложения PHP на сервере приложений, связываясь с MySQL на сервере БД.

Вот что говорит MySQL Documentation с этими настройками:

  • wait_timeout (по умолчанию 28800 [8 часов]): количество секунд, в течение которых сервер ожидает активности на неинтерактивном соединении, прежде чем закрывать его. Этот тайм-аут применяется только к соединениям с файлами сокетов TCP / IP и Unix, но не к соединениям с использованием именованных каналов или общей памяти. При запуске потока значение сеанса wait_timeout инициализируется из глобального значения wait_timeout или из глобального значения interactive_timeout, в зависимости от типа клиента (как определено параметром соединения CLIENT_INTERACTIVE для mysql_real_connect ()). Смотрите также interactive_timeout.
  • interactive_timeout (по умолчанию 28800 [8 часов]): количество секунд, в течение которых сервер ожидает активности на интерактивном соединении, прежде чем закрывать его. Интерактивный клиент определяется как клиент, который использует параметр CLIENT_INTERACTIVE для mysql_real_connect (). Смотрите также wait_timeout.
  • net_read_timeout (по умолчанию 30): количество секунд ожидания для получения дополнительных данных из соединения перед прекращением чтения. Когда сервер читает с клиента, net_read_timeout - это значение времени ожидания, определяющее, когда следует прервать операцию. Когда сервер пишет клиенту, net_write_timeout - это значение времени ожидания, определяющее, когда следует прервать операцию. Смотрите также slave_net_timeout.
  • net_write_timeout (по умолчанию 60): количество секунд ожидания записи блока в соединение перед прерыванием записи. Смотрите также net_read_timeout.

Пожалуйста, убедитесь, что эти тайм-ауты установлены достаточно высоко для размещения запросов, которые могут выполняться в течение очень длительного времени, которые могут включать:

  • масса UPDATEs
  • масса DELETEs
  • ENABLE KEYS на большой MyISAM

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

RolandoMySQLDBA
источник
Существует ли стандартный надежный способ запуска KILL для процессов, которые выполнялись в течение длительного времени, или это обычно выполняется с помощью задания bash-скрипта / cron?
Астхаср
На самом деле я написал в мае 2011 года сообщение о том, как запустить скрипт с использованием information_schema для уничтожения связок с
RolandoMySQLDBA
«Пожалуйста, убедитесь, что эти тайм-ауты установлены достаточно высокими для размещения запросов, которые могут выполняться в течение очень долгого времени, которые могут включать в себя: массовые обновления ...» пример: php + mysql мне нужно выбрать каждую запись из столбца таблицы, так что выбирайте строки, а затем сделать что-то ... затем обновить другую запись с новым значением. Положите случай, что этот скрипт требует около 5 + минут. Один SELECT в начале и один UPDATE до конца, извлекайте строки и делайте ... посередине. Можете ли вы объяснить, что делать с wait_timeout в этой ситуации? На самом деле мне неясно ... какое безопасное значение для wait_timeout для свободного ресурса