解决“MySQL server has gone away"问题错误

2022-01-24 00:00:00 connection php mysql phpmyadmin

我用 PHP 编写了一些代码,这些代码从 .edu 域返回 html 内容.这里简单介绍一下:关于PHP中Web Crawler的错误

I have written some code in PHP that returns the html content from .edu domains. A brief introduction is given here: Errors regarding Web Crawler in PHP

当要抓取的链接数量很少(大约 40 个 URL)时,抓取工具可以正常工作,但在此数字之后出现MySQL 服务器已消失"错误.

The crawler works fine when the number of links to crawl are small (something around 40 URLS) but I am getting "MySQL server has gone away" error after this number.

我将 html 内容作为长文本存储在 MySQL 表中,但我不明白为什么在至少 40-50 次插入后出现错误.

I am storing html content as longtext in MySQL tables and I am not getting why the error arrives after at least 40-50 insertions.

非常感谢您在这方面的任何帮助.

Any help in this regard is highly appreciated.

请注意,我已经更改了 wait_timeout 和 max_allowed_pa​​cket 以适应我的查询和 php 代码,现在我不知道该怎么做.请在这方面帮助我.

Please note that I have already altered the wait_timeout and max_allowed_packet to accomodate my queries and the php code and now I don't know what to do. Please help me in this regard.

推荐答案

您可能倾向于通过在查询之前ping"mysql 服务器来处理这个问题.这是一个坏主意.有关原因的更多信息,请查看此 SO 帖子:我应该先 ping mysql 服务器吗每个查询?

You might be inclined to handle this problem by "pinging" the mysql server before a query. This is a bad idea. For more on why, check this SO post: Should I ping mysql server before each query?

处理该问题的最佳方法是将查询包装在 try/catch 块中并捕获任何数据库异常,以便您可以适当地处理它们.这在长时间运行和/或守护程序类型的脚本中尤其重要.因此,这是一个非常基本的示例,使用连接管理器"来控制对数据库连接的访问​​:

The best way to handle the issue is by wrapping queries inside try/catch blocks and catching any database exceptions so that you can handle them appropriately. This is especially important in long running and/or daemon type scripts. So, here's a very basic example using a "connection manager" to control access to DB connections:

class DbPool {

    private $connections = array();

    function addConnection($id, $dsn) {
        $this->connections[$id] = array(
            'dsn' => $dsn,
            'conn' => null
        );
    }

    function getConnection($id) {
        if (!isset($this->connections[$id])) {
            throw new Exception('Invalid DB connection requested');
        } elseif (isset($this->connections[$id]['conn'])) {
            return $this->connections[$id]['conn'];
        } else {
            try {
                // for mysql you need to supply user/pass as well
                $conn = new PDO($dsn);

                // Tell PDO to throw an exception on error
                // (like "MySQL server has gone away")
                $conn->setAttribute(
                    PDO::ATTR_ERRMODE,
                    PDO::ERRMODE_EXCEPTION
                );
                $this->connections[$id]['conn'] = $conn;

                return $conn;
            } catch (PDOException $e) {
                return false;
            }
        }
    }

    function close($id) {
        if (!isset($this->connections[$id])) {
            throw new Exception('Invalid DB connection requested');
        }
        $this->connections[$id]['conn'] = null;
    }


}


class Crawler {

    private $dbPool;

    function __construct(DbPool $dbPool) {
        $this->dbPool = $dbPool;
    }

    function crawl() {
        // craw and store data in $crawledData variable
        $this->save($crawledData);
    }

    function saveData($crawledData) {
        if (!$conn = $this->dbPool->getConnection('write_conn') {
            // doh! couldn't retrieve DB connection ... handle it
        } else {
            try {
                // perform query on the $conn database connection
            } catch (Exception $e) {
                $msg = $e->getMessage();
                if (strstr($msg, 'MySQL server has gone away') {
                    $this->dbPool->close('write_conn');
                    $this->saveData($val);
                } else {
                    // some other error occurred
                }
            }
        }
    }
}

相关文章