简体   繁体   中英

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. This is caused by the connection between mysql and php being dropped. 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:

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. 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. 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. It seems like my custom CDbConnection::setActive() method might be the culprit. When you run the CActiveRecord::save() method, yii prepares the necessary sql and executes it via PDO. Immediately after this, yii uses PDO::lastInsertId() to grab the latest inserted ID and populates your models PK attribute. 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. 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.

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. A couple common tricks to try are:

  • Increase the wait_timeout in your my.cnf file. See also innodb_lock_wait_timeout and lock_wait_timeout if your locks need to remain locked for a longer period of time.

    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. 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. It should be as big as the largest BLOB you want to use. The protocol limit for max_allowed_packet is 1GB. The value should be a multiple of 1024; nonmultiples are rounded down to the nearest multiple.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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