繁体   English   中英

PHP警告:在MySQL转储到macOS终端后,“MySQL服务器已经消失”

[英]PHP Warning: “MySQL server has gone away” after MySQL dump in macOS Terminal

我使用CLI的PHP脚本下载远程MySQL数据库(gzip)并将它们直接提取到我的MacBook的MySQL 5.7(不是MAMP)服务器。 它工作正常,但作为副作用,我的PHP应用程序(MAMP Pro)在CLI脚本中间丢失了MySQL连接并带有警告

PHP Warning:  mysqli::__construct(): MySQL server has gone away in ...

这种情况发生在十几个数据库(无法重现确切数量)之后。 在CLI脚本运行时,系统首选项中的MySQL窗格从每次CLI转储后的绿色/运行变为红色/停止再次变为绿色/运行,这首先与浏览器中的PHP应用程序不冲突。 但在某些时候,PHP应用程序显然失去了连接。

我和my.cnf一起玩了

[mysqld]
max_allowed_packet=128M
max_connections=1024

或其他金额,但似乎没有任何改变。

当CLI脚本完成后,我在“系统偏好设置”中手动停止并启动MySQL时,PHP将继续正常工作。

有任何想法吗?

编辑:

谢谢到目前为止,但它仍然没有修复。 所以这是主要的脚本:

$tmpPath = '/tmp/'

For each of 30 databases with different size:

$dbName = database name

exec('ssh user@server.com "mysqldump --login-path=local --lock-tables=false '.$dbName.' | gzip" > '.$tmpPath.$dbName.'.sql.gz');
exec('gzip -q -dc '.$tmpPath.$dbName.'.sql.gz | mysql -u root -proot '.$dbName)

就像我说的,终端中的PHP CLI脚本根本不会抱怨! 这是我的PHP 应用程序 (Angular前端应用程序的后端),由于上述错误,30个转储中间某处停止工作。

我有类似的问题,并通过在mysql.conf中添加max_connections = 1024来修复

我们遇到了类似的问题,并使用了这个问题,如果连接消失,它会重新连接:

<?php

use Exception;
use PDO;
use Our\Package\Common\Config\DbCredentials;

class DbConnectionManager
{
    private $credentials;

    /** @var PDO $connection */
    private $connection;

    /**
     * DbConnectionManager constructor.
     * @param DbCredentials $credentials
     */
    public function __construct(DbCredentials $credentials)
    {
        $this->credentials = $credentials;
        $this->reconnect();
    }

    /**
     * @return PDO
     */
    public function getConnection()
    {
        if (!$this->isConnected()) {
            $this->reconnect();
        }
        return $this->connection;
    }

    /**
     * @return bool
     */
    private function isConnected()
    {
        try {
            return $this->connection->query('SELECT 1 + 1;');
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     *  Reinitialise the connection to MySQL
     */
    private function reconnect()
    {
        $dsn = $this->credentials->getDriver()
            .':host='.$this->credentials->getHost()
            .';port='.$this->credentials->getPort()
            .';dbname='.$this->credentials->getDbName()
        ;
        $connection = new PDO($dsn, $this->credentials->getUser(), $this->credentials->getPassword(), array(
            PDO::ATTR_TIMEOUT => 28800,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        ));
        $this->connection = $connection;
    }
}

你可以调整一下。 DBCredentials类只是一个普通的PHP类,包含驱动程序,主机名,用户,密码,数据库名称的getter和setter,如果您愿意,可以将其更改为仅将参数作为字符串。

如果向服务器发送不正确或太大的查询,也可能会出现这些错误。 如果mysqld获取的数据包太大 或者不按顺序,它假定客户端出现问题并关闭连接。

要避免此问题,必须确保mysqld服务器中的max_allowed_pa​​cket设置得比客户端大,并且所有客户端都使用相同的max_allowed_pa​​cket值。 并记得在那之后重新启动服务器!!!!

创建mysqldump时,锁定表。 我认为这是主要问题,这就是为什么你的应用程序出错了。 使用此选项:

--lock-tables, -l

Lock all tables before dumping them. The tables are locked with READ
LOCAL to allow concurrent inserts in the case of MyISAM tables. For
transactional tables such as InnoDB and BDB, --single-transaction is
a much better option, because it does not need to lock the tables at
all.

原来的答案在这里:

运行MySQLDump而不锁定表

并尝试用户在转储命令之间“睡眠”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM