【问题标题】:"MySQL server has gone away" when running script as cronjob将脚本作为 cronjob 运行时“MySQL 服务器已消失”
【发布时间】:2016-02-28 22:36:55
【问题描述】:

我有一个运行 PHP 脚本的 cronjob,它获取数百个 RSS 提要、解析它们、更新数据库,然后编写新的 Atom 和 RSS 提要文件。

当我在浏览器中调用它时脚本运行良好,但是当我让 crond 运行它时,它向我发送以下错误:

Warning:  mysqli::query(): MySQL server has gone away in /script.php on line 149

以下是脚本中的相关代码部分:

// ...
// the script has now been running for some time,
// fetching feeds, parsing them, and updating the database;
// now we check if the connection to the mysql server is still there,
// and then query the database and write the feed files

if (!isset($mysqli)) {
    $mysqli = new mysqli($db_host,
                         $db_username,
                         $db_password,
                         $db_name);
    $mysqli->set_charset('utf8');
    $mysqli->query("SET lc_time_names = 'de_DE'");
}

$query = "..."; // some SELECT query

if (!($result =  $mysqli->query($query))) {  // this is line 149
    // error message
}

// write the feed files
// ...

如您所见,在发送查询之前,我会检查连接是否有效。显然,数据库服务器在检查它和执行查询之间断开了连接。至少我猜是这样的。

那么,为什么会发生这种情况,我可以做些什么来保持连接处于活动状态(如果这确实是问题所在)?

我的 PHP 脚本在共享服务器(Linux 和 Apache)上运行,并且我没有对 MySQL 服务器的 root 访问权限 - 所以相关问题都没有回答我的问题,因为它们都建议更改数据库中的设置服务器配置文件。

另外,如果从浏览器调用,脚本在不同的 PHP 版本 (5.6) 下运行,而不是我让 crond 执行它时 (5.5)。见this related question


按照this answer 中的建议,我已尝试关闭现有连接并重新建立它:

$mysqli->close();
if (!isset($mysqli)) {
    $mysqli = new mysqli($db_host,
                         $db_benutzername,
                         $db_passwort,
                         $db_name);
    $mysqli->set_charset('utf8');
    $mysqli->query("SET lc_time_names = 'de_DE'");
}

我已尝试设置执行时间限制,如this answer 中所建议的那样:

set_time_limit(180);

或者在下面拉杰普特王子的回答中:

ignore_user_abort(true);
set_time_limit(0);

但这些都没有帮助。

【问题讨论】:

    标签: php mysql cron


    【解决方案1】:

    在 cron 作业文件的头部试试这个:

    <?php
    ignore_user_abort(true);
    set_time_limit(0);
    ?>
    

    【讨论】:

    • 其实在运行了几次cronjob之后,我发现这并没有帮助。不管有没有ignore_user_abort(true),都没有时间限制(0)和特定的时间限制(例如300)——有时脚本完成,有时没有。显然这个解决方案对是否发生错误没有影响。
    【解决方案2】:

    第一次尝试解决方案的问题(在我的问题中给出)是关闭连接不会取消设置变量,因此在

    $mysqli->close();
    if (!isset($mysqli)) {
    

    if-条件始终为假。

    一种解决方案是在关闭连接后取消设置变量:

    $mysqli->close();
    unset($mysqli);
    if (!isset($mysqli)) {
    

    但更简单的解决方案是检查连接而不是变量:

    if (!mysql_ping($mysqli)) {
    

    (请注意,我们当然不会关闭连接来测试它是否打开。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2011-06-07
      • 2010-12-20
      • 2013-06-13
      相关资源
      最近更新 更多