Я недавно получал эти ошибки на моем сервере:
mysql_connect() [function.mysql-connect ]:
Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (4)
Я не думаю, что это проблема с учетными данными, поскольку имя пользователя, пароль, IP-адрес хоста и имя базы данных считываются из конфигурации плоского файла и сохраняются в константе PHP. Кроме того, мой журнал ошибок сообщает мне, что используемые учетные данные на самом деле те, что указаны в конфигурации.
Я попытался найти это в Google, и один из них указывает мне на max_connections
вопрос. Этот сайт все еще находится в стадии бета-тестирования, и количество одновременных пользователей не превышает 10. Я посмотрел значение max_connections
и это на 2048
Версия MySQL - 5.0.91, а сервер - Gentoo Linux (это то, что version_comment
говорит). Файл сокета находится в /var/run/mysqld/mysqld.sock
и порт 3306
Что меня действительно беспокоит, так это то, что эта ошибка кажется прерывистой. Я действительно не могу это уловить, когда пытаюсь воспроизвести. Кто-то сказал с одного сайта, что индекс ошибок (4)
означает прерванные системные вызовы.
Означает ли это, что я могу отклонить ошибку как ошибку моего веб-хоста, а не скрипта PHP?
Попробуйте проверить, не превышаете ли вы максимальное количество открытых файлов при вводе dmesg
и наблюдая за ошибкой "Слишком много открытых файлов".
Если вы его превышаете, вам придется увеличить лимиты, установленные системой, изменив /etc/security/limits.conf
с этим заявлением:
mysql soft nofile 2048
mysql hard nofile 4096
Где 2048 и 4096 - максимальное количество файлов, которое может открыть пользователь mysql. (Сюда входят все файловые дескрипторы, такие как сокеты)
Если ваша строка подключения является именем узла сервера и требует DNS, убедитесь, что это не промежуточное медленное разрешение DNS, вызывающее тайм-аут при попытке подключения. Используйте localhost, если это уместно. При необходимости запустите локальный DNS. Короткое замыкание в файле LMHOSTS, если необходимо. Полностью устраните необходимость в DNS и при необходимости укажите IP-адрес. Все, что нужно, чтобы не зависеть от внешнего, иногда медленного DNS-поиска имени сервера в строке подключения.
Иногда со строкой подключения все в порядке; иногда разрешение DNS периодически оказывается слишком медленным. Это может быть одной из причин периодических проблем с подключением.
Пример: предположим, что у вас есть облачный экземпляр, на котором размещены и mysql, и apache, но иногда вы запускаете сайт на локальной машине DevO. Таким образом, в строке подключения вы используете полное имя узла сервера, поэтому сайт «работает» либо с сайта развертывания, либо с вашей машины Devo. Может случиться так, что он никогда не выходит из строя на вашей машине Dev (потому что DNS вашей машины Dev всегда блестит), но вы получаете прерывистые проблемы с подключением на развернутом сайте (потому что, даже если экземпляр mysql расположен вместе, ваша строка подключения по-прежнему нуждается в чтобы DNS был разрешен обратно к самому себе, но DNS на вашем облачном экземпляре иногда не так блестит. Это немного раздражает, потому что в развернутом экземпляре экземпляр mysql на самом деле является локальным. Но на самом деле даже не суть - суть действительно , разница между временем отклика DNS вашего компьютера DevOps во всех условиях нагрузки и таким же в облачном экземпляре. Так что упростите задачу в облачном экземпляре. Ошибка не будет выглядеть так: «DNS был слишком медленным», даже если это является первопричиной.
Вы можете копать дальше, используя mysql_error () и mysql_errno ()-функции, но насколько я могу судить, ваши предположения верны.
В качестве короткого исправления ошибки (которую я обычно использую в своих веб-приложениях) является повторное подключение с логированием через две секунды:
$i = 0;
if ($i < 3 && ($db = mysql_connect(...)) == false) {
trigger_error('Could not connect to ...', E_USER_WARNING);
$i++;
sleep(2);
}
if (!$db)
die('Could not connect to ... for 3 times with a 2 second dely - giving up');
Поскольку посещаемость сайта низкая, вы можете подумать о запуске tcpdump на сервере в файл и настройте свой php-скрипт на отправку вам предупреждения в случае сбоя соединения. Скопируйте файл tcpdump в свой локальный ящик и проанализируйте сбой подключения через WireShark.
Вы также должны проверять журналы mysql-daemon и системные журналы в вашей системе во время сбоя на наличие аномалий.
Имейте в виду, что при регистрации вашего трафика будет регистрироваться все содержимое трафика, включая пароли и другую конфиденциальную информацию, что может нарушать политику или законы компании. Вы должны стереть tcpdump-файл после деактивации ведения журнала, чтобы не позволять конфиденциальной информации оставаться на сервере и передавать файлы через ssh или любое другое подходящее зашифрованное соединение.