2

我们有几台不同的服务器运行相同的 PHP 脚本,所有这些都使用 PHP mysqli 连接/函数,我们注意到,在一台新服务器上,我们开始收到许多 MYSQL Gone Away 错误。

wait_timeout在 MYSQL 中,在所有服务器上都设置为 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。

4

3 回答 3

2

原来问题出在 MYSQLND 驱动程序上。我们的服务提供商基本上重新编译了 PHP,这解决了这个问题。

于 2013-02-19T10:20:17.820 回答
1

有一个关于此的 php 错误,解决为 wontfix:https ://bugs.php.net/bug.php?id=52561

于 2014-09-26T23:46:50.697 回答
0

我只是在寻找有关设置的信息时遇到了这个问题mysqli.reconnect。根据手册:

https://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.reconnect

注意php.inimysqlnd 驱动程序忽略此设置。

这没有具体说明它是否意味着它总是会或总是不会自动重新连接。“不会”似乎更有可能,上面的评论证实了这一点,指出当设置为 1 时它没有发生。

我的问题是我想要一种方法来知道连接何时终止(出于错误报告的目的,因此我只能在这种情况下实现对失败的数据库操作的选择性重试)。我不知道是否有更直接的方法来检查数据库连接是否存在,但我找到了mysqli::ping()方法。除非,如果它默默地自动重新连接,我不会知道它发生了。

所以我的解决方案是保存/禁用/恢复设置以及 using 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...
}
于 2019-05-17T21:54:11.503 回答