PHP 警告:在 macOS 终端中 MySQL 转储后“MySQL 服务器已消失”
Posted
技术标签:
【中文标题】PHP 警告:在 macOS 终端中 MySQL 转储后“MySQL 服务器已消失”【英文标题】:PHP Warning: "MySQL server has gone away" after MySQL dump in macOS Terminal 【发布时间】:2018-02-13 15:08:49 【问题描述】:我使用 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 个转储中间的某处停止工作。
【问题讨论】:
SHOW GLOBAL VARIABLES LIKE '%timeout%';
和 SHOW SESSION VARIABLES LIKE '%timeout%';
同时我发现系统偏好设置中的 MySQL 变红了,所以在每次数据库转储后停止半秒,然后立即重新启动。
@RickJames 你能给我另一个提示你的评论是什么意思吗?我玩过可变超时设置,但没有帮助。
尝试偶尔使用 mysqli_ping() ping mysql 服务器
@rndus2r 我一直在运行 PHP MySQL 脚本,直到连接丢失并且脚本失败。所以无论如何都要检查与 MySQL 服务器的连接。
【参考方案1】:
我有类似的问题,只需在 mysql.conf 中添加 max_connections = 1024 即可解决
【讨论】:
【参考方案2】:我们遇到了类似的问题,并使用了这个,如果连接消失,它会重新连接:
<?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,如果您愿意,您可以将其更改为仅将参数作为字符串。
【讨论】:
【参考方案3】:如果您向服务器发送查询,您也可能会收到这些错误 不正确或太大。如果 mysqld 收到一个太大的数据包。 或乱序,它假定某些地方出了问题 客户端并关闭连接。
为避免此问题,您必须确保 mysqld 服务器中的 max_allowed_packet 设置大于客户端中的 max_allowed_packet,并且所有客户端都使用相同的 max_allowed_packet 值。 并且记得在那之后重新启动你的服务器!!!!
【讨论】:
请添加指向您的引用/参考来源的链接(黄色块引用文本是从某处复制的吗?)。【参考方案4】:当您创建 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.
这里的原始答案:
Run MySQLDump without Locking Tables
并尝试用户在转储命令之间“休眠”。
【讨论】:
据我了解,--lock-tables
仅防止实时(源)数据库在转储时未锁定。但是在本地我不使用mysqldump
,而是gzip
使用gzip -q -dc '.$tmpPath.$dbName.'.sql.gz | mysql -u root -proot '.$dbName
直接解压到mysql
哇。对不起。您的本地数据库崩溃。我以为服务器崩溃了。在这种情况下,请尝试“睡眠”选项,以便在导入时在本地完成索引,然后尝试 wait_timeout=30000以上是关于PHP 警告:在 macOS 终端中 MySQL 转储后“MySQL 服务器已消失”的主要内容,如果未能解决你的问题,请参考以下文章