首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >E_WARNING:发送STMT_PREPARE数据包时出错。PID=*

E_WARNING:发送STMT_PREPARE数据包时出错。PID=*
EN

Stack Overflow用户
提问于 2018-11-25 17:02:53
回答 4查看 3.1K关注 0票数 12

我的Laravel5.7网站经历了一些问题,我认为这些问题是相互关联的(但发生在不同的时间):

  1. PDO::prepare(): MySQL server has gone away
  2. E_WARNING: Error while sending STMT_PREPARE packet. PID=10
  3. PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry (我的数据库似乎经常尝试在同一秒钟内写两次相同的记录。我一直无法弄清楚为什么或如何复制它;它似乎与用户行为无关。)
  4. 不知何故,前2种错误只出现在我的Rollbar日志中,而不是出现在服务器上的文本日志或我的Slack通知中,正如所有错误都应该出现的那样(所有其他错误都会出现)。

几个月来,我一直看到这样可怕的日志消息,我完全无法复制这些错误(并且无法诊断和解决它们)。

我还没有发现任何实际的症状,也没有从用户那里听到任何抱怨,但是错误信息似乎并不微不足道,所以我真的很想了解和解决问题的根源。

我尝试过将我的MySQL配置更改为使用max_allowed_packet=300M (而不是400万的默认设置 ),但是当我有超过几个访问者访问我的站点的时候,仍然经常会遇到这些异常。

我还设置了(从5M到10M),因为这个建议

代码语言:javascript
运行
复制
innodb_buffer_pool_chunk_size=218M
innodb_buffer_pool_size = 218M

作为进一步的背景:

  • 我的站点有一个运行作业(artisan queue:work --sleep=3 --tries=3 --daemon)的队列工作者。
  • 根据访问者的注册时间,可以在同一时间安排一组排队的作业。但我所看到的最多的同时发生的是20。
  • MySQL慢速查询日志中没有条目。
  • 我有几份工作,但我怀疑它们是有问题的。每分钟跑一次,但很简单。另一个每5分钟运行一次,发送某些预定的电子邮件(如果有的话)。另一个每30分钟运行一次报告。
  • 我运行过各种mysqlslap查询(不过,我完全是新手),甚至在模拟数百个并发客户端时,我也没有发现任何慢的地方。
  • 我用的是拉拉多克(码头)。
  • 我的服务器是DigitalOcean 1GB内存,1 vCPU,25 1GB。我也尝试过2GB内存,没有差别。
  • SHOW VARIABLES;SHOW GLOBAL STATUS; 在这里的结果。

我的my.cnf是:

代码语言:javascript
运行
复制
[mysql]

[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
character-set-server=utf8
innodb_buffer_pool_chunk_size=218M
innodb_buffer_pool_size = 218M
max_allowed_packet=300M
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow_query_log.log
long_query_time = 10
log_queries_not_using_indexes = 0

对于我应该探索什么来诊断和解决这些问题有什么想法吗?谢谢。

EN

Stack Overflow用户

发布于 2019-04-02 08:05:21

我在一个长期运行的PHP脚本上遇到了同样的情况(它在Redis列表上侦听;每个动作都是快速的,但脚本基本上永远运行)。

我在开始时创建PDO对象和一个准备好的语句,然后再使用它们。

在我开始脚本的第二天,我得到了完全相同的错误:

代码语言:javascript
运行
复制
PHP Warning:  Error while sending STMT_EXECUTE packet. PID=9438 in /...redacted.../myscript.php on line 39

SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

在我的例子中,它是一个开发服务器,没有负载,MySQL在同一个盒子上.因此,这不太可能来自外部因素。这很可能与我使用同一个MySQL连接太久而超时有关。而且PDO也不麻烦,因此任何后续查询都将返回"MySQL服务器已经消失“。

在wait_timeout中检查“MySQL”的值:

代码语言:javascript
运行
复制
mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.06 sec)

mysql> show local variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

我看到28800秒=8小时,这似乎与我的错误时间一致。

在我的例子中,重新启动MySQL服务器,或者将wait_timeout设置得很低,同时保持相同的PHP运行,使得重现问题变得非常容易。

总体而言:

  • PDO不在乎连接是否超时,也不会自动重新连接。如果您在PDO查询周围放置了try/catch,脚本就不会崩溃,并且会继续使用过时的PDO实例。
  • STMT_EXECUTE警告可能是附带的;仅仅因为连接超时的脚本使用准备好的语句,而第一个查询后超时恰好使用了准备好的语句。

回到你的案子

  • 从理论上讲,Laravel 5不受这个问题的影响:准备-错误/;您使用的不是照明,甚至是直接使用光的PDO吗?另外,我不确定Laravel在检测到丢失的连接时会做什么(它是否重新连接和重建准备好的语句?),它可能值得进一步挖掘。
  • 检查您的MySQL wait_timeout值,如果它太低,就增加它
  • 如果它不是一直都在发生,那么看看这些错误是否与服务器/ DB负载相关。高负载可以使事情(特别是大型SQL查询)慢几倍,到了达到其他一些MySQL超时(比如max_execution_time )的程度。
  • 查看是否将PDO查询包装在try / catch块中,并使用它重试查询;这可能会防止连接错误冒泡。
票数 2
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53469793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档