| |
Часто это выглядит так:
$php phpconf2009_3.php
string(26) "MySQL server has gone away"
Код:
$cat phpconf2009_3.php
<?php
mysql_connect('127.0.0.1:3351', 'root', '');
mysql_select_db('test');
mysql_query('set wait_timeout=1');
$query = 'SELECT 1';
sleep(3);
$result = mysql_query($query);
if (0 != mysql_errno())
var_dump(mysql_error());
else
while ($row = mysql_fetch_row($result))
var_dump($row);
mysql_close();
?>
Перед тем как указать на причину возникновения ошибки мне бы хотелось обратить ваше внимание на несколько сиситемных переменных MySQL сервера. Это переменные, отвечающие за timeout:
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 |
+----------------------------+-------+
Ниже приведены их описания:
connect_timeout
Сколько ждать ответа сервера перед тем как выдать ошибку о том, что сервер не отвечает.
interactive_timeout
Сколько ждать активности от интерактивного клиента перед тем как разорвать соединение.
wait_timeout
Сколько ждать активности от любого клиента перед тем как разорвать соединение. Если клиент интерактивный и значение interactive_timeout отличается от wait_timeout, то будет использовано значение interactive_timeout.
net_read_timeout
Сколько ждать ответа на запрос SELECT
net_write_timeout
Сколько ждать ответа на запрос, модифицирующий данные.
В приведённом выше примере проблема была в том, что мы ждали слишком долго для предварительно установенного маленького wait_timeout:
mysql_query('set wait_timeout=1');
установленный wait_timeout.
sleep(3);
время ожидания: 3>1, поэтому не удивительно, что мы получили ошибку.
Естественно sleep(3) был добавлен только для наглядности. В случае реального приложения следует обратить внимания на места, где такая задержка может быть вызвана в том числе кодом без использования sleep и подобных функций.
Также проверяйте другие timeout-ы в случае аналогичных ошибок.
Приём 16: проверяйте значение wait_timeout и других timeout-ов, если вы встречаете ошибку "MySQL server has gone away"
Также я хотела бы обратить ваше внимание на то, что вы не всегда получите сообщение "MySQL server has gone away" в случае слишком маленького timeout. Это также может быть сообщение Lost connection to MySQL server at 'reading authorization packet'. Чаще всего такое сообщение говорит о проблеме с connect_timeout.
Для примера я не смогла найти сети с достаточными для повторения проблемы перебоями, поэтому применила отладчик.
Запускаем интерпретатор PHP под отладчиком gdb:
$gdb php
Устанавливаем breakpoint в клиентской функции MySQL C API:
(gdb) b wait_for_data
Breakpoint 1 at 0x4337a: file client.c, line 190.
Передаём имя файла с PHP скриптом интерпретатору:
(gdb) set args phpconf2009_3.php
Запускаем программу:
(gdb) run
Starting program: /usr/local/bin/php phpconf2009_3.php
Reading symbols for shared libraries .+.................................................................++.++ done
Breakpoint 1 at 0x204e435: file client.c, line 1861.
Reading symbols for shared libraries . done
Breakpoint 1, wait_for_data (fd=6, timeout=60) at client.c:195
195 ufds.fd= fd; client.c:1861
(gdb)
Когда интерпретатор останавливается ждём 11 секунд, что на 1 секунду больше предустановленного значения connect_timeout, затем вводим команду с (продолжить).
(gdb) c
Continuing.
PHP Warning: mysql_connect(): Lost connection to MySQL server at 'reading authorization packet', system error: 0 in /Users/apple/Documents/www_project/MySQL/Conferences/phpconf2009_3.php on line 2
Warning: mysql_connect(): Lost connection to MySQL server at 'reading authorization packet', system error: 0 in /Users/apple/Documents/www_project/MySQL/Conferences/phpconf2009_3.php on line 2
В результате иы получили ошибку Lost connection to MySQL server at 'reading authorization packet', что говорит о слишком маленьком connect_timeout
Что делать?
Проблемы с connect_timeout чаще всего свидетельствуют либо о нестабильной работе сети между клиентом и MySQL сервером, либо о том, что машина, на которой запущен MySQL сервер, перегружена.
Поэтому после того как вы проверили помогает ли увеличение timeout, попытайтесь найти и устранить реальную причину такого поведения, если это возможно.
Не увеличивайте connect_timeout без необходимости: никому не пронравится ждать слишком долго!
Приём 17: проверяйте значение connect_timeout в случае ошибки Lost connection to MySQL server at 'reading authorization packet'
Назад | Содержание | Вперёд |
Автор 2009 Света Смирнова COPYRIGHT © 2009 С.Смирнова и С.Ласунов sveta_гав_js-client_точка_com |
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |