【问题标题】:What would cause PHP to ignore mysqli.reconnect setting?什么会导致 PHP 忽略 mysqli.reconnect 设置?
【发布时间】:2013-02-18 12:42:36
【问题描述】:

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

wait_timeout 在 MYSQL 中在所有服务器上设置为 300 秒,这是在此特定服务器上连接断开之前所需的时间长度(即下面代码中的查询之间等待 301 秒会产生错误,但 299 秒没有)。

但是,所有服务器也将mysqli.reconnect 设置为 1(打开)。根据文档,mysqli.reconnect 应该意味着断开的连接会自动重新连接,但绝对不是。

这是我运行的代码 sn-p 来演示该问题。它适用于除此特定服务器之外的所有服务器:

$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。

【问题讨论】:

  • 您可能会从某个地方获得一个压倒一切的设置。您是否检查过新服务器上的多个 my.cnf 文件?
  • 当我在服务器上执行echo ini_get('mysqli.reconnect'); 时(命令行和通过网络浏览器),设置总是显示为“1”(打开),所以在运行时 PHP 肯定有正确的值。是否存在可能导致重新连接不起作用的 MySQL 配置设置?
  • 确实有一种方法可以控制从 MySQL 端自动重新连接 - dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html - 我假设所有服务器都使用相同的数据库服务器,所以我认为这是一个可能的原因。
  • 他们都连接到同一个数据库服务器,对不起,我的错!
  • Craig,您能否更新您的代码 sn-p 以显示您最新的测试脚本?塔

标签: php mysql


【解决方案1】:

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

【讨论】:

  • 您有更多信息吗?我们有同样的问题,从 MYSQLND 驱动切换回 libmysql 解决了这个问题,但我们想使用本机驱动。提供者是否重新编译了 php、驱动程序或其他?您能告诉我们重新编译的 php 版本是什么吗?想知道您是否仍在使用本机驱动程序。
  • 嗨,安迪,据我了解,他们只重新编译了 PHP。恐怕我不记得它是什么版本的 PHP,我认为它是 5.3.3 或 5.3.27 版本。抱歉,这是前一段时间了,我找不到原始电子邮件记录。
  • @CraigSefton,是不是因为下面提到的 Mysqlnd Jay 的错误?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    注意:这个php.ini设置被mysqlnd驱动忽略了。

    这并没有具体说明它是否总是会自动重新连接,或者总是不会自动重新连接。 “不会”似乎更有可能,上面的评论证实了这一点,指出当设置为 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...
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多