Клієнт вичерпується, а запит MySQL залишається запущеним?


9

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

Запитання

  • Чи існує стандартний спосіб вирішення подібних проблем у MySQL?
  • Чи є фундаментальна причина, якої нам потрібно уникати?

Відповіді:


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 на сервері DB.

Ось що говорить Документація MySQL, що відповідає цим параметрам:

  • 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 вам доведеться чекати будь-якого запиту, який знаходиться посеред кроків, що інтенсивно працюють з диском, або мають внутрішні мутекси.


Чи є стандартний надійний спосіб запустити KILL проти процесів, що працюють давно, або це зазвичай робиться за допомогою роботи bash script / cron?
asthasr

Я фактично написав повідомлення ще в травні 2011 року про те, як запустити скрипт за допомогою information_schema, щоб знищити купу підключень до БД: dba.stackexchange.com/a/2637/877
RolandoMySQLDBA

"Будь ласка, переконайтеся, що ці тайм-аути встановлені достатньо високо, щоб вмістити запити, які можуть працювати протягом дуже тривалого часу, які можуть включати: Mass UPDATE ..." Приклад: php + mysql Мені потрібно вибрати кожен запис із стовпця таблиці, тому отримати рядки, а потім щось зробити ... потім оновіть інший запис з новим значенням. Поставте випадок, що для цього сценарію потрібно близько 5+ хвилин. Один ВИБІР на початку і ОНОВЛЕННЯ до кінця, набирайте рядки і робіть ... посередині. Чи можете ви пояснити, що має стосуватися wait_timeout у цій ситуації? Дійсно, мені незрозуміло ... що таке безпечне значення для wait_timeout до безкоштовного ресурсу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.