Почему наши запросы застряли в состоянии "Запись в сеть" в MySql?
У нас много запросов
select * from tbl_message
которые застревают на состоянии "Запись в сеть". Таблица имеет 98 тысяч строк.
Дело в том, что... мы даже не выполняем ни одного запроса из нашего приложения, поэтому я думаю, что вопрос заключается в следующем:
- Что может генерировать запрос?
- ... и почему он застревает в состоянии "запись в сеть"
Я чувствую себя глупо, задавая этот вопрос, но я на 99,99% уверен, что наше приложение не выполняет такой запрос к нашей базе данных... однако мы выполняем пару запросов к этой таблице, используя инструкцию WHERE:
SELECT Count(*) as StrCount FROM tbl_message WHERE m_to=1960412 AND m_restid=948
SELECT Count(m_id) AS NrUnreadMail FROM tbl_message WHERE m_to=2019422 AND m_restid=440 AND m_read=1
SELECT * FROM tbl_message WHERE m_to=2036390 AND m_restid=994 ORDER BY m_id DESC
Я искал наше приложение несколько раз для select * from tbl_message
но ничего не нашли... Но все равно наш журнал запросов на нашем сервере MySQL полон Select * from tbl_message
запросы
3 ответа
Поскольку приложения волшебным образом не генерируют запросы так, как им нравится, я думаю, что вполне вероятно, что где-то в вашем приложении есть ошибка, которая вызывает это. Вот несколько советов, которые вы можете использовать, чтобы отследить это. Я предполагаю, что вы используете PHP, так как вы используете MySQL, поэтому я буду использовать это для моих примеров.
Попробуйте добавить комментарии перед всеми вашими запросами в приложении, например так:
$sqlSelect = "/* file.php, class::method() */";
$sqlSelect .= "SELECT * FROM foo ";
$sqlSelect .= "WHERE criteria";
Комментарий появится в вашем журнале запросов. Если вы используете какую-то оболочку API базы данных, вы можете добавить эти сообщения автоматически:
function query($sql)
{
$backtrace = debug_backtrace();
// The function that executed the query
$prev = $backtrace[1];
$newSql = sprintf("/* %s */ ", $prev["function"]);
$newSql .= $sql;
mysql_query($newSql) or handle_error();
}
Если вы не используете оболочку, а выполняете запросы напрямую, вы можете использовать расширение runkit и функцию runkit_function_rename, чтобы переименовать mysql_query (или что вы используете) и перехватить запросы.
Временно включить журнал запросов, поставив
log=
в ваш файл my.cnf перезапустите mysql и просмотрите журнал запросов для этих загадочных запросов (вам не нужно давать журналу имя, оно будет принимать одно из значений хоста).
Существует (по крайней мере) два режима извлечения данных для MySQL. С помощью c api вы можете либо вызвать mysql_store_result (), либо mysql_use_result ().
mysql_store_result () возвращается, когда все данные результатов передаются с сервера MySQL в память вашего процесса, т.е. никакие данные не должны передаваться для дальнейших вызовов mysql_fetch_row ().
Однако с помощью mysql_use_result () каждая запись должна выбираться индивидуально, если и когда вызывается mysql_fetch_row (). Если ваше приложение выполняет некоторые вычисления, которые занимают больше времени, чем период времени, указанный в net_write_timeout между двумя вызовами mysql_fetch_row (), сервер MySQL считает, что ваше соединение истекло.