ситуация следующая:
php-скрипт на сервере a, запущенный пользователем 'web' (nginx + php-fpm), должен обращаться к mysql на сервере b через библиотеку pdo, но получает SQLSTATE [HY000] [2003] Невозможно подключиться к серверу MySQL на 'xxx.xxx .xxx.xxx '(4)
сервер centos 6.5, php 5.3; сервер b centos 6.2, mysql 5.1
однако клиент командной строки mysql - запускаемый от имени непривилегированного пользователя - может подключаться идеально, воспроизводимо и стабильно.
после того, как клиент командной строки mysql установил успешное соединение между серверами, сценарий php также успешно работает в течение 5-7 минут, предположительно до тех пор, пока клиентское соединение командной строки mysql не истечет.
что мне не хватает?
вот тестовый сценарий:
<?php
try {
$dbh = new PDO('mysql:host=111.111.111.111;dbname=myname;port=3306', 'myuser',
'mypass');
echo 'Connected to database';
}
catch(PDOException $e)
{
echo $e->getMessage();
}
Итак, оказывается, что это все-таки проблема маршрутизации.
В настоящее время мы используем сеть со статической маршрутизацией, и для сервера mysql a не определен маршрут обратно к серверу b.
настройка сети немного запутана, поскольку физическое соединение выглядит следующим образом: сервер b (вне сайта)> vpn gw> интернет> контрольная точка fw> openwrt router> server a
Очевидно, клиент командной строки mysql более снисходительный и все равно смог установить это соединение, но библиотека pdo - нет.
После добавления маршрута библиотека pdo могла самостоятельно успешно устанавливать соединения и с тех пор успешно работает.
Итак, проверьте свои маршруты, даже если соединения ping / telnet / mysql вроде бы работают.
Кстати, может ли ошибка «Прерванный системный вызов» покрыть этот сценарий?
Просто столкнулся с такой проблемой, хотя она была немного другой с точки зрения серверов, адресов и т. Д. Важная вещь, которая помогла мне решить эту проблему:
Если первый выходит из строя, а второй работает, возможно, у вас есть дополнительная учетная запись пользователя в вашей БД, назначенная для хоста, с которого вы подключаетесь.
Проверить существующих пользователей с помощью
select host, user, password from mysql.user;
Если вы найдете там что-то вроде:
| host | user | password
+----------------+----------------+------------------------------------------
| 10.10.10.1 | myuser |
| % | myuser | *0803B925439C244BA857C3FD07A4F86A556F0925
это означает, что у вас есть этот дополнительный пользователь, подключенный к хосту PHP, с которого вы подключаетесь. Либо отбросьте его, либо сделайте правильный пароль привилегиями для этого конкретного пользователя хоста.
$ perror 4
OS error code 4: Interrupted system call
Вы должны просто попробовать еще раз при получении этой конкретной ошибки.
Это может быть признаком сильно загруженный сервер / сеть. В этом случае вы можете попробовать увеличение таймаута подключения как краткосрочное решение, а также решение проблем с перегрузкой в долгосрочной перспективе.