什么会导致PHP忽略mysqli.reconnect设置?

时间:2013-02-18 12:42:37

标签: php mysql

我们有几个不同的服务器运行相同的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。

3 个答案:

答案 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...
}