解决“MySQL服务器已经消失”错误

2022-08-30 23:29:50

我已经用PHP编写了一些代码,从.edu域返回html内容。这里给出了一个简短的介绍:PHP中关于Web爬虫的错误

当要抓取的链接数量很少(大约40个URLS)时,爬虫工作正常,但是在此数字之后我收到“MySQL服务器已消失”错误。

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

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

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


答案 1

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

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

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
                }
            }
        }
    }
}

答案 2

我有另一个答案来处理我认为是类似的问题,它需要一个类似的答案。基本上,您可以使用mysql_ping()函数在插入之前测试连接。在MySQL 5.0.14之前,会自动重新连接服务器,但现在你必须构建自己的重新连接逻辑。与此类似的内容应该适合您:mysql_ping()

function check_dbconn($connection) {
    if (!mysql_ping($connection)) {
        mysql_close($connection);
        $connection = mysql_connect('server', 'username', 'password');
        mysql_select_db('db',$connection);
    } 
    return $connection;
}

foreach($array as $value) {
    $dbconn = check_dbconn($dbconn);
    $sql="insert into collected values('".$value."')";
    $res=mysql_query($sql, $dbconn);
    //then some extra code.
}

推荐