MySQL sleep запросы

Многим новичкам интересно знать, откуда берутся эти спящие запросы в мускуле, а все очень просто.

Давайте освежим память перечнем того, как все работает.

  1. пользователь открывает страницу Вашего сайта
  2. на сервер приходит запрос к Apache
  3. Apache посылает запрос PHP
  4. PHP подключается к MySQL
  5. PHP направляет SQL-запрос в MySQL
  6. MySQL выполняет запрос и отдает результат в PHP
  7. PHP закрывает соединение с MySQL
  8. PHP формирует контент и отдает его в Apache
  9. Apache посылает ответ в браузер

Вроде бы все отлично, и никаких проблем быть не может, но они появляются на шаге 6, потому, что до шага 7 дело не доходит.

А может это быть потому, что PHP скрипт не завершает свою работу, и обычно причина:

  • банальная нехватка памяти (память можно увеличить в PHP-конфиге)
  • неправильная логика работы скрипта в результате которой получился безконечный цикл
  • php-процесс просто убили в консоле

Собственно все, исправляйте одну из этих ошибок и SLEEP-запросов не будет.

Подробнее

А теперь подробнее, для тех кто не поверил и хочет разобраться подробнее:

mysql> show full processlist;
+-----+------------+-----------+------------+---------+------+-------+-----------------------+
| Id  | User       | Host      | db         | Command | Time | State | Info                  |
+-----+------------+-----------+------------+---------+------+-------+-----------------------+
| 127 | putin      | localhost | mydb       | Sleep   |  895 |       | NULL                  |
| 130 | root       | localhost | mydb       | Query   |    0 | NULL  | show full processlist |
+-----+------------+-----------+------------+---------+------+-------+-----------------------+

итак, мы видим зависший (уснувший) MySQL-процесс, и в довесок к нему мы можем увидеть зависший Apache-процесс

# netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
...
tcp        0      0 127.0.0.1:80            127.0.0.1:47733         ESTABLISHED 27420/apache2  
...

а давайте убьем Apache-процесс, ведь это должно отразиться и на MySQL:

# service apache2 restart

готово, теперь смотрим на MySQL-процессы:

mysql> show full processlist;
+-----+------------+-----------+------------+---------+------+-------+-----------------------+
| Id  | User       | Host      | db         | Command | Time | State | Info                  |
+-----+------------+-----------+------------+---------+------+-------+-----------------------+
| 130 | root       | localhost | mydb       | Query   |    0 | NULL  | show full processlist |
+-----+------------+-----------+------------+---------+------+-------+-----------------------+

и видим, что спящего процесса нет, а это значит, что убив Apache-процесс, у нас убился PHP-процесс, который закрыл соединение с MySQL.

Что такое SLEEP запрос MySQL

Это процесс, который отработал и который теперь ждет, что клиент с помощью указателя выполнит считывание результатов запроса.

SLEEP процесс никак не влиеют на производительность. Однако, он использует несколько байт, чтобы поддержать текущее соединение с клиентом.

Что делать, чтобы SLEEP запросов не было

Вернемся к ситуации выше (клиент может подключиться и упасть не закрыв соединение или клиент ушел в рекурсию и поэтому держит подключение), тогда SLEEP процесс будет висеть до истечения таймаута. Вот тут может возникнуть другая проблема - у Вас наступит сутуация с лимитом подключений к MySQL. Чтобы такой ситуации не произошло, Вам нужно чтобы соединения закрывались по тайм-ауту, который можно указать следующими параметрами:

interactive_timeout - Сколько ждать активности от интерактивного клиента перед тем как разорвать соединение.

wait_timeout - Сколько ждать активности от любого клиента перед тем как разорвать соединение. Если клиент интерактивный и значение interactive_timeout отличается от wait_timeout, то будет использовано значение interactive_timeout.

Указать параметры можно следующими способами:

1. Указать параметры в файле my.cnf (не забудьте затем перезапустить mysql):

[mysqld]
interactive_timeout=180
wait_timeout=180

2. Если Вы не хотите перезапускать mysql, тогда в mysql-клиенте выполните две команды:

SET GLOBAL interactive_timeout = 180;
SET GLOBAL wait_timeout = 180;

3. Сделать, чтобы клиент (например PHP) указал данные параметры для текущей сессии:

<?php
mysql_connect('127.0.0.1:3351', 'root', '');
mysql_select_db('test');
mysql_query('set wait_timeout=1');
$result = mysql_query( 'SELECT * FROM table');

p.s. Есть и другие интересные параметры:

mysql> show variables like '%timeout%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| interactive_timeout        | 28800 |
| net_read_timeout           | 30    |
| net_write_timeout          | 60    |
| wait_timeout               | 28800 |
+----------------------------+-------+

Немного про PROCESSLIST

Следующие две команды эквивалентны:

SHOW FULL PROCESSLIST;

SELECT * FROM information_schema.processlist;

Так же результат можно представить из списка процессов, любым удобным для Вас способом. Есть некоторые базовые примеры.

Показать количество подключений для каждого пользователя:

SELECT 'USER', COUNT(*) FROM information_schema.processlist GROUP BY 'USER';

Показать количество подключений по каждому хосту:

SELECT 'HOST', COUNT(*) FROM information_schema.processlist GROUP BY 'HOST';

Показать активности пользователя root:

SELECT * FROM information_schema.processlist WHERE 'USER' = 'root';

Показать процессы подобные указанному:

SELECT * FROM information_schema.processlist WHERE 'INFO' LIKE 'SELECT %';

Показать среднее время запроса для каждой базы данных:

SELECT 'DB', AVG('TIME') FROM information_schema.processlist GROUP BY 'DB';

Удачки в разработке!

Источники: 1 - 2 - 3 - 4 - 5

Оцени публикацию:
  • 15,75
Оценили человек: 15
Теги : php, mysql, sleep, processes

Похожие статьи:

Справочники и учебники:


Предложения и пожелания:
Ваше имя:
Ваш E-mail:
Сколько будет Οдин + Τри
Главная
X

Новые заметки:

Про что мы забываем когда делаем оценку задачи по времени

Список вопросов для собеседования разработчика по телефону

Symfony2 авторизация без Doctrine2 для чайника

Phpstorm7 LiveEdit

Жесткий хабр или не хабр, тогда кто?

Яндекс.Деньги мошенничество

Как узнать какие страницы в поиске яндекса или это секрет

Последние комменты:

Yapro CMS:

Здравствуйте, Гость | Войти | Регистрация | Карта сайта | RSS ленты | Ошибка в тексте? Выделите её мышкой и нажмите: Ctrl + Enter

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2018 YaPro.Ru

Главная » Веб-мастеру » MySQL »