Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no reconnection attempted when runnning a db queue and db goes away during commit #17785

Closed
cosmok opened this issue Feb 6, 2017 · 8 comments

Comments

@cosmok
Copy link

cosmok commented Feb 6, 2017

  • Laravel Version: 5.3.9
  • PHP Version: 7.0.11
  • Database Driver & Version: mysqlnd 5.0.12, mysql 5.7.12

Description:

When using the DB Queue Driver I am noticing that when server connection goes away while committing, transactions count remains the same. (function below):

During the next iteration (of the queue/loop) there are more server connection errors (General error: 2006 MySQL server has gone away) (as the db connection is not reconnected and because connection obj is being reused in daemon mode) (function below):

} elseif ($this->transactions >= 1 && $this->queryGrammar->supportsSavepoints()) {

The behavior has been verified in 5.3. 5.4 appears to be no different in handling this scenario.

How should I handle this?

@cosmok cosmok changed the title transaction count when commit fails and in queue/daemon mode no reconnection attempted when runnning a db queue and db goes away during commit Feb 7, 2017
@barryvdh
Copy link
Contributor

I'm also getting a similar error on Laravel 5.3.30

I'm running 10 queue workers, and sometimes they seem to crash and take down the mysql server (needs to restart to function again). Not sure if the queue works are the cause or just showing up in the logs as result..

Stacktrace:

exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' [2017-02-14 12:38:19] production.ERROR: exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in /home/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php:624 Stack trace: #0 /home/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(624): PDO->exec('SAVEPOINT trans...') #1 /home/app/vendor/laravel/framework/src/Illuminate/Queue/DatabaseQueue.php(175): Illuminate\Database\Connection->beginTransaction() #2 /home/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(175): Illuminate\Queue\DatabaseQueue->pop('default') #3 /home/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(146): Illuminate\Queue\Worker->getNextJob(Object(Illuminate\Queue\DatabaseQueue), 'default') #4 /home/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(75): Illuminate\Queue\Worker->runNextJob('database', 'default', Object(Illuminate\Queue\WorkerOptions)) #5 /home/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(101): Illuminate\Queue\Worker->daemon('database', 'default', Object(Illuminate\Queue\WorkerOptions)) #6 /home/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(85): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default') #7 [internal function]: Illuminate\Queue\Console\WorkCommand->fire()

@barryvdh
Copy link
Contributor

As observation, I had a lot of errors in my logs, every 3 seconds (the sleep duration) about not being able to connect, while the mysql connection was available for other processes. So it seems that no reconnection was attempted but the script kept running (but failing).
A restart of the supervisor processes made it work again.

So it should either kill the queue worker process or restart, not keep failing..

@barryvdh
Copy link
Contributor

So basically; not sure where it started, but now it does the following according to stack trace:

But probably an error occurred first during the commit;


Which didn't reach the transactions change;
$this->transactions = max(0, $this->transactions - 1);

So should we wrap all $this->getPdo()->... with a try/catch and check causedByLostConnection($e) ?

@cosmok
Copy link
Author

cosmok commented Feb 21, 2017

This is what I ended up doing in app/Exceptions/Handler.php

use Illuminate\Database\DetectsLostConnections;

inside report function:

if ('cli' === php_sapi_name() && $e instanceof PDOException && $this->causedByLostConnection($e)) {
     sleep(1);
     try {
         DB::reconnect('connection_name');
      } catch (Exception $exceptionOnReConnect) {
      }
}   

@barryvdh
Copy link
Contributor

So is that working reliably? Seems a bit hacky..

@cosmok
Copy link
Author

cosmok commented Feb 23, 2017

Appears to be working as expected during tests.

@rap2hpoutre
Copy link
Contributor

Not sure but maybe similar: #18384

@barryvdh
Copy link
Contributor

I think this might be fixed with #19080 ?
(I switched to Redis, which also solved it..)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants