简体   繁体   English

除了ping之外,保持mysql连接存活的更好方法

[英]Better way to keep mysql connection alive other than pinging

I'm sure a lot of developers have run into the dreaded "Mysql has gone away" issue, especially when dealing with long running scripts such as those reserved for background or cron jobs. 我确信很多开发人员都遇到了可怕的“ Mysql走开”问题,尤其是在处理长时间运行的脚本(例如为后台或cron作业保留的脚本)时。 This is caused by the connection between mysql and php being dropped. 这是由于mysql和php之间的连接被删除引起的。 What exactly is the best way to prevent that from happening? 防止这种情况发生的最佳方法到底是什么?

I currently use a custom CDbConnection class with a setActive method straight out of here: 我目前在这里直接使用带有setActive方法的自定义CDbConnection类:

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

This worked great and has stopped my MySQL gone away issue. 这很好用,并且阻止了我的MySQL消失问题。 Unfortunately, I've been running into a really random issue where after inserting a new record to the database via CActiveRecord, yii fails to set the primary key value properly. 不幸的是,我一直遇到一个随机的问题,即在通过CActiveRecord将新记录插入数据库后,yii无法正确设置主键值。 You end up with a pk value of 0. I looked into the issue more deeply and was finally able to reproduce it on my local machine. 您最终得到的pk值为0。我更深入地研究了该问题,最终能够在我的本地计算机上重现该问题。 It seems like my custom CDbConnection::setActive() method might be the culprit. 似乎我的自定义CDbConnection :: setActive()方法可能是罪魁祸首。 When you run the CActiveRecord::save() method, yii prepares the necessary sql and executes it via PDO. 当您运行CActiveRecord :: save()方法时,yii准备必要的sql并通过PDO执行它。 Immediately after this, yii uses PDO::lastInsertId() to grab the latest inserted ID and populates your models PK attribute. 此后,yii立即使用PDO :: lastInsertId()获取最新插入的ID,并填充模型PK属性。 What happens though if for whatever reason, the initial insert command takes more than a few seconds to complete? 但是,如果由于某种原因,初始插入命令需要花费几秒钟以上的时间才能完成? This triggers the mysql ping action in my custom setActive() method, which only waits for a 2 second difference between the current timestamp and the last active timestamp. 这将触发我的自定义setActive()方法中的mysql ping操作,该方法仅等待当前时间戳和最后一个活动时间戳之间的2秒差异。 I noticed that when you do a PDO insert query, followed by a PDO select query, then finally the PDO::lastInsertId(), you end up with a last insert id value of 0. 我注意到,当您执行PDO插入查询,然后执行PDO选择查询,最后执行PDO :: lastInsertId()时,最后插入的ID值为0。

I can't say for certain if this is what's happening on our live servers where the issue randomly occurs but it's been the only way I have been able to reproduce it. 我不能确定这是否是发生在随机出现问题的实时服务器上的情况,但这是我能够重现此问题的唯一方法。

There are actually many reasons for the Server Has Gone Away error, which are well documented in the MySQL Documentation. 实际上, Server Has Gone Away原因有很多,在MySQL文档中Server Has Gone Away对此进行了充分说明。 A couple common tricks to try are: 几个常见的技巧可以尝试:

  • Increase the wait_timeout in your my.cnf file. 增加my.cnf文件中的wait_timeout See also innodb_lock_wait_timeout and lock_wait_timeout if your locks need to remain locked for a longer period of time. 如果您的锁需要保持较长时间,请参见innodb_lock_wait_timeoutlock_wait_timeout

    The number of seconds the server waits for activity on a noninteractive connection before closing it. 服务器在关闭非交互式连接之前等待活动的秒数。

  • Increase max_allowed_packet in your my.cnf file. 增加my.cnf文件中的max_allowed_pa​​cket Large data packets can trip up the connection and cause it to be closed abruptly. 大型数据包可能会使连接断开,并导致其突然关闭。

    You must increase this value if you are using large BLOB columns or long strings. 如果使用大的BLOB列或长字符串,则必须增加此值。 It should be as big as the largest BLOB you want to use. 它应该与要使用的最大BLOB一样大。 The protocol limit for max_allowed_packet is 1GB. max_allowed_pa​​cket的协议限制为1GB。 The value should be a multiple of 1024; 该值应为1024的倍数; nonmultiples are rounded down to the nearest multiple. 非整数将四舍五入到最接近的倍数。

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

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