【问题标题】:Better way to keep mysql connection alive other than pinging除了 ping 之外,保持 mysql 连接处于活动状态的更好方法
【发布时间】:2016-07-21 19:31:16
【问题描述】:

我确信很多开发人员都遇到了可怕的“Mysql 已消失”问题,尤其是在处理长时间运行的脚本时,例如为后台或 cron 作业保留的脚本。这是由于 mysql 和 php 之间的连接断开造成的。防止这种情况发生的最佳方法究竟是什么?

我目前直接使用自定义 CDbConnection 类和 setActive 方法:

http://www.yiiframework.com/forum/index.php/topic/20063-general-error-2006-mysql-server-has-gone-away/page__p__254495#entry254495

这很有效,并阻止了我的 MySQL 消失问题。不幸的是,我遇到了一个非常随机的问题,在通过 CActiveRecord 向数据库插入新记录后,yii 无法正确设置主键值。你最终的 pk 值为 0。我更深入地研究了这个问题,最终能够在我的本地机器上重现它。似乎我的自定义 CDbConnection::setActive() 方法可能是罪魁祸首。当你运行 CActiveRecord::save() 方法时,yii 准备好必要的 sql 并通过 PDO 执行它。紧接着,yii 使用 PDO::lastInsertId() 获取最新插入的 ID 并填充您的模型 PK 属性。但是,如果出于某种原因,初始插入命令需要几秒钟以上才能完成,会发生什么?这会在我的自定义 setActive() 方法中触发 mysql ping 操作,该方法只等待当前时间戳和最后一个活动时间戳之间的 2 秒差异。我注意到,当您执行 PDO 插入查询,然后执行 PDO 选择查询,最后执行 PDO::lastInsertId() 时,最后的插入 id 值为 0。

我不能确定这是否是我们的实时服务器上发生的问题,随机发生的问题,但这是我能够重现它的唯一方法。

【问题讨论】:

    标签: php mysql pdo yii


    【解决方案1】:

    Server Has Gone Away 错误实际上有很多原因,MySQL 文档中有详细记录。几个常见的尝试技巧是:

    • 增加 my.cnf 文件中的wait_timeout。如果您的锁需要保持锁定更长的时间,另请参阅 innodb_lock_wait_timeoutlock_wait_timeout

      服务器在关闭非交互式连接之前等待其活动的秒数。

    • 在您的 my.cnf 文件中增加 max_allowed_packet。大数据包可能会使连接中断并导致它突然关闭。

      如果您使用大型 BLOB 列或长字符串,则必须增加此值。它应该与您要使用的最大 BLOB 一样大。 max_allowed_pa​​cket 的协议限制为 1GB。该值应为 1024 的倍数;非倍数向下舍入到最接近的倍数。

    【讨论】:

    • 如果我有一个无限期运行的脚本,wait_timeout 选项是否有帮助?我有一个永远运行的 beanstalkd 进程,只是等待作业保留和处理。我相信这是我第一次遇到这个问题的地方,我的框架(yii)会尝试做一些数据库操作,只是为了让它们由于连接断开而随机失败
    • 是的,但它不能设置为无限。要解决该问题,您的进程应定期断开连接并重新连接。
    猜你喜欢
    • 2013-03-20
    • 2014-06-17
    • 2012-01-03
    • 2021-09-13
    • 2013-08-27
    • 2019-09-01
    • 1970-01-01
    • 2014-11-16
    相关资源
    最近更新 更多