i’m using Yii 116 with the following application/workflow:
creating an DB conncetion
some php code
executing one SQL Statement with $res=$con->createCommand($sql)->queryAll(); and processing the results
some php code
executing next SQL Statement, wehere $sql changed followed by: $res=$con->createCommand($sql)->queryAll();
creating some forks in an loop (for multi threaded PHP Processing)
-> $npid = pcntl_fork();
inside every fork fork:
** some php code
** calling $this->getData($con) (to bring the connection-information inside the method getData
** some php code
** end of process-child
*end of mother-process
The method $this->getData($con) works like that:
*$sql="<my sql statement>";
$res=$con->createCommand($sql)->queryAll();
processing $res and finish with
return $result
That script works in 1 of 5 cases. In 4 runs, the script ends with the error "General error: 2006 MySQL server has gone away".
Without calling the method $this->getData($con), the scripts runs fine. It looks like there are an problem with using the DB connection inside the forked process!?
Is it possible, that one fork ends this DB connection, while the other fork isn’t finish and still needs this connection?
Finlay i changed localhost into 127.0.0.1 in order to come to the same result as some users before:
Changing wouldn’t be the right way, because the defaults values are much higher than the application-runtime.
The current value of wait_timeout is the default value with 8 hours, same as connect_timeout: default value with 5 seconds. The application needs less than 2 seconds until finished.
So what else could it be?
How to solve? Is persistent connection the right idea??
//Edit Maybe the error rises in context with "applications that fork child processes"
If I have an connection created in that way: $con=Yii::app()->db;
How can I ad an 2nd connection for an forked child process? Is "$con2=Yii::app()->db;" sufficient or my i have to create an new DB definition at the main.php? (an DBx)
Anyone getting "MySQL server has gone away (error 2006)" with YII should try this.
For me, doing a large file upload and parsing thousands of files on GoDaddy (or other multi-tenant host) the connection was getting dropped. GoDaddy does not provide access to the globals in MySQL to increase timeouts, etc… which really isn’t a good solution anyway. The proper way of handling these issues and for handling transient errors on cloud hosted MySQL instances is to do automatic retries. This little script worked perfect, thanks a ton for sharing, I hope other’s get some use out of it too.
Anyone know how to properly simulate the Gone Away error? I tried setting a low wait_timeout and manually killing the connection made by PHP but these result in a different error (Error while sending QUERY packet) that does not trigger an exception, meaning this script won’t help in that situation if the $autoReconnect value is higher than when the timeout occurs.
EDIT:
Oh ok, so I can get that exception error to occur if I use the @ error suppressor on the pdo query statement, just like the sample code above. I think this is pretty helpful for long running scripts, instead of manually calling
Yii::app()->db->setActive(false);
everytime to force a new connection (which is what I was doing before)