我们有几个不同的服务器运行相同的PHP脚本,所有这些都使用PHP mysqli连接/函数,我们注意到,在一台新服务器上,我们开始收到很多MYSQL Gone Away错误。
MYSQL中的 wait_timeout
在所有服务器上设置为300秒,这是连接在此特定服务器上丢失之前所花费的时间长度(即,在下面的代码中,查询之间的等待时间为301秒)错误,但299秒没有)。
但是,所有服务器的mysqli.reconnect
也设置为1(开启)。根据文档,mysqli.reconnect
应该意味着丢弃的连接会自动重新连接,但绝对不是。
以下是我运行的代码片段,演示了此问题。它适用于除此特定服务器之外的所有服务器:
$mysqli = new mysqli('ip', 'username', 'pass', 'db');
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT * FROM table LIMIT 1";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
sleep(301);
$query = "SELECT * FROM table LIMIT 1";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
mysqli_close($mysqli);
print "Finished\n";
exit;
我还重写了测试脚本以使用mysqli_ping()
(因为文档声明如果mysqli.reconnect设置为1,此函数应该自动重新连接),但是这仍然没有重新连接,第二个查询总是会产生MySQL已经消失的错误。
所有服务器都运行略有不同的PHP版本。失败的服务器运行5.3.21,其他服务器运行5.3.0和5.3.10。
答案 0 :(得分:2)
原来问题在于MYSQLND驱动程序。我们的服务提供商基本上重新编译了PHP,这解决了这个问题。
答案 1 :(得分:1)
有一个关于此的PHP错误,解析为wontfix:https://bugs.php.net/bug.php?id=52561
答案 2 :(得分:0)
我只是在寻找有关mysqli.reconnect
设置的信息时碰到了这一点。根据手册:
https://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.reconnect
注意:mysqlnd驱动程序将忽略此
php.ini
设置。
这并没有指定它是否意味着总是会或者永远不会自动重新连接。似乎更有可能“不会”,这已通过上面的评论得到确认,并指出在设置为1时不会发生。
我的问题是我想要一种方法来知道连接终止时的 (出于错误报告的目的,因此只有在这种情况下,我才能选择性地重试失败的数据库操作)。我不知道是否有更直接的方法来检查数据库连接是否存在,但是我找到了进入mysqli::ping()
方法的方法。除非它默默地自动重新连接,否则我不知道它发生了。
所以我的解决方案是使用ping()
来保存/禁用/恢复设置,如下所示:
if (!$result) { // DB operation failed
$save = ini_get('mysqli.reconnect'); // save setting
ini_set('mysqli.reconnect', 0); // disable it
$connected = $mysqli->ping(); // check connection
ini_set('mysqli.reconnect', $save); // restore setting
}
if ($connected) {
// Failure was something else. Handle that...
} else {
// Failure was due to dropped connection.
// Explicitly reconnect.
// Ok to retry operation...
}