MySQL server has gone away报错原因分析

之前在测试thinkPHP框架各种插入数据方式的遇到了 MySQL server has gone away 的错误,如图:

代码如下:

<?php
namespace app\index\controller;

use think\Db;

class Index
{
    public function test2()
    {
        set_time_limit(0);   //防止超300s 500错误

        ini_set('memory_limit','1024M');

        $t1 = microtime(true);

        //插入20万条数据
        for ($i=1; $i<=200000; $i++){
            $data[$i] = ['value' => uniqid().$i];
        }
        //程序运行时间
        $t2 = microtime(true);

        echo '循环耗时:'.round($t2-$t1,3).'秒<br>';

        Db::name('myisam')->insertAll($data);

        $t3 = microtime(true);

        echo '插入耗时:'.round($t3-$t2,3).'秒<br>';

        echo '内存消耗:'.round(memory_get_usage()/1048576,2)." M<br/>";
    }
}

那哪些原因有可能导致 MySQL server has gone away 这个错误呢?


一、MySQL服务本身挂掉了


这一点可以直接排除,因为其他的MySQL连接没有问题,也可以再确认一下

show global status like 'uptime';

可以看到uptime值为23926秒,MySQL已经连续运行六个多小时,所以排除此项


二、MySQL连接超时


即某个mysql长连接很久没有新的请求发起,达到了server端的timeout,被server强行关闭。此后再通过这个connection发起查询的时候,就会报错MySQL server has gone away(大部分PHP脚本就是属于此类)

连接MySQL查看一下相关参数

show global variables like '%timeout';

部分参数解释:

connect_timeout
  连接响应超时时间。服务器端在这个时间内如未连接成功,则会返回连接失败

wait_timeout
  连接空闲超时时间。与服务器端非交互状态的连接,直到被服务器端强制关闭而等待的时间
  可以认为是服务器端连接空闲的时间,空闲超过这个时间将自动关闭

interactive_timeout
  连接空闲超时时间。与服务器端交互状态的连接,直到被服务器端强制关闭而等待的时间

interactive_timeoutwait_timeoutu两者差异
  interactive_timeout针对交互式连接(比如通过mysql客户端连接数据库)
  wait_timeout针对非交互式连接(比如一般在PHP中使用PDO连接数据库,当然你可以设置CLIENT_INTERACTIVE选项来改变)
  所谓的交互式连接,就是在mysql_real_connect()函数中使用了CLIENT_INTERACTIVE选项

net_read_timeout
  数据读取超时时间。在终止读之前,从一个连接获得数据而等待的时间秒数
  当服务正在从客户端读取数据时,net_read_timeout控制何时超时
  即客户端执行数据读取,等待多少秒仍未执行成功时自动断开连接

net_write_timeout
  数据库写超时时间。和net_read_timeout意义类似,在终止写之前,等待多少秒把block写到连接
  当服务正在写数据到客户端时,net_write_timeout控制何时超时

connect_timeout:在获取连接阶段起作用
interactive_timeoutwait_timeout:在连接空闲阶段起作用
net_read_timeoutnet_write_timeout:则是在连接执行时起作用

这里因为我们用的是PDO连接,所以相关的参数就是wait_timeout,其值为28800秒,上面的程序在刚连接到数据库的时候就报错了,并且在数据量较小的时候可以成功执行,显然不存在等待超时,所以问题不在这


三、SQL语句内容过大


我们先来查看一下相关参数:

show global variables like 'max_allowed_packet'; //接受的最大数据包大小

默认值 1018576,也就是1M,我们来临时修改一下,改为100M

set global max_allowed_packet=1024*1024*100;

如果需要永久修改,需要到MySQL的配置文件里进行修改

修改完以后,我们来重新执行一下我们程序,程序已经可以顺利进行

问题找到,关于MySQL server has gone away 的问题差不多也就这些了

飞行猿博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论