资讯专栏INFORMATION COLUMN

mysqli_ping(): MySQL server has gone away

n7then / 2422人阅读

摘要:错误信息错误级别代号值常量说明运行时警告非致命错误。仅给出提示信息,但是脚本不会终止运行。方法的作用是检测当前连接是否存活,若不存活则自动重连。此外,对于第二个错误即虽然没有找到确切的原因,但是可以推测也是由于连接断开而造成的。

PHP 错误信息
errno:2 errmsg:mysqli_ping(): MySQL server has gone away
errno:8 errmsg:mysqli_ping(): send of 5 bytes failed with errno=32 Broken pipe

错误级别代号

常量 说明
2 E_WARNING 运行时警告 (非致命错误)。仅给出提示信息,但是脚本不会终止运行。
8 E_NOTICE 运行时通知。表示脚本遇到可能会表现为错误的情况,但是在可以正常运行的脚本里面也可能会有类似的通知。
原因分析

mysqli_ping()方法是专门为 libmysql 这种旧式的数据库驱动而设计的,它跟现在新式的 mysqlnd 驱动已不再兼容,所以才会报错。

从 PHP 5.3.0 开始,就引入了 mysqlnd 驱动,并且在 5.4.0 版本开始作为默认的 MySQL 数据库驱动。
所以,现在最新的 PHP 版本也是使用 mysqlnd 作为默认驱动。

mysqli_ping() 方法的作用是检测当前 mysql 连接是否存活,若不存活则自动重连。不过官方有下面一段话

Note: The php.ini setting mysqli.reconnect is ignored by the mysqlnd driver, so automatic reconnection is never attempted.

这说明了对于 mysqlnd 驱动来说,mysqli_ping() 已经不能再实现自动重连了。

那我们还能够用该方法来判断当前的 MySQL 连接是否存活吗?如果能,那在我们实现单例模式时是有帮助的。
因为我只需要连接一次数据库,就可以自始至终都使用同一个数据库连接来操作数据库。


看起来上面的程序并没有问题,但是为什么就会出现上面两个报错呢?而且是由于调用 mysqli_ping() 而引起的错误。

errno:2 errmsg:mysqli_ping(): MySQL server has gone away
errno:8 errmsg:mysqli_ping(): send of 5 bytes failed with errno=32 Broken pipe

其实无论怎么说,这个方法也不应该报错才对的,返回 true 或者 false 来告诉我们连接是否存活即可,这里直接报错不太好。

根据 Bug #52561 和 Bug #53287 这两个反馈来看,官方也没有给出答案,只是说 mysqli_ping() 已不适用于 mysqlnd,如果一定要用该函数那只能配合 libmysql 驱动来用。

原因结论

实际上,如果 MySQL 连接还存活的情况下,使用 mysqli_ping() 去检测是不会报错的,一切正常。只有当 MySQL 主动断开了与 PHP 的连接后,再用该方法去检测时才会出现报错信息。

这种情况一般会出现在两次间隔时间较长的时间内,期间 MySQL 根据配置参数 wait_timeout 的阀值而断开了长时间没有再发送查询请求的连接。若此时再调用 mysqli_ping(self::$link) 就会出现 MySQL server has gone away 这样的报错信息。

此外,对于第二个错误即 send of 5 bytes failed with errno=32 Broken pipe 虽然没有找到确切的原因,但是可以推测也是由于 MySQL 连接断开而造成的。因为这两个错误出现得很有规律,而且都是在差不多的时间间隔内出现。

解决方法

为了减少这种报错信息的出现,我们可以在 php 程序中实现自动重连,即在 MySQL 断开连接前,就自动实现重新连接或者避免再使用 mysqli_ping() 去检测。MySQL 会在什么时候断开连接,可以查看 my.ini 配置中的 wait_timeout 参数。

mysql> show global variables like "%timeout";
+-----------------------------+----------+
| Variable_name               | Value    |
|-----------------------------+----------|
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| slave_net_timeout           | 3600     |
| thread_pool_idle_timeout    | 60       |
| wait_timeout                | 1800     |
+-----------------------------+----------+

注意最后一项 wait_timeout 的值是 1800 秒,表示 MySQL 会把 30 分钟以上没有任何查询请求的连接给断开。

根据上面的阀值,我们在程序中实现自动重连。

 1800)
        {
            $start = time();
            self::$link = null;
        }
    }
}

在 PHP 程序中使用(一般会在耗时的 woker 中使用)

$start = time();

while(true)
{
    $params = Queues::get();

    DB::keepConnectionAlive($start);
    $link = DB::getLink();
    
    //...处理业务逻辑
}
参考文献

B.5.2.9 MySQL server has gone away

MySQL native driver for PHP - mysqlnd

LONG RUNNING PHP SCRIPT AND MYSQL SERVER GONE AWAY

6.1.5 Server System Variables

数据库持久连接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/47078.html

相关文章

  • MySQL Insert数据量过大导致报错 MySQL server has gone away

    摘要:直接在上执行语句,报错搜索得知当客户端或服务器收到大于字节的信息包时,将发出信息包过大错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,可能会遇到丢失与服务器的连接错误。 接手了同事的项目,其中有一个功能是保存邮件模板(包含图片),同事之前的做法是把图片进行base64编码然后存在mysql数据库中(字段类型为mediumtext)然后保存三张图片(大概400k)的...

    evin2016 评论0 收藏0
  • MySQL Insert数据量过大导致报错 MySQL server has gone away

    摘要:直接在上执行语句,报错搜索得知当客户端或服务器收到大于字节的信息包时,将发出信息包过大错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,可能会遇到丢失与服务器的连接错误。 接手了同事的项目,其中有一个功能是保存邮件模板(包含图片),同事之前的做法是把图片进行base64编码然后存在mysql数据库中(字段类型为mediumtext)然后保存三张图片(大概400k)的...

    liaoyg8023 评论0 收藏0
  • 解决PHP脚本 MySQL has gone away错误

    摘要:当使用访问数据库且脚本需要长时间执行时,频繁会遇见的错误。分析问题产生原因因为脚本较长时间未与数据库进行通信,导致数据库连接超时与服务器断开连接导致,这时使用断开的数据库连接操作数据库,就会产生的错误提示。 当PHP 使用PDO访问数据库且脚本需要长时间执行时,频繁会遇见’ MySQL server has gone away’的错误。分析问题产生原因:因为脚本较长时间未与数据库进行通...

    honhon 评论0 收藏0
  • 解决PHP脚本 MySQL has gone away错误

    摘要:当使用访问数据库且脚本需要长时间执行时,频繁会遇见的错误。分析问题产生原因因为脚本较长时间未与数据库进行通信,导致数据库连接超时与服务器断开连接导致,这时使用断开的数据库连接操作数据库,就会产生的错误提示。 当PHP 使用PDO访问数据库且脚本需要长时间执行时,频繁会遇见’ MySQL server has gone away’的错误。分析问题产生原因:因为脚本较长时间未与数据库进行通...

    Scliang 评论0 收藏0
  • MySQL错误 ERROR 2006 (HY000): MySQL server has gone

    摘要:下当我导入一个比较大的文件时出现了错误,具体情况如下上面可以看到,文件大小为导入的时候会报这个错误。错误原因我们通过相关文档可以发现默认大小是。 MySQL下当我导入一个比较大的SQL文件时出现了ERROR 2006 (HY000): MySQL server has gone away错误,具体情况如下: > ll *.sql -rwxr-xr-x@ 1 bohan staff...

    Alfred 评论0 收藏0

发表评论

0条评论

n7then

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<