如何解决一般错误:2006 MySQL server has gone away

Posted

技术标签:

【中文标题】如何解决一般错误:2006 MySQL server has gone away【英文标题】:How to solve General error: 2006 MySQL server has gone away 【发布时间】:2016-01-19 22:15:18 【问题描述】:

我正在执行将数百条记录插入 mysql 数据库的操作。

准确插入 176 条记录后,我收到此错误:

[PDOException] SQLSTATE[HY000]: 一般错误:2006 MySQL server has gone away

关于如何解决它的任何想法?

这个过程是用php的。

【问题讨论】:

您在共享服务器上吗? 是的。去吧爸爸。有关系吗? 可能。 WebHostingHub 经常遇到同样的问题。我还没有运气弄清楚“为什么”。如果您发布您的代码,可能更容易告诉what might be going on. 查看您帖子“相关”下的顶部链接(获得 58 票)。 The post 只是为了好奇你能运行这个:SHOW VARIABLES LIKE '%timeout%'; 【参考方案1】:

我敢说问题出在wait_timeout。在我的共享主机上设置为 30 秒,在我的本地主机上设置为 28800。

我发现我可以为会话更改它,因此您可以发出查询:SET session wait_timeout=28800

更新 OP 确定他还需要更改变量interactive_timeout。每个人都可能需要也可能不需要。

下面的代码显示了更改前后的设置,以验证是否已更改。

所以,在查询开始时设置 wait_timeout=28800(和 interactive_timeout = 28800),看看它是否完成。

记得插入你自己的数据库凭证来代替DB_SERVER, DB_USER, DB_PASS, DB_NAME

更新另外,如果这确实有效,您希望通过将 wait_timeout 设置得更高来清楚自己在做什么。将它设置为 28800 是 8 小时,而且很多。

以下来自this site。它建议将 wait_timeout 设置为 300 - 我会尝试并报告我的结果(几周后)。

wait_timeout 变量表示 MySQL 将等待的时间量 在杀死空闲连接之前等待。默认的wait_timeout 变量为 28800 秒,即 8 小时。太多了。

我在不同的论坛/博客中看到将 wait_timeout 设置得太低 (例如 30、60、90)可能会导致 MySQL has away 错误消息。所以 你必须决定你的配置。

<?php

$db = new db();

$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";

$results = $db->query("SET session wait_timeout=28800", FALSE);
// UPDATE - this is also needed
$results = $db->query("SET session interactive_timeout=28800", FALSE);

$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";


class db 

    public $mysqli;

    public function __construct() 
        $this->mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
        if (mysqli_connect_errno()) 
            exit();
        
    

    public function __destruct() 
        $this->disconnect();
        unset($this->mysqli);
    

    public function disconnect() 
        $this->mysqli->close();
    

    function query($q, $resultset) 

        /* create a prepared statement */
        if (!($stmt = $this->mysqli->prepare($q))) 
            echo("Sql Error: " . $q . ' Sql error #: ' . $this->mysqli->errno . ' - ' . $this->mysqli->error);
            return false;
        

        /* execute query */
        $stmt->execute();

        if ($stmt->errno) 
            echo("Sql Error: " . $q . ' Sql error #: ' . $stmt->errno . ' - ' . $stmt->error);
            return false;
        
        if ($resultset) 
            $result = $stmt->get_result();
            for ($set = array(); $row = $result->fetch_assoc();) 
            $set[] = $row;
            
            $stmt->close();
            return $set;
        
    

【讨论】:

它在 WebHostingHub 上确实如此,它们似乎是等价的。我必须说我很惊讶它起作用了。 它对我不起作用。将不得不尝试别的东西。还是谢谢。 是没有改变wait_timeout还是改变了wait_timeout但是2006的错误还是发生了? 我能够将当前事务中的 wait_timeout 设置为 28800,但该过程仍然失败。我想知道这是否与另一个值有关。 添加了评论@mseifert。我接受了你的帖子作为有效答案,因为你给了我解决这个问题的想法和部分解决方案。谢谢!【参考方案2】:

谢谢@mseifert。

你的想法是通过对两个变量做同样的事情来实现的。

interactive_timeout & wait_timeout

我从本地数据库复制了配置:

SHOW VARIABLES LIKE  '%timeout%'

本地数据库:

远程数据库:

我在连接和断开连接中做了这个并且工作:

mysql_query("SET SESSION interactive_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'interactive_timeout';");
$row = mysql_fetch_array($result);
$interactive_timeout = $row["Value"];
echo("interactive_timeout" . " = " . $interactive_timeout . "\n");

mysql_query("SET SESSION wait_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'wait_timeout';");
$row = mysql_fetch_array($result);
$wait_timeout = $row["Value"];
echo("wait_timeout" . " = " . $wait_timeout . "\n");

令人惊讶的是,它与 GoDaddy 合作。

我会接受你的回答为有效的@mseifert,因为你给了我最初的想法。

非常感谢。

让我们希望这对其他开发人员将来解决 2006 MySQL 错误有用。

【讨论】:

这很有趣。我读到 interactive_timeout 用于 mysql shell 会话,如 mysqldump 或 mysql 命令行工具。无论如何,在解决问题方面做得很好。我将更新我的答案以包含此信息,因为您已将其设为已接受的答案。 对了,我还要补充一点。我所做的大量 sql 插入可以通过 Web 浏览器通过 REST API 调用,也可以通过控制台 - 命令行调用。也许这就是我必须添加这两个选项的原因。【参考方案3】:

就我而言,当我在客户端收到此错误时,服务器端是

(Got a packet bigger than 'max_allowed_packet' bytes)

所以我增加了 max_allowed_pa​​cket 的值,到目前为止,没有更多问题。

在 Google Cloud Platform 上,我编辑数据库并添加一个数据库标志并将值设置为 max_allowed_pa​​cket=134217728

(即 2^27 = 128M)

因为你只能输入数字。

在常规情况下,您可以在此处关注文档:

https://dev.mysql.com/doc/refman/8.0/en/packet-too-large.html

【讨论】:

【参考方案4】:

假设您的代码是:

// your codes
$pdo = db::connection()->getPdo();
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);

所以在你的 sql 查询之前添加以下代码:

$pdo = db::connection()->getPdo();

// Increase interactive_timeout
$prepend_sql = "SET SESSION interactive_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);

// Increase wait_timeout 
$prepend_sql = "SET SESSION wait_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);

// your codes
/* $pdo = db::connection()->getPdo(); */
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);

【讨论】:

$params?那是错误的。你没有在那里绑定任何东西!【参考方案5】:

另一个可能的原因是您的客户端正在尝试使用 SSL 进行连接。而 MySQL/MariaDB 服务器并没有预料到这一点。

【讨论】:

以上是关于如何解决一般错误:2006 MySQL server has gone away的主要内容,如果未能解决你的问题,请参考以下文章

MAMP ";#2006的解决方案-MySQL服务器已消失";错误

[故障解决]Mysql爆出ERROR 2006 (HY000): MySQL server has gone away的错误怎么办?

解决MySQL报错:ERROR 2006 (HY000): MySQL server has gone away No connection(图文并茂)

解决MySQL报错:ERROR 2006 (HY000): MySQL server has gone away No connection(图文并茂)

ThinkPHP出现General error: 2006 MySQL server has gone away的解决方法

MySQL导入sql脚本错误:2006 - MySQL server has gone away